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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7084|回復: 16
收起左側

STM32+定時ADC+DMA+FFT源碼

  [復制鏈接]
ID:352663 發表于 2018-7-21 18:03 | 顯示全部樓層 |閱讀模式
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "pwm.h"
  6. #include "adc.h"
  7. #include "dma.h"
  8. #include "lcd.h"
  9. #include "math.h"
  10. #include "arm_math.h"



  11. float CalMax_FREQ(float *Data, u16 DataSize);

  12. #define SEND_BUFF_SIZE 4096
  13. #define SAMPLE_FREQ    6000
  14. #define INIT_FREQ             400
  15. #define MAX_FREQ           3000
  16. #define INC_FREQ       25
  17. u16 ADCDMA_DATA[SEND_BUFF_SIZE];
  18. float fft_inputbuf[SEND_BUFF_SIZE*2];        //FFT輸入數組
  19. float fft_outputbuf[SEND_BUFF_SIZE];        //FFT輸出數組
  20. float  FundamentalFreq;
  21. u16 ExsistingFreq;


  22. int main(void)
  23. {
  24.         u16 led0pwmval=1000000/SAMPLE_FREQ;
  25.         float temp;
  26.         u16 adcx;
  27.         u16 i = 0,j=0,k=0;
  28.         u16 ExsistingPwmCount;
  29.         u8 INC_FREQ_Flag = 0;
  30.         arm_cfft_radix4_instance_f32 scfft;
  31.         FundamentalFreq = 0;
  32.         ExsistingFreq = INIT_FREQ;
  33. //        u8 dir=1;
  34.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2
  35.         delay_init(168);  //初始化延時函數
  36.         uart_init(115200);//初始化串口波特率為115200
  37.         LED_Init();
  38.         LCD_Init();
  39.          
  40.         Adc_Init();
  41.         MYDMA_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC1->DR,(u32)ADCDMA_DATA,SEND_BUFF_SIZE);
  42.         TIM3_PWM_Init(led0pwmval-1,84-1);        //84M/84=1Mhz的計數頻率,重裝載值500,所以PWM頻率為 1M/500=2Khz.
  43.     TIM_SetCompare1(TIM3,led0pwmval/2);        //修改比較值,修改占空比
  44.         
  45. //        ExsistingFreq = 814;
  46. //        ExsistingFreq = INIT_FREQ;
  47. //        ExsistingPwmCount = 100000/ExsistingFreq;
  48. //        TIM14_PWM_Init(ExsistingPwmCount-1,840-1);        //84M/840=100Khz的計數頻率,重裝載值25,所以PWM頻率為 100K/ExsistingFreq=5KHz.
  49. //    TIM_SetCompare1(TIM14,ExsistingPwmCount/2);        //修改比較值,修改占空比
  50.         
  51.         arm_cfft_radix4_init_f32(&scfft,SEND_BUFF_SIZE,0,1);//初始化scfft結構體,設定FFT相關參數
  52.         POINT_COLOR=RED;
  53.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
  54.         LCD_ShowString(30,70,200,16,16,"ADC TEST");        
  55.         LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
  56.         LCD_ShowString(30,110,200,16,16,"2014/5/6");         
  57.         POINT_COLOR=BLUE;//設置字體為藍色
  58.         LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:");              
  59.         LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V");        //先在固定位置顯示小數點  
  60.         
  61. //        //初始化掃頻
  62. //        for(i=0;i<(MAX_FREQ-INIT_FREQ)/INC_FREQ;i++)
  63. //        {
  64. //                ExsistingFreq = INIT_FREQ+i*INC_FREQ;
  65. //                ExsistingPwmCount = 100000/ExsistingFreq;
  66. //                TIM14_PWM_Init(ExsistingPwmCount-1,840-1);        
  67. //                TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
  68. //                TIM_Cmd(TIM14, ENABLE);
  69. //                delay_ms(10);
  70. //                TIM_Cmd(TIM14, DISABLE);
  71. //        }
  72. //        delay_ms(100);
  73. //        printf("The %d times:\r\n",j);
  74. //                //開始采樣
  75. //        ADC_Cmd(ADC1,ENABLE);
  76. //        //等待采樣完成
  77. //        while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
  78. //        //DMA傳輸完成,清除標志位,等待下次DMA傳輸
  79. //        DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
  80. //        //禁止ADC轉換,計算傳感器頻率
  81. //        ADC_Cmd(ADC1,DISABLE);
  82. //        LED0 = !LED0;
  83. //        for(k=0;k<SEND_BUFF_SIZE;k++)
  84. //        {
  85. //                fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
  86. //                fft_inputbuf[2*k+1] = 0;
  87. //        }
  88. //        //計算頻率,傅里葉變換
  89. //        arm_cfft_radix4_f32(&scfft,fft_inputbuf);        //FFT計算(基4)        
  90. //        arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE);        //把運算結果復數求模得幅值
  91. //        //計算基頻
  92. //        FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
  93. //        //得到初始頻率
  94. //        ExsistingFreq = FundamentalFreq;
  95. //        printf("FFT Result:\r\n");
  96. //        printf("The Calculate Fundamental Frequency: %f\r\n",FundamentalFreq);
  97. //        
  98. //        k=0;
  99.         
  100.     while(1) //實現比較值從0-300遞增,到300后從300-0遞減,循環
  101.         {
  102.                         
  103.                 adcx = ADCDMA_DATA[SEND_BUFF_SIZE-1];
  104.                 LCD_ShowxNum(134,130,adcx,4,16,0);    //顯示ADCC采樣后的原始值
  105.                 temp=(float)adcx*(3.3/4096);          //獲取計算后的帶小數的實際電壓值,比如3.1111
  106.                 adcx=temp;                            //賦值整數部分給adcx變量,因為adcx為u16整形
  107.                 LCD_ShowxNum(134,150,adcx,1,16,0);    //顯示電壓值的整數部分,3.1111的話,這里就是顯示3
  108.                 temp-=adcx;                           //把已經顯示的整數部分去掉,留下小數部分,比如3.1111-3=0.1111
  109.                 temp*=1000;                           //小數部分乘以1000,例如:0.1111就轉換為111.1,相當于保留三位小數。
  110.                 LCD_ShowxNum(150,150,temp,3,16,0X80); //顯示小數部分(前面轉換為了整形顯示),這里顯示的就是111.

  111. //                //激勵
  112. ////                ExsistingFreq = 810;
  113. //                ExsistingPwmCount = 100000/ExsistingFreq;
  114. //                TIM14_PWM_Init(ExsistingPwmCount-1,840-1);        
  115. //                TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
  116. //                TIM_Cmd(TIM14, ENABLE);  //使能TIM14
  117. //                //激勵50ms
  118. //                delay_ms(50);
  119. //                //停止激勵
  120. ////                TIM_Cmd(TIM14, DISABLE);  
  121. //                //延時200ms采樣,去除波形不穩定時波形對采樣結果影響
  122. //                delay_ms(100);
  123. //                //開始采樣
  124. //                ADC_Cmd(ADC1,ENABLE);
  125. //                //等待采樣完成
  126. //                while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
  127. //                //DMA傳輸完成,清除標志位,等待下次DMA傳輸
  128. //                DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
  129. //                //禁止ADC轉換,計算傳感器頻率
  130. //                ADC_Cmd(ADC1,DISABLE);
  131. //                LED0 = !LED0;
  132. //                for(i=0;i<SEND_BUFF_SIZE;i++)
  133. //                {
  134. //                        fft_inputbuf[2*i] =(float)(ADCDMA_DATA[i]*(3.3/4096));
  135. //                        fft_inputbuf[2*i+1] = 0;
  136. //                }
  137. //                //計算頻率,傅里葉變換
  138. //                arm_cfft_radix4_f32(&scfft,fft_inputbuf);        //FFT計算(基4)        
  139. //                arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE);        //把運算結果復數求模得幅值
  140. //                //計算基頻
  141. //                FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
  142. //                printf("FFT Result:\r\n");
  143. //                printf("The Calculate Fundamental Frequency: %f\r\n",FundamentalFreq);
  144. //               
  145. //                //判斷是否起振
  146. //                if(FundamentalFreq>(ExsistingFreq-INC_FREQ/2)&&FundamentalFreq<(ExsistingFreq+INC_FREQ/2))
  147. //                {
  148. //                        //起振成功,保留起振頻率
  149. //                        ExsistingFreq = (u16)FundamentalFreq;
  150. //                        printf("FFT Result:\r\n");
  151. //                        printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
  152. //                }
  153. //                else
  154. //                {        
  155.                         if((FundamentalFreq>ExsistingFreq-INC_FREQ/2)&&(FundamentalFreq<ExsistingFreq+INC_FREQ/2))
  156.                         {
  157.                                 printf("Frequency is correct: \r\n");
  158.                                 k=0;
  159.                         }
  160.                         else
  161.                         {
  162.                                 k=1;
  163.                         }
  164.                         //起振失敗,掃頻
  165.                         //初始化掃頻
  166.                         if(k==1)
  167.                         {
  168.                                 printf("Initial Scan Frequency:\r\n");
  169.                                 for(i=0;i<(MAX_FREQ-INIT_FREQ)/INC_FREQ;i++)
  170.                                 {
  171.                                         ExsistingFreq = INIT_FREQ+i*INC_FREQ;
  172.                                         ExsistingPwmCount = 100000/ExsistingFreq;
  173.                                         TIM14_PWM_Init(ExsistingPwmCount-1,840-1);        
  174.                                         TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
  175.                                         TIM_Cmd(TIM14, ENABLE);
  176.                                         delay_ms(10);
  177.                                         TIM_Cmd(TIM14, DISABLE);
  178.                                 }
  179. //                        delay_ms(100);
  180. //                        printf("The %d times:\r\n",j);
  181. //                                //開始采樣
  182. //                        ADC_Cmd(ADC1,ENABLE);
  183. //                        //等待采樣完成
  184. //                        while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
  185. //                        //DMA傳輸完成,清除標志位,等待下次DMA傳輸
  186. //                        DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
  187. //                        //禁止ADC轉換,計算傳感器頻率
  188. //                        ADC_Cmd(ADC1,DISABLE);
  189. //                        LED0 = !LED0;
  190. //                        for(k=0;k<SEND_BUFF_SIZE;k++)
  191. //                        {
  192. //                                fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
  193. //                                fft_inputbuf[2*k+1] = 0;
  194. //                        }
  195. //                        //計算頻率,傅里葉變換
  196. //                        arm_cfft_radix4_f32(&scfft,fft_inputbuf);        //FFT計算(基4)        
  197. //                        arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE);        //把運算結果復數求模得幅值
  198. //                        //計算基頻
  199. //                        FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
  200. //                        //得到初始頻率
  201. //                        ExsistingFreq = (u16)FundamentalFreq;
  202. //                        printf("FFT Result:\r\n");
  203. //                        printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
  204.                 }
  205.                 else      //正常激勵
  206.                 {
  207. //                        ExsistingFreq = FundamentalFreq;
  208.                         ExsistingPwmCount = 100000/ExsistingFreq;
  209.                         TIM14_PWM_Init(ExsistingPwmCount-1,840-1);        
  210.                         TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
  211.                         TIM_Cmd(TIM14, ENABLE);
  212.                         delay_ms(100);
  213.                         TIM_Cmd(TIM14, DISABLE);
  214. //                        delay_ms(100);
  215. //                        printf("The %d times:\r\n",j);
  216. //                                //開始采樣
  217. //                        ADC_Cmd(ADC1,ENABLE);
  218. //                        //等待采樣完成
  219. //                        while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
  220. //                        //DMA傳輸完成,清除標志位,等待下次DMA傳輸
  221. //                        DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
  222. //                        //禁止ADC轉換,計算傳感器頻率
  223. //                        ADC_Cmd(ADC1,DISABLE);
  224. //                        LED0 = !LED0;
  225. //                        for(k=0;k<SEND_BUFF_SIZE;k++)
  226. //                        {
  227. //                                fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
  228. //                                fft_inputbuf[2*k+1] = 0;
  229. //                        }
  230. //                        //計算頻率,傅里葉變換
  231. //                        arm_cfft_radix4_f32(&scfft,fft_inputbuf);        //FFT計算(基4)        
  232. //                        arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE);        //把運算結果復數求模得幅值
  233. //                        //計算基頻
  234. //                        FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
  235. //                        //得到初始頻率
  236. //                        ExsistingFreq = (u16)FundamentalFreq;
  237. //                        printf("FFT Result:\r\n");
  238. //                        printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
  239.                 }
  240. //                }
  241.                 delay_ms(100);
  242.                         printf("The %d times:\r\n",j);
  243.                                 //開始采樣
  244.                         ADC_Cmd(ADC1,ENABLE);
  245.                         //等待采樣完成
  246.                         while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
  247.                         //DMA傳輸完成,清除標志位,等待下次DMA傳輸
  248.                         DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
  249.                         //禁止ADC轉換,計算傳感器頻率
  250.                         ADC_Cmd(ADC1,DISABLE);
  251.                         LED0 = !LED0;
  252.                         for(k=0;k<SEND_BUFF_SIZE;k++)
  253.                         {
  254.                                 fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
  255.                                 fft_inputbuf[2*k+1] = 0;
  256.                         }
  257.                         //計算頻率,傅里葉變換
  258.                         arm_cfft_radix4_f32(&scfft,fft_inputbuf);        //FFT計算(基4)        
  259.                         arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE);        //把運算結果復數求模得幅值
  260.                         //計算基頻
  261.                         FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
  262.                         for(i=0;i<10;i++)
  263.                         {
  264.                                 if(fft_inputbuf[2*i])
  265.                                 {
  266.                                         INC_FREQ_Flag = 0;
  267.                                 }
  268.                                 else
  269.                                 {
  270.                                         INC_FREQ_Flag = 1;
  271.                                 }        
  272.                         }
  273.                         if(0 == INC_FREQ_Flag)
  274.                         {
  275.                                 //更新激勵頻率
  276.                                 ExsistingFreq = (u16)FundamentalFreq;
  277.                         }
  278. //                        //得到初始頻率
  279. //                        ExsistingFreq = (u16)FundamentalFreq;
  280.                         printf("FFT Result:\r\n");
  281.                         printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
  282.                 //串口打印頻率
  283.                 printf("FFT Result:\r\n");
  284.                 printf("The Fundamental Frequency: %f\r\n",FundamentalFreq);
  285.                
  286.                 delay_ms(1000);
  287.                 //使能激勵信號
  288. //                TIM_Cmd(TIM14, ENABLE);  //使能TIM14
  289. //                delay_ms(50);        
  290.                
  291.         }
  292. }


  293. float CalMax_FREQ(float *Data, u16 DataSize)
  294. {
  295.         u16 i;
  296.         u16 MaxIndex = 1;
  297.         float CalFreq = 0;
  298.         for(i=1;i<DataSize;i++)
  299.         {
  300. //                printf("%f\r\n",Data[i]);
  301.                 if(Data[i]>Data[MaxIndex])
  302.                 {
  303.                         MaxIndex = i;
  304.                 }
  305.         }
  306.         CalFreq =  (float)MaxIndex* SAMPLE_FREQ/SEND_BUFF_SIZE;
  307.         return CalFreq;
  308. }

復制代碼

全部資料51hei下載地址:

定時ADC+DMA +FFT-0118.rar (1.12 MB, 下載次數: 250)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:354404 發表于 2018-8-5 12:42 | 顯示全部樓層
這個能把能不能采集到頻率啊!!!!!
回復

使用道具 舉報

ID:267330 發表于 2018-9-20 13:35 | 顯示全部樓層
這個能把能不能采集到頻率啊!!!!!
回復

使用道具 舉報

ID:267330 發表于 2018-9-20 13:35 | 顯示全部樓層
很想學習啊
回復

使用道具 舉報

ID:476548 發表于 2019-4-29 17:06 | 顯示全部樓層
希望有用
回復

使用道具 舉報

ID:317574 發表于 2019-5-5 09:44 | 顯示全部樓層
非常感謝樓主的分享,現在正在學習
回復

使用道具 舉報

ID:465802 發表于 2019-5-14 09:29 | 顯示全部樓層
這個是F4系列的板子呀。。我的是F1的。。
回復

使用道具 舉報

ID:68875 發表于 2019-5-16 23:07 | 顯示全部樓層
很想學習啊
回復

使用道具 舉報

ID:68875 發表于 2019-5-18 21:57 | 顯示全部樓層
good job
回復

使用道具 舉報

ID:68875 發表于 2019-5-18 21:58 | 顯示全部樓層
很想學習
回復

使用道具 舉報

ID:68875 發表于 2019-5-21 22:23 | 顯示全部樓層

希望有用
回復

使用道具 舉報

ID:403626 發表于 2019-7-3 11:08 | 顯示全部樓層
感謝分享
回復

使用道具 舉報

ID:416106 發表于 2019-7-17 16:59 | 顯示全部樓層
感謝分享!!
回復

使用道具 舉報

ID:652775 發表于 2019-12-4 17:05 | 顯示全部樓層
資料不錯,做個記號
回復

使用道具 舉報

ID:652775 發表于 2019-12-13 08:19 | 顯示全部樓層
資料不錯,感謝樓主分享
回復

使用道具 舉報

ID:447147 發表于 2019-12-23 14:26 | 顯示全部樓層
很想學習啊
回復

使用道具 舉報

ID:658039 發表于 2019-12-24 19:30 | 顯示全部樓層
本人對傅里葉一竅不通,希望能有所 了解,學習了。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产网址 | 精品91久久 | 中文字幕在线观看视频网站 | 国产精品久久久久久网站 | 97人人澡人人爽91综合色 | 日韩精品一区二区不卡 | 日本亚洲欧美 | 一区二区视频 | 久久久久久久久久久福利观看 | 范冰冰一级做a爰片久久毛片 | 91高清视频在线观看 | 日本黄色一级片视频 | 成人在线免费观看 | 国产视频精品区 | 中文字幕日韩在线观看 | 色综合天天天天做夜夜夜夜做 | 成人免费精品 | 国产91成人 | 亚洲国产精品99久久久久久久久 | 国产欧美久久一区二区三区 | 精品国产乱码久久久久久丨区2区 | 中文字幕 视频一区 | 中文字幕在线网 | 国产一级一级国产 | 日日操夜夜操天天操 | 91电影院| 在线成人福利 | 国产一二区视频 | 久久久久久高潮国产精品视 | 欧美激情精品久久久久久免费 | 国产精品久久久久久久久免费桃花 | 日韩伦理一区二区 | 日韩欧美国产成人一区二区 | 精品一二区 | 日韩精品视频在线 | 成人免费激情视频 | 亚洲精品精品 | 三级视频在线观看 | 欧美一二三四成人免费视频 | 成人欧美一区二区三区视频xxx | 天天天天操|