网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> 技术文库 >> 嵌入式 >> 文章正文
  单片机FFT必须全是整数运算         ★★★ 【字体:
单片机FFT必须全是整数运算
作者:61IC录入    文章来源:本站原创    点击数:    更新时间:2006-4-7    

sin.cos表必须放大成整数.
我的一段代码:

// cos, sin表. 比特倒序表. 共128个点: == sin(2*PI*n/N); cos(2*PI*n/N). 放大128倍
flash char sin_tab[SAMPLE_NUM] = { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70, 75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126, 126, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121, -123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102, -98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6 };
flash char cos_tab[SAMPLE_NUM] = { 127, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121, -123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102, -98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70, 75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126 };
flash char inv_tab[SAMPLE_NUM] = { 0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120, 4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124, 2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122, 6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126, 1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121, 5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125, 3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123, 7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127 };


// 128个整数实部,虚部的累加和
short FftReal[SAMPLE_NUM];                // fft的实部
short FftImage[SAMPLE_NUM];               // fft的虚部

LIGHT_SOUND LightSound;                   // 发送给计算机的频谱( 单字节频谱 )
UCHAR power;                              // 平均值

// fft运算时的变量.寄存器/全局变量可以加快运算速度
register UCHAR i,j,k,b,p;                 // 用寄存器变量,加快速度
register short TR,TI,temp;                // 中间变量  
ULONG ulReal;                             // 平方/开方
ULONG ulImage;   

// 初始化
void InitFft()
{   
    SampAdd = sqrt_16(SampAdd/SAMPLE_NUM); // 功率值
    power = SampAdd;                       // 功率值
      
    for( i=0; i<SAMPLE_NUM; i++ )
    {   
        FftReal[i] = SampleValue[i];       // SampleValue里时10位的AD结果    
        FftImage[i] = 0;
    }      
}

               
/* 128点的FFT运算. 采样数据已经按'比特倒序'放置在FftReal[]里
输出的结果也放在: FftRead[]里
*/
void FFT( )
{                   
    /************** following code FFT *******************/
    for( i=1; i<=NUM_2_LOG; i++)                            /* for(1) */
    {
        b=1;
        b <<= (i-1);                                       /*b= 2^(L-1) */
        for( j=0; j<=b-1; j++)                              /* for (2) */
        {
            p=1;
            p <<= (NUM_2_LOG-i);            
            p = p*j;
            for( k=j; k<SAMPLE_NUM; k=k+2*b)                /* for (3) 2点的dft */
            {
                TR = FftReal[k]; TI = FftImage[k]; temp = FftReal[k+b];
                FftReal[k] = FftReal[k] + ((FftReal[k+b]*cos_tab[p])>>7) + ((FftImage[k+b]*sin_tab[p])>>7);
                FftImage[k] = FftImage[k] - ((FftReal[k+b]*sin_tab[p])>>7) + ((FftImage[k+b]*cos_tab[p])>>7);
                FftReal[k+b] = TR - ((FftReal[k+b]*cos_tab[p])>>7) - ((FftImage[k+b]*sin_tab[p])>>7);
                FftImage[k+b] = TI + ((temp*sin_tab[p])>>7) - ((FftImage[k+b]*cos_tab[p])>>7);
                
                // 移位.防止溢出. 结果已经是本值的 1/64               
                FftReal[k]  >>= 1;             
                FftImage[k]  >>= 1;
                FftReal[k+b]  >>= 1;                 
                FftImage[k+b]  >>= 1;
                                                                               
            } /* END for (3) */      
        } /* END for (2) */
    } /* END for (1) */
    
    // 计算复数的模. 结果保存到虚部里, 发送给计算机.同时进行下次的采样,采样数据放入实部里
    // FftImage[i] = sqrt( 1.0*FftReal[i]*FftReal[i] + 1.0*FftImage[i]*FftImage[i] );
    SoundFrenMax = 0;                           // 保存频谱的最大值
    for( i=0; i<SAMPLE_NUM/2; i++)
    {  
        ulReal = FftReal[i];
        ulReal *= ulReal;
        ulImage = FftImage[i];
        ulImage *= ulImage;
        
        LightSound.value[i] = sqrt_16( ulReal + ulImage );
        
        if( i == 0 )
            LightSound.value[i] /= 4;                // 直流分量的特别处理    
        if( LightSound.value[i] < FFT_OUT_MIN )      // 太小的值人为是0
            LightSound.value[i] = 0;
                                 
        if( LightSound.value[i] > SoundFrenMax )     // 保存最大值
            SoundFrenMax = LightSound.value[i];
    }           
}


  
/****************************************/
/*Function: 开根号处理 */
/*入口参数:被开方数,长整型 */
/*出口参数:开方结果,整型 */
/****************************************/
short sqrt_16( ULONG M)                // 快速long型开方
{
    unsigned int N, i;
    unsigned long tmp, ttp; // 结果、循环计数
    if( M == 0 )             // 被开方数,开方结果也为0
        return 0;
    
    N = 0;
    
    tmp = ( M >> 30 );        // 获取最高位:B[m-1]
    M <<= 2;
    if( tmp > 1 )            // 最高位为1
    {
        N ++;               // 结果当前位为1,否则为默认的0
        tmp -= N;
    }
    
    for( i=15; i>0; i-- )    // 求剩余的15位
    {
        N <<= 1;            // 左移一位
        
        tmp <<= 2;
        tmp += (M >> 30);   // 假设
        
        ttp = N;
        ttp = (ttp<<1)+1;
        
        M <<= 2;
        if( tmp >= ttp )     // 假设成立
        {
            tmp -= ttp;
            N ++;
        }       
    }
    
    return N;
}

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号