找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2835|回复: 5
打印 上一主题 下一主题
收起左侧

c8051f020单片机AD采样,然后FFT变换程序

  [复制链接]
跳转到指定楼层
楼主
ID:582255 发表于 2021-1-26 15:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用单片机对模拟信号进行转换,转换后做FFT快速傅里叶变换。
程序如下:
  1. #include<c8051f020.h>
  2. #include<math.h>

  3. #define SYSCLK 11000000
  4. #define  PI 3.1415926536
  5. #define  size_x  1024

  6. sfr16 ADC0 = 0xbe;

  7. typedef struct{
  8.      float real;
  9.      float img;
  10. }complex;

  11. complex W[512];
  12. complex xdata x[1024];
  13. float p=0;                                                           //总功率
  14. unsigned int h;

  15. void SYSCLK_Init (void)
  16. {
  17.    int i;                              // delay counter
  18.    OSCXCN = 0x67;                      // start external oscillator with
  19.                                        // 11MHz crystal
  20.    for (i=0; i < 256; i++) ;           // Wait for osc. to start up
  21.    while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle
  22.    OSCICN = 0x88;                      // select external oscillator as SYSCLK
  23.                                        // source and enable missing clock
  24.                                        // detector
  25. //        OSCICN = 0x07;   //interal 16MHZ
  26. }
  27. void WDT_Init()
  28. {
  29. WDTCN = 0xde;
  30. WDTCN = 0xad;
  31. }
  32. void T3_Init()                                                      //定时48.8us
  33. {
  34. TMR3CN=0x02;
  35. TMR3RLL=(65536-540)%256;
  36. TMR3RLH=(65536-540)/256;
  37. TMR3L=(65536-540)%256;
  38. TMR3H=(65536-540)/256;
  39. TMR3CN|=0X04;                                                          //启动定时器
  40. }
  41. void ADC_Init()
  42. {
  43. AMX0CF=0X00;                                                          //通道0
  44. AMX0SL=0X00;
  45. ADC0CF = (SYSCLK/2500000) << 3;               //SAR时钟为2.5mhz
  46. ADC0CN = 0x84;                                                          //定时器3方式启动
  47. REF0CN = 0x03;
  48. EA=1;
  49. EIE2|=0X02;                    
  50. EIE1&= ~0x04;
  51. }
  52. void ADC0_ISR() interrupt 15
  53. {
  54. ADC0CN&=0xdf;
  55. x[h].real=ADC0;
  56. h++;
  57. }
  58. void add(complex a,complex b,complex *c)
  59. {
  60.      c->real=a.real+b.real;
  61.      c->img=a.img+b.img;
  62. }
  63. void mul(complex a,complex b,complex *c)
  64. {
  65.      c->real=a.real*b.real - a.img*b.img;
  66.      c->img=a.real*b.img + a.img*b.real;
  67. }
  68. void sub(complex a,complex b,complex *c)
  69. {
  70.      c->real=a.real-b.real;
  71.      c->img=a.img-b.img;
  72. }
  73. void change()                                                                                                  //倒位序
  74. {
  75.   unsigned int i=0,j=0,k=0,t;
  76.   complex temp;
  77.   for(i=0;i<size_x;i++)
  78.   {
  79.     k=i;j=0;
  80.         t=(unsigned) (log(size_x)/log(2));
  81.     while(t--)
  82.         {
  83.        j=j<<1;
  84.        j|=(k & 1);                                                                                         
  85.        k=k>>1;
  86.     }
  87.     if(j>i)
  88.         {
  89.        temp=x[i];
  90.        x[i]=x[j];
  91.        x[j]=temp;
  92.     }
  93.   }                                                                                          
  94. }                                                                                                                         //计算旋转因子
  95. void init_W()                                                                                
  96. {
  97. int i;
  98. for(i=0;i<(size_x/2);i++)
  99. {
  100.    W[i].real=cos(2*PI/size_x*i);
  101.    W[i].img=-1*sin(2*PI/size_x*i);
  102.                   
  103. }
  104. }
  105. void FFT()
  106. {
  107.      unsigned int i=0,j=0,k=0,l=0;
  108.      complex up,down;
  109.      change();                                                                                                                          //倒位序
  110.          init_W();                                                                                                                          //计算旋转因子
  111.      for(i=0;i<(int)( log(size_x)/log(2) );i++)                                                          //一级蝶形运算
  112.          {                     
  113.            l=( 1<<i );                                                                                                         
  114.            for(j=0;j<size_x;j+=(1<<(i+1)))                                                                  //一组蝶形运算
  115.                    {                              
  116.                  for(k=0;k<l;k++)
  117.                                  {                                                                                                                  //一个蝶形运算
  118.                                                                      
  119.                         mul(x[j+k+l],W[size_x*k/2/l],&up);
  120.                         add(x[j+k],up,&up);
  121.                         mul(x[j+k+l],W[size_x*k/2/l],&down);
  122.                         sub(x[j+k],down,&down);
  123.                         x[j+k]=up;
  124.                         x[j+k+l]=down;
  125.                  }
  126.            }
  127.      }
  128. }
  129. void PSD()                                                                                             //功率谱
  130. {
  131. unsigned int i;
  132. for(i=0;i<size_x;i++)
  133. {                        
  134.   x[i].real=(1/1024.0)*(x[i].real*x[i].real+x[i].img*x[i].img);
  135.   x[i].img=0;
  136. }
  137. }
  138. void ZP()                                                                                           //总功率
  139. {
  140.   int i;
  141.   for(i=0;i<size_x;i++)
  142. {p+=x[i].real*x[i].real;}
  143.   p=(1/1024.0)*p;
  144. }                                                                                                           //转电压
  145. void ZDY()
  146. {
  147. unsigned int i;
  148. for(i=0;i<1024;i++)
  149. {
  150.   x[i].real=(1/4096.0)*x[i].real*2.4;
  151. }
  152. }
  153. void main()
  154. {
  155.   WDT_Init();
  156.   SYSCLK_Init();
  157.   ADC_Init();
  158.   T3_Init();
  159.   while(h==1024)
  160.   {
  161.    TMR3CN&=0xfb;
  162.    ZDY();
  163.    ZP();
  164.    FFT();
  165.    PSD();
  166.    h=0;
  167.    TMR3CN|=0x04;
  168.   }
  169. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:64765 发表于 2022-2-6 13:38 | 只看该作者
学习,受益匪浅,谢谢分享。
回复

使用道具 举报

板凳
ID:1064338 发表于 2023-2-26 13:26 | 只看该作者
学习,受益匪浅,谢谢分享
回复

使用道具 举报

地板
ID:29750 发表于 2023-8-10 23:50 | 只看该作者
学习,受益匪浅,谢谢分享
回复

使用道具 举报

5#
ID:654480 发表于 2023-8-29 09:33 | 只看该作者
能直接用吗
回复

使用道具 举报

6#
ID:227484 发表于 2023-10-28 19:29 | 只看该作者
这个程序能直接使用吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表