微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 初学者都被这个程序弄得没信心了!

初学者都被这个程序弄得没信心了!

时间:10-02 整理:3721RD 点击:
#include<stc12c5a60s2.h>
#include<math.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define ADC_POWER   0x80            //ADC power control bit
#define ADC_FLAG    0x10            //ADC complete flag
#define ADC_START   0x08            //ADC start control bit
#define ADC_SPEEDLL 0x00            //420 clocks
#define ADC_SPEEDL  0x20            //280 clocks
#define ADC_SPEEDH  0x40            //140 clocks
#define ADC_SPEEDHH 0x60            //70 clocks
uchar LEDBuf[35];
uchar gain=6;
uchar Menu=2;
uchar refreshflag[40];
//#include<fft.h>
struct compx
{
        float real;
        float imag;
};
struct compx dd[65]; //FFT数据   
data struct compx temp;  
code float iw[64]=
{
        1.000,0,0.9952,-0.0980,0.9808,-0.1951,0.9569,-0.2903,0.9239,-0.3827,0.8819,-0.4714,0.8315,-0.5556,
        0.7730,-0.6344,0.7071,-0.7071,0.6344,-0.7730,0.5556,-0.8315,0.4714,-0.8819,0.3827,-0.9239,0.2903,-0.9569,
        0.1951,-0.9808,0.0980,-0.9952,0.0,-1.0000,-0.0980,-0.9952,-0.1951,-0.9808,-0.2903,0.9569,-0.3827,-0.9239,
        -0.4714,-0.8819,-0.5556,-0.8315,-0.6344,-0.7730,-0.7071,-0.7071,-0.7730,-0.6344,-0.8315,-0.5556,-0.8819,-0.4714,
        -0.9239,-0.3827,-0.9569,-0.2903,-0.9808,-0.1951,-0.9952,-0.0980
};

//复数乘法
void ee(struct compx b1,uchar data b2)
{
        temp.real=b1.real*iw[2*b2]-b1.imag*iw[2*b2+1];
        temp.imag=b1.real*iw[2*b2+1]+b1.imag*iw[2*b2];
}
//乘方函数  
uint mypow(uchar data nbottom,uchar data ntop)
{
    uint data result=1;
    uchar data t;   
    for(t=0;t<ntop;t++)result*=nbottom;
    return result;
}
//快速傅立叶变换  
void fft(struct compx *xin,uchar data N)
{
        uchar data  fftnum,i,j,k,l,m,n,disbuff,dispos,dissec;
        data struct compx t;
        fftnum=N;                         //傅立叶变换点数
        for(m=1;(fftnum=fftnum/2)!=1;m++);//求得M的值
        for(k=0;k<=N-1;k++)               //码位倒置
        {
                n=k;
                j=0;
                for(i=m;i>0;i--)             //倒置
                {
                        j=j+((n%2)<<(i-1));
                        n=n/2;
                }
                if(k<j){t=xin[1+j];xin[1+j]=xin[1+k];xin[1+k]=t;}//交换数据
        }  
        for(l=1;l<=m;l++)                //FFT运算
        {
                disbuff=mypow(2,l);          //求得碟间距离
                dispos=disbuff/2;            //求得碟形两点之间的距离
                for(j=1;j<=dispos;j++)
                        for(i=j;i<N;i=i+disbuff) //遍历M级所有的碟形
                        {
                                dissec=i+dispos;     //求得第二点的位置
                                ee(xin[dissec],(uint)(j-1)*(uint)N/disbuff);//复数乘法
                                t=temp;
                                xin[dissec].real=xin[i].real-t.real;
                                xin[dissec].imag=xin[i].imag-t.imag;
                                xin[i].real=xin[i].real+t.real;
                                xin[i].imag=xin[i].imag+t.imag;
                        }
        }
}

//完成显示数据的转换工作,包括顶点下落速度控制以及顶点更新定格
//对fft数据进行处理,得到各个频率段的电压幅值
void processfft(void)
{
    uchar data pt=0,tmp;
    for(pt=1;pt<65;pt++)
    {
        dd[pt].imag=0;                //清零虚部
    }
    fft(dd,64);                       //对当前数据进行傅立叶变换
         
    for(pt=1;pt<65;pt++)
    {                                      
        dd[pt].real=sqrt(dd[pt].real*dd[pt].real+dd[pt].imag*dd[pt].imag);//取均方根
    }
        if(Menu==1)
        {
                for(pt=2;pt<34;pt+=2)         
            {      
                        for(tmp=(dd[pt].real/32)+1,LEDBuf[pt]=0xFF;tmp>=1;tmp--)//tmp>1;不保留最低位那一行常亮
                        {
                                 LEDBuf[pt]<<=1;                       
                        }
                       
                        LEDBuf[pt]=~(LEDBuf[pt]);
         
                }
        }
        else if(Menu==2)
        {
                //下落感
                for(pt=2;pt<34;pt+=2)       
            {      
                        tmp=(dd[pt].real/32)+1;
                        if(refreshflag[pt]<tmp)                            //刷新数据,取较大高度值 存储显示  
                        {
                                for(LEDBuf[pt]=0xFF;tmp>1;tmp--)        //tmp>1;不保留  最低位那一行常亮;{}一次也不执行;
                                {
                                         LEDBuf[pt]<<=1;       
                                       
                                }
                                refreshflag[pt]=(dd[pt].real/32)+1;
                        }
                        else
                        {
                                 if(refreshflag[pt]>1)refreshflag[pt]--;                //顶端下落速度控制  改变值可以改变下降速度
                                 for(LEDBuf[pt]=0xFF,tmp=refreshflag[pt];tmp>1;tmp--)   //tmp>1;不保留 最低位那一行常亮
                                {
                                         LEDBuf[pt]<<=1;                                               
                                }
                        }
                }
        }
        else if(Menu==0)
        {
                //下落感频谱
                for(pt=2;pt<34;pt+=2)         
            {      
                        tmp=(dd[pt].real/32)+1;
                        if(refreshflag[pt]<tmp)                          //刷新数据,取较大高度值 存储显示  
                        {
                                for(LEDBuf[pt]=0xFF;tmp>=1;tmp--)//tmp>1;不保留  最低位那一行常亮;{}一次也不执行;
                                {
                                         LEDBuf[pt]<<=1;       
                                       
                                }
                                refreshflag[pt]=(dd[pt].real/32)+1;
                       
                        }
                        else
                        {
                                 if(refreshflag[pt]>1)refreshflag[pt]--;                        
                                 for(LEDBuf[pt]=0xFF,tmp=refreshflag[pt];tmp>=1;tmp--)       
                                {
                                         LEDBuf[pt]<<=1;                                       
                                }
                        }
                        LEDBuf[pt]=~(LEDBuf[pt]);
                }
        }
       
}  
void delay(uchar t)
  {
   uchar a=2,j;
          while(--a)
        {
         for(j=t;j>0;j--);
         }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         for(j=t;j>0;j--);
  }
  void InitADC()  //AD初始化
   {
       ADC_RES = 0;  //Clear previous result
       ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
       delay(10);//ADC power-on and delay
       }
   uchar GetADCResult(uchar ch)//是几通道就输入几                 {
    {
            ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
              _nop_();                        //Must wait before inquiry
              _nop_();
              _nop_();
              _nop_();
         while(!(ADC_CONTR & ADC_FLAG));//Wait complete flag
         ADC_CONTR &= ~ADC_FLAG;         //Close ADC
         return ADC_RES;                 //Return ADC result
      }
         void IOINT()
         {
            P1ASF=0X03;
            P0=0Xff;
                P2=0X00;
                P3=0X00;
      }
   void LEDBufrefresh(void)//频谱显示程序
   {
          uchar data i,x,y;
         for(x=1,i=2;x!=0;x<<=1,i+=2)//移位;
         {
            P2=x;
            for(y=1;y!=0;y<<=1)
            {
              P0=y&LEDBuf[i];
              delay(2);
                  P0=0xff;
            }
              P2=0x00;
          }
        for(x=1,i=2;x!=0x80;x<<=1,i+=2)
          {
            P3=x;
            for(y=1;y!=0;y<<=1)
            {
              P0=y&LEDBuf[i];
              delay(2);
                  P0=0xff;
            }
              P3=0;
           }
    }
  void time(void)//定时器开启
   {
           EA=0;
           TMOD=0x01;
           TH0=0x00;
           TL0=0x00;
           TR0=1;
           ET0=1;
            EA=1;
   }
   void main()
   {
         uint data Count=700;
        uchar data i,Cgain,num=0;
   IOINT();
   for(i=0;i<=34;i++)
         {
                 LEDBuf[i]=0x00;
         }
        for(i=0;i<=39;i++)
        {
         refreshflag[i]=0x09;
        }
        InitADC();
         time();
        while(1)
        {        for(i=0;i<65;i++)
                {  
                        dd[i].real=(GetADCResult(0)+GetADCResult(1))<<gain;          //读取ad结果并放大;
                }
                 processfft();//傅立叶变化及处理
                  if(dd[2].real<32)
                 {
                         if(++Count==300)          //电平值过小,这降低gain,减少噪音的电平显示;
                         {
                                Count=0;
                                //if(++Menu==4)Menu=0;                  //切换Menu,显示方式;
                                gain=6;                         
                         }
                 }
                 else
                 {
                         Count=1;
       
                         if(++num==0xAF)                         //播放时,Auto gain;
                         {
                                num=0;                                   //自动增益;Automatic gain;
                                Cgain=dd[2].real/32;
                                if(7<Cgain<=8)
                                {
                                        gain=4;
                                       
                                }
                                else if(4<Cgain<=6)
                                {
                                        gain=5;
                                       
                                }
                                else if(2<Cgain<=4)
                                {
                                        gain=6;
                                }
                                else
                                {
                                        gain=7;
                       
                                }
       
                         }
                  }                 
        }
}
void LED() interrupt 1 using 1
   {
   TR0=0;
   LEDBufrefresh();
   TL0=0x00;
   TH0=0x50;
   TR0=1;
根据别人的频谱程序改来的这个程序,他是说要35M的晶振而我手上只有12M的就用了12M的,把延时时间改了一下,但每次运行程序都是满屏的闪烁,看不到频谱,哪位大神帮我看一下,新人,这个问题困惑我好久了!

你可以在网上买个35M的晶振试一下,两者相差太大了,

你的做好了吗?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top