久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 11272|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

C51單片機(jī)FFT OLED顯示程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:460753 發(fā)表于 2020-4-8 11:07 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
經(jīng)過(guò)10幾天的努力,參考http://www.zg4o1577.cn/bbs/dpj-122556-1.html貼子,終于完成OLED C51頻譜顯示,實(shí)際測(cè)試頻譜范圍約500Hz-20KHz,64個(gè)點(diǎn)約150ms。
制作出來(lái)的實(shí)物圖如下:



單片機(jī)源程序如下:
  1. /*
  2. 0.芯片為STC15W4K58S4
  3. 1.使用的為IIC OLED,端口為OLED_SDA=P0^1;OLED_SCL=P0^0;
  4. 2.AD輸入為P1^6;
  5. 3.晶振選擇為內(nèi)置,24M;
  6. */

  7. #include <math.h>
  8. #include "OLED.h"
  9. #define FFT_N 64                                                   //定義福利葉變換的點(diǎn)數(shù)
  10. #define PI 3.1415926535897932384626433832795028841971               //定義圓周率值
  11. #define Process_sensitivity        0                                                                                //修改Process_sensitivity的數(shù)值個(gè)調(diào)整頻譜變化幅度,不建議超過(guò)4
  12. unsigned char tmrcnt=0;
  13. float ADC_OutBuf[FFT_N/4];
  14. struct compx ADC_InBuf[FFT_N];                                      //FFT輸入和輸出:從S[0]開始存放,根據(jù)大小自己定義
  15. float SIN_TAB[FFT_N/4+1];                                           //定義正弦表的存放空間
  16. struct compx {float real,imag;};

  17. struct compx EE(struct compx a,struct compx b)      
  18. {
  19. struct compx c;
  20. c.real=a.real*b.real-a.imag*b.imag;
  21. c.imag=a.real*b.imag+a.imag*b.real;
  22. return(c);
  23. }

  24. void create_sin_tab(float *sin_t)                     
  25. {
  26.   int i;
  27.   for(i=0;i<=FFT_N/4;i++)
  28.   sin_t[i]=sin(2*PI*i/FFT_N);
  29. }

  30. float sin_tab(float pi)
  31. {
  32.   int n;
  33.   float a=0;
  34.    n=(int)(pi*FFT_N/2/PI);
  35.    
  36.   if(n>=0&&n<=FFT_N/4)
  37.     a=SIN_TAB[n];
  38.   else if(n>FFT_N/4&&n<FFT_N/2)
  39.     {
  40.      n-=FFT_N/4;
  41.      a=SIN_TAB[FFT_N/4-n];
  42.     }
  43.   else if(n>=FFT_N/2&&n<3*FFT_N/4)
  44.     {
  45.      n-=FFT_N/2;
  46.      a=-SIN_TAB[n];
  47.    }
  48.   else if(n>=3*FFT_N/4&&n<3*FFT_N)
  49.     {
  50.      n=FFT_N-n;
  51.      a=-SIN_TAB[n];
  52.    }
  53.   
  54.   return a;
  55. }

  56. float cos_tab(float pi)
  57. {
  58.    float a,pi2;
  59.    pi2=pi+PI/2;
  60.    if(pi2>2*PI)
  61.      pi2-=2*PI;
  62.    a=sin_tab(pi2);
  63.    return a;
  64. }

  65. void FFT(struct compx *xin)
  66. {
  67.   register int f,m,nv2,nm1,i,k,l,j=0;
  68.   struct compx u,w,t;
  69.    
  70.    nv2=FFT_N/2;                  //變址運(yùn)算,即把自然順序變成倒位序,采用雷德算法
  71.    nm1=FFT_N-1;  
  72.    for(i=0;i<nm1;i++)        
  73.    {
  74.     if(i<j)                    //如果i<j,即進(jìn)行變址
  75.      {
  76.       t=xin[j];           
  77.       xin[j]=xin[i];
  78.       xin[i]=t;
  79.      }
  80.     k=nv2;                    //求j的下一個(gè)倒位序
  81.     while(k<=j)               //如果k<=j,表示j的最高位為1   
  82.      {           
  83.       j=j-k;                 //把最高位變成0
  84.       k=k/2;                 //k/2,比較次高位,依次類推,逐個(gè)比較,直到某個(gè)位為0
  85.      }
  86.    j=j+k;                   //把0改為1
  87.   }
  88.                         
  89.   {
  90.    int le,lei,ip;                            //FFT運(yùn)算核,使用蝶形運(yùn)算完成FFT運(yùn)算
  91.     f=FFT_N;
  92.    for(l=1;(f=f/2)!=1;l++)                  //計(jì)算l的值,即計(jì)算蝶形級(jí)數(shù)
  93.            ;
  94.   for(m=1;m<=l;m++)                         // 控制蝶形結(jié)級(jí)數(shù)
  95.    {                                        //m表示第m級(jí)蝶形,l為蝶形級(jí)總數(shù)l=log(2)N
  96.     le=2<<(m-1);                            //le蝶形結(jié)距離,即第m級(jí)蝶形的蝶形結(jié)相距l(xiāng)e點(diǎn)
  97.     lei=le/2;                               //同一蝶形結(jié)中參加運(yùn)算的兩點(diǎn)的距離
  98.     u.real=1.0;                             //u為蝶形結(jié)運(yùn)算系數(shù),初始值為1
  99.     u.imag=0.0;
  100.     w.real=cos_tab(PI/lei);                //w為系數(shù)商,即當(dāng)前系數(shù)與前一個(gè)系數(shù)的商
  101.     w.imag=-sin_tab(PI/lei);
  102.     for(j=0;j<=lei-1;j++)                  //控制計(jì)算不同種蝶形結(jié),即計(jì)算系數(shù)不同的蝶形結(jié)
  103.      {
  104.       for(i=j;i<=FFT_N-1;i=i+le)           //控制同一蝶形結(jié)運(yùn)算,即計(jì)算系數(shù)相同蝶形結(jié)
  105.        {
  106.         ip=i+lei;                          //i,ip分別表示參加蝶形運(yùn)算的兩個(gè)節(jié)點(diǎn)
  107.         t=EE(xin[ip],u);                   //蝶形運(yùn)算,詳見公式
  108.         xin[ip].real=xin[i].real-t.real;
  109.         xin[ip].imag=xin[i].imag-t.imag;
  110.         xin[i].real=xin[i].real+t.real;
  111.         xin[i].imag=xin[i].imag+t.imag;
  112.        }
  113.       u=EE(u,w);                          //改變系數(shù),進(jìn)行下一個(gè)蝶形運(yùn)算
  114.      }
  115.    }
  116.   }
  117.   
  118. }
  119. void Timer0Init(void)                //1毫秒@24.000MHz
  120. {
  121.         AUXR |= 0x80;                //定時(shí)器時(shí)鐘1T模式
  122.         TMOD &= 0xF0;                //設(shè)置定時(shí)器模式
  123.         TL0 = 0x40;                //設(shè)置定時(shí)初值
  124.         TH0 = 0xA2;                //設(shè)置定時(shí)初值
  125.         TF0 = 0;                //清除TF0標(biāo)志
  126.         TR0 = 1;                //定時(shí)器0開始計(jì)時(shí)
  127.         ET0 = 1;
  128. }
  129. void Delay(unsigned short n)
  130. {
  131.     unsigned short x;

  132.     while (n--)
  133.     {
  134.         x = 5000;
  135.         while (x--);
  136.     }
  137. }
  138. void InitADC()
  139. {
  140.     P1ASF = 0xff;                   //設(shè)置P1口為AD口
  141.     ADC_CONTR =0x80|0x60;
  142.     Delay(2);                       //ADC上電并延時(shí)
  143. }
  144. unsigned short GetADCResult(unsigned char ch)//ch為輸入端口
  145. {
  146.         ADC_RES = 0;
  147.         ADC_RESL = 0;
  148.     ADC_CONTR =0x80|0x60|ch|0x08;
  149.     _nop_();                        
  150.     _nop_();
  151.     _nop_();
  152.     _nop_();
  153.     while (!(ADC_CONTR & 0x10));
  154.     ADC_CONTR &= ~0x10;         
  155.     return ((unsigned short)(ADC_RES<<2)+ADC_RESL);
  156. }
  157. void processfft(void)
  158. {
  159.         unsigned char data pt=0,i,high,x,temp,p,j;
  160.         for(pt=0;pt<(FFT_N);pt++)
  161.         {
  162.                 ADC_InBuf[pt].imag=0;
  163.         }

  164.         FFT(ADC_InBuf);

  165.         for(pt=2,i=0;pt<(FFT_N/2+1);pt+=2)
  166.         {
  167.                 ADC_OutBuf[i++] = sqrt(ADC_InBuf[pt].real*ADC_InBuf[pt].real+ADC_InBuf[pt].imag*ADC_InBuf[pt].imag);
  168.         }

  169.         for(i=0;i<(FFT_N/4);i++)
  170.         {
  171.                 high=(((unsigned char)ADC_OutBuf[i])>>Process_sensitivity);//修改Process_sensitivity的數(shù)值個(gè)調(diào)整頻譜變化幅度,不建議超過(guò)4
  172.                 for(x=0;x<8;x++)
  173.                 {
  174.                         OLED_SetPos(i*8,7-x);
  175.                         temp=0x00;
  176.                         for(j=0;j<8;j++)
  177.                         {
  178.                                 OLED_WriteData(temp);
  179.                         }
  180.                 }
  181.                 if(high>64)high=64;
  182.                 if(high==0)high=1;
  183.                 p=high/8;
  184.                 for(x=0;x<p;x++)
  185.                 {
  186.                         OLED_SetPos(i*8,7-x);
  187.                         temp=0xff;
  188.                         for(j=0;j<7;j++)
  189.                         {
  190.                                 OLED_WriteData(temp);
  191.                         }
  192.                 }
  193.                 OLED_SetPos(i*8,7-(high/8));
  194.                 temp=~0xff>>(high%8);
  195.                 for(j=0;j<7;j++)
  196.                 {
  197.                         OLED_WriteData(temp);
  198.                 }
  199.         }
  200. }
  201. void main()
  202. {
  203.         unsigned char i;
  204.         P0M1=0x00;
  205.         P0M0=0x00;
  206.         P1M1=0xc0; //設(shè)定AD輸入為P16/P17,實(shí)際只用了P16
  207.         P1M0=0x00;
  208.         EA=1;
  209.         Oled_Init();
  210.         Timer0Init();
  211.         InitADC();
  212.         create_sin_tab(SIN_TAB);
  213.         while(1)
  214.         {
  215.                 if(tmrcnt>=70)
  216.                 {
  217.                         P55=1;
  218.                         for(i=0;i<(FFT_N);i++)
  219.                         {  
  220.                                 ADC_InBuf[i].real=((GetADCResult(6))<<Process_sensitivity);//修改Process_sensitivity的數(shù)值個(gè)調(diào)整頻譜變化幅度,不建議超過(guò)4
  221.                         }
  222.                         
  223.                         processfft();
  224.                         P55=0;
  225.                         tmrcnt=0;
  226.                 }
  227.         }
  228. }
  229. void Time0() interrupt 1
  230. {
  231.         tmrcnt++;
  232. }
復(fù)制代碼

fft5.png (1.11 MB, 下載次數(shù): 179)

fft5.png

fft4.png (1.39 MB, 下載次數(shù): 161)

fft4.png

fft3.png (999.53 KB, 下載次數(shù): 166)

fft3.png

code.rar

65.44 KB, 下載次數(shù): 224, 下載積分: 黑幣 -5

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏20 分享淘帖 頂5 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:582255 發(fā)表于 2020-4-17 22:23 | 只看該作者
樓主有仿真不
回復(fù)

使用道具 舉報(bào)

板凳
ID:169891 發(fā)表于 2021-7-27 09:40 | 只看該作者
正需要用到FFT,謝謝樓主
回復(fù)

使用道具 舉報(bào)

地板
ID:206695 發(fā)表于 2021-8-1 14:50 | 只看該作者
樓主能說(shuō)說(shuō)怎么用嗎
回復(fù)

使用道具 舉報(bào)

5#
ID:422023 發(fā)表于 2021-9-23 21:59 | 只看該作者
可否注釋下processfft()里的每是怎么來(lái)的。得出的結(jié)果又是什么?
回復(fù)

使用道具 舉報(bào)

6#
ID:156220 發(fā)表于 2022-7-2 09:32 | 只看該作者
參考參考,謝謝樓主的分享
回復(fù)

使用道具 舉報(bào)

7#
ID:962396 發(fā)表于 2022-7-2 11:29 | 只看該作者

學(xué)習(xí),謝謝樓主無(wú)私的分享
回復(fù)

使用道具 舉報(bào)

8#
ID:164385 發(fā)表于 2022-7-3 12:05 | 只看該作者
親,半年報(bào)把那兩個(gè)工具也共享一下?謝謝!
回復(fù)

使用道具 舉報(bào)

9#
ID:1063066 發(fā)表于 2023-2-14 22:37 | 只看該作者
不錯(cuò) 可以參考一下
回復(fù)

使用道具 舉報(bào)

10#
ID:1063621 發(fā)表于 2023-7-15 17:42 | 只看該作者
你好,這個(gè)代碼怎樣設(shè)置頻率,我想把顯示的頻率做更低一些60Hz-20K
回復(fù)

使用道具 舉報(bào)

11#
ID:285069 發(fā)表于 2023-7-16 09:38 | 只看該作者
謝謝樓主無(wú)私的分享
回復(fù)

使用道具 舉報(bào)

12#
ID:460753 發(fā)表于 2023-7-18 08:03 | 只看該作者
7631001 發(fā)表于 2022-7-3 12:05
親,半年報(bào)把那兩個(gè)工具也共享一下?謝謝!

兩個(gè)工具,一個(gè)是音頻信號(hào)發(fā)生器,一個(gè)是邏輯分析儀。上傳了信號(hào)發(fā)生器,邏輯分析議我用的是金沙灘的,百度一下即可。

WaveGen3.8.rar

109.63 KB, 下載次數(shù): 13, 下載積分: 黑幣 -5

回復(fù)

使用道具 舉報(bào)

13#
ID:582109 發(fā)表于 2023-7-22 22:28 | 只看該作者
有時(shí)間研究一下
回復(fù)

使用道具 舉報(bào)

14#
ID:1017706 發(fā)表于 2023-9-15 17:13 | 只看該作者
剛好可以來(lái)測(cè)試一下,謝謝分享
回復(fù)

使用道具 舉報(bào)

15#
ID:1098277 發(fā)表于 2023-11-2 22:36 | 只看該作者
STC15W4K58S4 支持float 類型嗎?
是否可以直接在不支持float上跑
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产精品欧美一区二区三区不卡 | 91大神在线看 | 超碰在线人 | 欧美日韩第一页 | 人人做人人澡人人爽欧美 | 国产精品99久久久久久人 | 精品中文字幕一区 | 一区二区av | 国产高清在线精品一区二区三区 | www.操.com| 久久久久久久电影 | 三级成人片 | www.日韩 | 一区二区三区电影在线观看 | 成人在线视频看看 | 亚洲成人av一区二区 | 欧美三级视频 | 国产综合精品一区二区三区 | 精品一区二区电影 | 五月激情综合网 | 欧美中文字幕一区二区三区亚洲 | 国产精品久久久久av | 中文精品视频 | 国产亚洲网站 | 欧美伊人久久久久久久久影院 | 99re视频在线免费观看 | 黄色大片免费观看 | 成人免费一区二区 | 久久精品国产99国产精品 | 精品欧美一区二区三区精品久久 | 欧美综合精品 | 亚洲色图综合网 | 亚洲第一天堂 | 在线播放中文字幕 | 日本成人福利 | 99福利 | 国产精品免费播放 | 一区二区在线不卡 | 亚洲香蕉在线视频 | 亚洲色图婷婷 | 精品国产欧美一区二区三区成人 |