五 {MOD}音频谱源程序

2019-07-15 23:42发布

五 {MOD}的音频谱
有一段程序uv4里过不去(红 {MOD}字体)
求大神修改

#include <stc12c5a60s2.h>//"stc12c5620ad.h"
#include<intrins.h>
#define LongToBin(n) (((n>>21)&0x80)|((n>>18)&0x40)|((n>>15)&0x20)|((n>>12)&0x10)|((n>>9)&0x08)|((n>>6)&0x04)|((n>>3)&0x02)|((n)&0x01))
#define BIN(n) LongToBin(0x##n##)
#define uchar  unsigned char
#define uint  unsigned int
#define SAMPLE_NUM 64
#define NUM_2_LOG 6
#define FFT_OUT_MIN 3
uchar code BRTable[SAMPLE_NUM] ={ 0, 32, 16, 48, 8, 40, 24, 56,4, 36, 20, 52, 12, 44, 28, 60, 2, 34, 18, 50, 10, 42, 26, 58, 6, 38, 22, 54, 14, 46, 30, 62, 1, 33, 17, 49, 9, 41, 25, 57,5, 37, 21, 53, 13, 45, 29, 61,3, 35, 19, 51, 11, 43, 27, 59,7, 39, 23, 55, 15, 47, 31, 63};
char code sin_tabb[SAMPLE_NUM] = { 0 ,12 ,25 ,37 ,49 ,60 ,71 ,81 ,90 ,98 ,106 ,112 ,117 ,122 ,125 ,126 ,127 ,126 ,125 ,122 ,117 ,112 ,106 ,98 ,90 ,81 ,71 ,60 ,49 ,37 ,25 ,12 ,0 ,-12 ,-25 ,-37 ,-49 ,-60 ,-71 ,-81 ,-90 ,-98 ,-106 ,-112 ,-117 ,-122 ,-125 ,-126 ,-127 ,-126 ,-125 ,-122 ,-117 ,-112 ,-106 ,-98 ,-90 ,-81 ,-71 ,-60 ,-49 ,-37 ,-25 ,-12  };
                                 
char code cos_tabb[SAMPLE_NUM] = {127 ,126 ,125 ,122 ,117 ,112 ,106 ,98 ,90 ,81 ,71 ,60 ,49 ,37 ,25 ,12 ,0 ,-12 ,-25 ,-37 ,-49 ,-60 ,-71 ,-81 ,-90 ,-98 ,-106 ,-112 ,-117 ,-122 ,-125 ,-126 ,-127 ,-126 ,-125 ,-122 ,-117 ,-112 ,-106 ,-98 ,-90 ,-81 ,-71 ,-60 ,-49 ,-37 ,-25 ,-12 ,0 ,12 ,25 ,37 ,49 ,60 ,71 ,81 ,90 ,98 ,106 ,112 ,117 ,122 ,125 ,126 };
uchar a[21];
uchar keep,keepnum,anum,timernum,timernum2,lednum3,Ltime;//用于分离
/*加入数组用于显示相应led灯数目*/
uchar lednum[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//0-7的显示数组  P2组控制
int xdata FftReal[SAMPLE_NUM];
int xdata FftImage[SAMPLE_NUM];
sbit p30=P3^0;
sbit p31=P3^1;
sbit p32=P3^2;
sbit p33=P3^3;
sbit p34=P3^4;
sbit p35=P3^5;//9-11的led控制
sbit p36=P3^6;
sbit p37=P3^7;
void timerinit()//定时器 初始化函数
{
  TMOD=0x01;
  TH0=(65536-6000)/256;
  TL0=(65536-6000)%256;
  EA=1;
  ET0=1;
  TR0=1;
}
void disp()
{
timernum++;
if(timernum==6) timernum=1;
P2=0;//显示前先关闭
P3=P3&0x1f;
switch(timernum)
{
  case 1:anum=a[0];p34=0;p33=1;p32=1;p31=1;p30=1;break;
  case 2:anum=a[1];p34=1;p33=0;p32=1;p31=1;p30=1;break;
  case 3:anum=a[2];p34=1;p33=1;p32=0;p31=1;p30=1;break;
  case 4:anum=a[3];p34=1;p33=1;p32=1;p31=0;p30=1;break;
  case 5:anum=a[4];p34=1;p33=1;p32=1;p31=1;p30=0;break;
}
//anum=a[10];/*修改可以改变光柱高度 (anum值分开几个部分用定时器区分显示)(a[]内逐加) */
if(anum<=8){P2=lednum[anum]3=P3&0x1f;}//屏蔽高三位
//else {P2=0xff3=lednum2[anum-9];}
if(anum==9){P2=0xff;p35=1;p36=0;p37=0;}
if(anum==10){P2=0xff;p35=1;p36=1;p37=0;}
if(anum==11){P2=0xff;p35=1;p36=1;p37=1;}
}
uchar STC_ADC()     //!!根据数据手册写一个ad读取函数
  {
     uchar i;
        ADC_RES   = 0;
        ADC_RESL  = 0;
  ADC_CONTR = BIN(10001000);
  i=3;
        while(i--);
        while (1)                     
     {
         if (ADC_CONTR & BIN(10000))      
         {
     break;
    }
     }
     ADC_CONTR = BIN(10000000);
  return( ADC_RESL<<2) ;
}
short sqrt_16( unsigned long M)   
{
    unsigned int N, i;
    unsigned long tmp, ttp;
    if( M == 0 )            
        return 0;
   
    N = 0;
   
    tmp = ( M >> 30 );        
    M <<= 2;
    if( tmp > 1 )            
    {
        N ++;               
        tmp -= N;
    }
   
    for( i=15; i>0; i-- )   
    {
        N <<= 1;           
        
        tmp <<= 2;
        tmp += (M >> 30);  
        
        ttp = N;
        ttp = (ttp<<1)+1;
        
        M <<= 2;
        if( tmp >= ttp )   
        {
            tmp -= ttp;
            N ++;
        }      
    }
   
    return N;
}
void FFT()
{
register    uchar i,bb,j,k,p,max;
register short TR,TI,temp;
    unsigned long ulReal;                             
    unsigned long ulImage;
   
   
                                                                 
for(i=0; i<SAMPLE_NUM;i++)   //此处可以加入自动增益
{
  FftReal[BRTable] = STC_ADC()<<keep;//使显示保持在一定范围内
        FftImage = 0;
}
  keepnum=FftReal[2]/32;//提取等级数
     if((7<keepnum)&&(keepnum<=8)) {keep=1;}
  else if((4<keepnum)&&(keepnum<=6)) {keep=2;}
  else if((2<keepnum)&&(keepnum<=4)) {keep=3;}
  else {keep=5;}
   
    for( i=1; i<=NUM_2_LOG; i++)                          
    {
        bb=1;
        bb <<= (i-1);                                      
        for( j=0; j<=bb-1; j++)                           
        {
            p=1;
            p <<= (NUM_2_LOG-i);            
            p = p*j;
            for( k=j; k<SAMPLE_NUM; k=k+2*bb)               
            {
                TR = FftReal[k]; TI = FftImage[k]; temp = FftReal[k+bb];
                FftReal[k] = FftReal[k] + ((FftReal[k+bb]*cos_tabb[p])>>7) + ((FftImage[k+bb]*sin_tabb[p])>>7);
                FftImage[k] = FftImage[k] - ((FftReal[k+bb]*sin_tabb[p])>>7) + ((FftImage[k+bb]*cos_tabb[p])>>7);
                FftReal[k+bb] = TR - ((FftReal[k+bb]*cos_tabb[p])>>7) - ((FftImage[k+bb]*sin_tabb[p])>>7);
                FftImage[k+bb] = TI + ((temp*sin_tabb[p])>>7) - ((FftImage[k+bb]*cos_tabb[p])>>7);
               
                FftReal[k]  >>= 1;            
                FftImage[k]  >>= 1;
                FftReal[k+bb]  >>= 1;                 
                FftImage[k+bb]  >>= 1;
                                                                              
            }  
        }
    }
    max=0;
    for( i=0; i<5; i++)//5
    {  
        ulReal = FftReal[i+1];
        ulReal *= ulReal;
        ulImage = FftImage[i+1];
        ulImage *= ulImage;
        
        a = sqrt_16( ulReal + ulImage );   //修改
                        
        if( a < FFT_OUT_MIN )     
            a = 0;//修改
        else
          a = a-FFT_OUT_MIN;
        if( a >max)
             max =a;
    //disp();                     
    }
    if(max>11) //11
    {
       max/=11;
        for( i=0; i<5; i++) //输出a的5个分离数值
        {      
             a/=max;
            
        }  
    }
}            

void main()
{
P2M0=0xff;//  BIN(11111111);//P2组设置为推挽输出
P2M1=0;   
P3M0=0xe0;//  BIN(11111111);
P3M1=0;
P1M0=0x00;
P1M1=0x01;

  P1ASF =1;    //设置P1.0为AD口
    AUXR1 =BIN(100);
keep=0;
keepnum=0;
timerinit();//定时器初始化
timernum=3;//从3开始
timernum2=0;
    while(1)
{
           FFT();
}
}
void timer0() interrupt 1
{
TH0=(65536-6000)/256;  //6000
TL0=(65536-6000)%256;
disp();
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。