新闻  |   论坛  |   博客  |   在线研讨会
示波器制作系列1:正弦插值算法
0750long | 2009-05-21 17:21:05    阅读:4280   发布文章

示波器制作系列1:正弦插值算法


?搞了半天,虽然学过 信号处理!

?先是一片茫然,然后开始看书,想写代码,发现自己还是不懂。做一下MATLAB的仿真,先分析一下matlab的代码 再去写C的。。。。
?代码:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%抽样
Ts = 0.04;
Fs = 1/Ts;
n = 1:1:60;
nTs = n*Ts;
x = sin(pi*10 * nTs);
subplot(2,2,1);
stem(nTs,x);
title('原始信号');
%%%%%%%%%%%%%%%%%%%%%%%
%重构
dt = 0.004;
t  = 0 :dt :0.1;
dn = length(t);
xa = ones(1,dn);
for i = 1:dn
    i
    s = sinc( i / 4  -  n )
    xa(i) = x * s';
end
subplot(2,2,2);
stem(t,xa);下图是仿真的结果,只要给便dt 就可以了
点击看大图

对你或许有用的资料;
DMF5001液晶显示器与波形显示技术rar

微型液晶显示数字存储示波器.pdfpdf


原理:rar

 
 
5-8号晚 补充:
我用单片机 C8051F020 24M的晶振在一块 640 *480 的液晶上显示采样回来的波形,采样时钟25M(用的FPGA),但是如果我用正弦插值,就像刚才使用Matlab的那种方法来实现,刷新一屏波形的时间间隔很长,也就是说算法的速度太慢了,尤其是在这种速度比较慢、内部存储空间比较小的设备上算法的优化显得格外的重要,我现在还没有找到合适的方法去减少算法的速度,希望有大侠可以帮俺一下啊 谢了
代码如下:
/*
pbuf    数据缓冲空间
buf_num 数据缓冲的大小     缓冲空间的大小 最好是WAVE_LEN的除数 按照正弦插值的理论算法,每个周期2.5采样点就可以重构一个正弦波形
color    线条的颜色
AD_CLK  AD采集时钟频率

///////////
数据点不能少于    SINP_LEN 个
*/
void GUI_Wave_SinP(uint8 *pbuf,uint16 buf_num,uint16 color)
{
    uint16  i = 0 ;     
    uint16  j = 0 ;
    float   sum      = 0;
    float   temp  = 0;
    uint8 data_buf[WAVE_LEN] = {0};           //存放插值以后的数据
    float sa_buf  [SINP_LEN] = {0};        // 正弦内插函数求得的系数

    uint16 interval = WAVE_LEN / buf_num ;
   
    for(i = 1 ; i < WAVE_LEN ; i++)      
    {
        temp = 0 ;      
        sum  = 0 ;        //不能少了啊
        for(j = 0 ; j < SINP_LEN ; j++) //计算内插系数
        {
         // sa_buf[j] =   sin(PI * ADC_CLK * (1/ ( ADC_CLK * interval) * i - j)       //原始计算式
            temp =     (float) ( PI *  ( (float) i / (float)interval - (float)j )) ;
            if (temp == 0)
                sa_buf[j] = 1.0000;
            else
                   sa_buf[j] =(float)((float) sin(temp) / (float)temp  );                                    //简化后的式子
        }

        //计算插值以后每个点的数据

    /*    if( i <= SINP_LEN )                    //如果计算的点小于SINP_LEN的一半,采用数据缓冲区的前60个点计算
        {
            for(j = 0 ; j < SINP_LEN ; j++)
                  sum +=  (float)sa_buf[j] * (float)(*(pbuf + j)) ;
        }
        else if( i >=  buf_num - SINP_LEN )   //如果计算的点大于buf_num - SINP_LEN / 2,采用数据缓冲区的后60个点计算
        {
            for(j = 0 ; j < SINP_LEN ; j++)
                  sum +=  (float)sa_buf[j] * (float)(*(pbuf + buf_num - SINP_LEN + j)) ;
        }
        else
        {
               for(j = 0 ; j < SINP_LEN ; j++)    //其余情况采用以这个点为中心的  SINP_LEN个点
                 sum +=  (float)sa_buf[j] * (float)(*(pbuf + i + j - (uint8)(SINP_LEN / 2) )) ;
        }   
          */
       for(j = 0 ; j < SINP_LEN ; j++)
               sum +=  (float)sa_buf[j] * (float)(*(pbuf + j)) ;
        data_buf[i]  =   (uint8) sum ;
       }
   
    GUI_Wave(data_buf,color);
 
}           

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客