- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "led.h"
- #include "pwm.h"
- #include "adc.h"
- #include "dma.h"
- #include "lcd.h"
- #include "math.h"
- #include "arm_math.h"
- float CalMax_FREQ(float *Data, u16 DataSize);
- #define SEND_BUFF_SIZE 4096
- #define SAMPLE_FREQ 6000
- #define INIT_FREQ 400
- #define MAX_FREQ 3000
- #define INC_FREQ 25
- u16 ADCDMA_DATA[SEND_BUFF_SIZE];
- float fft_inputbuf[SEND_BUFF_SIZE*2]; //FFT輸入數組
- float fft_outputbuf[SEND_BUFF_SIZE]; //FFT輸出數組
- float FundamentalFreq;
- u16 ExsistingFreq;
- int main(void)
- {
- u16 led0pwmval=1000000/SAMPLE_FREQ;
- float temp;
- u16 adcx;
- u16 i = 0,j=0,k=0;
- u16 ExsistingPwmCount;
- u8 INC_FREQ_Flag = 0;
- arm_cfft_radix4_instance_f32 scfft;
- FundamentalFreq = 0;
- ExsistingFreq = INIT_FREQ;
- // u8 dir=1;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2
- delay_init(168); //初始化延時函數
- uart_init(115200);//初始化串口波特率為115200
- LED_Init();
- LCD_Init();
-
- Adc_Init();
- MYDMA_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC1->DR,(u32)ADCDMA_DATA,SEND_BUFF_SIZE);
- TIM3_PWM_Init(led0pwmval-1,84-1); //84M/84=1Mhz的計數頻率,重裝載值500,所以PWM頻率為 1M/500=2Khz.
- TIM_SetCompare1(TIM3,led0pwmval/2); //修改比較值,修改占空比
-
- // ExsistingFreq = 814;
- // ExsistingFreq = INIT_FREQ;
- // ExsistingPwmCount = 100000/ExsistingFreq;
- // TIM14_PWM_Init(ExsistingPwmCount-1,840-1); //84M/840=100Khz的計數頻率,重裝載值25,所以PWM頻率為 100K/ExsistingFreq=5KHz.
- // TIM_SetCompare1(TIM14,ExsistingPwmCount/2); //修改比較值,修改占空比
-
- arm_cfft_radix4_init_f32(&scfft,SEND_BUFF_SIZE,0,1);//初始化scfft結構體,設定FFT相關參數
- POINT_COLOR=RED;
- LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
- LCD_ShowString(30,70,200,16,16,"ADC TEST");
- LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
- LCD_ShowString(30,110,200,16,16,"2014/5/6");
- POINT_COLOR=BLUE;//設置字體為藍色
- LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:");
- LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V"); //先在固定位置顯示小數點
-
- // //初始化掃頻
- // for(i=0;i<(MAX_FREQ-INIT_FREQ)/INC_FREQ;i++)
- // {
- // ExsistingFreq = INIT_FREQ+i*INC_FREQ;
- // ExsistingPwmCount = 100000/ExsistingFreq;
- // TIM14_PWM_Init(ExsistingPwmCount-1,840-1);
- // TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
- // TIM_Cmd(TIM14, ENABLE);
- // delay_ms(10);
- // TIM_Cmd(TIM14, DISABLE);
- // }
- // delay_ms(100);
- // printf("The %d times:\r\n",j);
- // //開始采樣
- // ADC_Cmd(ADC1,ENABLE);
- // //等待采樣完成
- // while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
- // //DMA傳輸完成,清除標志位,等待下次DMA傳輸
- // DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
- // //禁止ADC轉換,計算傳感器頻率
- // ADC_Cmd(ADC1,DISABLE);
- // LED0 = !LED0;
- // for(k=0;k<SEND_BUFF_SIZE;k++)
- // {
- // fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
- // fft_inputbuf[2*k+1] = 0;
- // }
- // //計算頻率,傅里葉變換
- // arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計算(基4)
- // arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE); //把運算結果復數求模得幅值
- // //計算基頻
- // FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
- // //得到初始頻率
- // ExsistingFreq = FundamentalFreq;
- // printf("FFT Result:\r\n");
- // printf("The Calculate Fundamental Frequency: %f\r\n",FundamentalFreq);
- //
- // k=0;
-
- while(1) //實現比較值從0-300遞增,到300后從300-0遞減,循環
- {
-
- adcx = ADCDMA_DATA[SEND_BUFF_SIZE-1];
- LCD_ShowxNum(134,130,adcx,4,16,0); //顯示ADCC采樣后的原始值
- temp=(float)adcx*(3.3/4096); //獲取計算后的帶小數的實際電壓值,比如3.1111
- adcx=temp; //賦值整數部分給adcx變量,因為adcx為u16整形
- LCD_ShowxNum(134,150,adcx,1,16,0); //顯示電壓值的整數部分,3.1111的話,這里就是顯示3
- temp-=adcx; //把已經顯示的整數部分去掉,留下小數部分,比如3.1111-3=0.1111
- temp*=1000; //小數部分乘以1000,例如:0.1111就轉換為111.1,相當于保留三位小數。
- LCD_ShowxNum(150,150,temp,3,16,0X80); //顯示小數部分(前面轉換為了整形顯示),這里顯示的就是111.
- // //激勵
- //// ExsistingFreq = 810;
- // ExsistingPwmCount = 100000/ExsistingFreq;
- // TIM14_PWM_Init(ExsistingPwmCount-1,840-1);
- // TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
- // TIM_Cmd(TIM14, ENABLE); //使能TIM14
- // //激勵50ms
- // delay_ms(50);
- // //停止激勵
- //// TIM_Cmd(TIM14, DISABLE);
- // //延時200ms采樣,去除波形不穩定時波形對采樣結果影響
- // delay_ms(100);
- // //開始采樣
- // ADC_Cmd(ADC1,ENABLE);
- // //等待采樣完成
- // while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
- // //DMA傳輸完成,清除標志位,等待下次DMA傳輸
- // DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
- // //禁止ADC轉換,計算傳感器頻率
- // ADC_Cmd(ADC1,DISABLE);
- // LED0 = !LED0;
- // for(i=0;i<SEND_BUFF_SIZE;i++)
- // {
- // fft_inputbuf[2*i] =(float)(ADCDMA_DATA[i]*(3.3/4096));
- // fft_inputbuf[2*i+1] = 0;
- // }
- // //計算頻率,傅里葉變換
- // arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計算(基4)
- // arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE); //把運算結果復數求模得幅值
- // //計算基頻
- // FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
- // printf("FFT Result:\r\n");
- // printf("The Calculate Fundamental Frequency: %f\r\n",FundamentalFreq);
- //
- // //判斷是否起振
- // if(FundamentalFreq>(ExsistingFreq-INC_FREQ/2)&&FundamentalFreq<(ExsistingFreq+INC_FREQ/2))
- // {
- // //起振成功,保留起振頻率
- // ExsistingFreq = (u16)FundamentalFreq;
- // printf("FFT Result:\r\n");
- // printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
- // }
- // else
- // {
- if((FundamentalFreq>ExsistingFreq-INC_FREQ/2)&&(FundamentalFreq<ExsistingFreq+INC_FREQ/2))
- {
- printf("Frequency is correct: \r\n");
- k=0;
- }
- else
- {
- k=1;
- }
- //起振失敗,掃頻
- //初始化掃頻
- if(k==1)
- {
- printf("Initial Scan Frequency:\r\n");
- for(i=0;i<(MAX_FREQ-INIT_FREQ)/INC_FREQ;i++)
- {
- ExsistingFreq = INIT_FREQ+i*INC_FREQ;
- ExsistingPwmCount = 100000/ExsistingFreq;
- TIM14_PWM_Init(ExsistingPwmCount-1,840-1);
- TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
- TIM_Cmd(TIM14, ENABLE);
- delay_ms(10);
- TIM_Cmd(TIM14, DISABLE);
- }
- // delay_ms(100);
- // printf("The %d times:\r\n",j);
- // //開始采樣
- // ADC_Cmd(ADC1,ENABLE);
- // //等待采樣完成
- // while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
- // //DMA傳輸完成,清除標志位,等待下次DMA傳輸
- // DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
- // //禁止ADC轉換,計算傳感器頻率
- // ADC_Cmd(ADC1,DISABLE);
- // LED0 = !LED0;
- // for(k=0;k<SEND_BUFF_SIZE;k++)
- // {
- // fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
- // fft_inputbuf[2*k+1] = 0;
- // }
- // //計算頻率,傅里葉變換
- // arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計算(基4)
- // arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE); //把運算結果復數求模得幅值
- // //計算基頻
- // FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
- // //得到初始頻率
- // ExsistingFreq = (u16)FundamentalFreq;
- // printf("FFT Result:\r\n");
- // printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
- }
- else //正常激勵
- {
- // ExsistingFreq = FundamentalFreq;
- ExsistingPwmCount = 100000/ExsistingFreq;
- TIM14_PWM_Init(ExsistingPwmCount-1,840-1);
- TIM_SetCompare1(TIM14,ExsistingPwmCount/2);
- TIM_Cmd(TIM14, ENABLE);
- delay_ms(100);
- TIM_Cmd(TIM14, DISABLE);
- // delay_ms(100);
- // printf("The %d times:\r\n",j);
- // //開始采樣
- // ADC_Cmd(ADC1,ENABLE);
- // //等待采樣完成
- // while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
- // //DMA傳輸完成,清除標志位,等待下次DMA傳輸
- // DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
- // //禁止ADC轉換,計算傳感器頻率
- // ADC_Cmd(ADC1,DISABLE);
- // LED0 = !LED0;
- // for(k=0;k<SEND_BUFF_SIZE;k++)
- // {
- // fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
- // fft_inputbuf[2*k+1] = 0;
- // }
- // //計算頻率,傅里葉變換
- // arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計算(基4)
- // arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE); //把運算結果復數求模得幅值
- // //計算基頻
- // FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
- // //得到初始頻率
- // ExsistingFreq = (u16)FundamentalFreq;
- // printf("FFT Result:\r\n");
- // printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
- }
- // }
- delay_ms(100);
- printf("The %d times:\r\n",j);
- //開始采樣
- ADC_Cmd(ADC1,ENABLE);
- //等待采樣完成
- while(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==RESET);
- //DMA傳輸完成,清除標志位,等待下次DMA傳輸
- DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);//清除DMA2_Steam7傳輸完成標志
- //禁止ADC轉換,計算傳感器頻率
- ADC_Cmd(ADC1,DISABLE);
- LED0 = !LED0;
- for(k=0;k<SEND_BUFF_SIZE;k++)
- {
- fft_inputbuf[2*k] =(float)(ADCDMA_DATA[k]*(3.3/4096));
- fft_inputbuf[2*k+1] = 0;
- }
- //計算頻率,傅里葉變換
- arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計算(基4)
- arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,SEND_BUFF_SIZE); //把運算結果復數求模得幅值
- //計算基頻
- FundamentalFreq = CalMax_FREQ(fft_outputbuf,SEND_BUFF_SIZE/2);
- for(i=0;i<10;i++)
- {
- if(fft_inputbuf[2*i])
- {
- INC_FREQ_Flag = 0;
- }
- else
- {
- INC_FREQ_Flag = 1;
- }
- }
- if(0 == INC_FREQ_Flag)
- {
- //更新激勵頻率
- ExsistingFreq = (u16)FundamentalFreq;
- }
- // //得到初始頻率
- // ExsistingFreq = (u16)FundamentalFreq;
- printf("FFT Result:\r\n");
- printf("The ExsistingFreq Frequency: %d\r\n",ExsistingFreq);
- //串口打印頻率
- printf("FFT Result:\r\n");
- printf("The Fundamental Frequency: %f\r\n",FundamentalFreq);
-
- delay_ms(1000);
- //使能激勵信號
- // TIM_Cmd(TIM14, ENABLE); //使能TIM14
- // delay_ms(50);
-
- }
- }
- float CalMax_FREQ(float *Data, u16 DataSize)
- {
- u16 i;
- u16 MaxIndex = 1;
- float CalFreq = 0;
- for(i=1;i<DataSize;i++)
- {
- // printf("%f\r\n",Data[i]);
- if(Data[i]>Data[MaxIndex])
- {
- MaxIndex = i;
- }
- }
- CalFreq = (float)MaxIndex* SAMPLE_FREQ/SEND_BUFF_SIZE;
- return CalFreq;
- }
復制代碼
全部資料51hei下載地址:
定時ADC+DMA +FFT-0118.rar
(1.12 MB, 下載次數: 250)
2018-7-21 18:11 上傳
點擊文件名下載附件
|