- #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)
|