当前位置:网站首页>STM32F4单片机ADC采样及ARM-DSP库的FFT
STM32F4单片机ADC采样及ARM-DSP库的FFT
2022-04-23 03:56:00 【Chenxr32】
模拟信号经过ADC采样后变成数字信号,数字信号可以进行FFT运算,在频域中更容易分析信号的特征。本文将介绍如何用STM32F4的进行ADC采样,并利用ARMDSP库里的FFT算法对ADC采样值进行快速傅里叶变换。
我使用的是STM32F407VG单片机,由于需要的ADC采样值较多(采集了4096个点),所以配置了STM32的ADC和DMA,使用DMA将ADC采样值传输到内存效率更高。配置外设时,使用APB2时钟的2分频作为ADCCLK,ADC采样时间为84个ADCCLK,Tconv(总转换时间) = 采样时间+12个ADCCLK,理论上ADC的采样频率约4,375,00Hz。为了保证信号的完整性,由奈奎斯特定理知采样频率需要大于信号中最高频率的2倍,因此该外设配置方法测量的信号频率不应大于218,750Hz。外设配置代码如下:
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2|RCC_AHB1Periph_GPIOC,ENABLE);
while(DMA_GetCmdStatus(DMA2_Stream0)!=DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);
//init GPIO ADC1, channel 14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned int)&(ADC1->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = (unsigned int)&(fft.ADC_ConvertedValue[0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 4096;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0,&DMA_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ClearFlag(DMA2_Stream0,DMA_IT_TC);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);//使能数据流传输完成中断
DMA_Cmd(DMA2_Stream0,ENABLE);
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//84M/2 = 42M
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Cmd(ADC1,ENABLE);
ADC_RegularChannelConfig(ADC1,ADC_Channel_14,1,ADC_SampleTime_84Cycles);//转换时间84个ADC周期
ADC_SoftwareStartConv(ADC1);
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
ADC_DMACmd(ADC1,ENABLE);
接下来,将ADC的采样值转换为对应的电压值,利用DSP库的FFT算法进行FFT运算,计算幅频特性。这里,我使用的是基4浮点FFT算法,基4的算法比基2的算法运算速度更快。代码如下:
#define FFT_LENGTH 4096
void FFTTestTask(void *arg)
{
OS_ERR err;
CPU_TS ts;
arm_cfft_radix4_instance_f32 scfft;
int i = 0;
unsigned char str[10];
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//FFT初始化
while(1)
{
OSTaskSemPend(0,OS_OPT_PEND_BLOCKING,&ts,&err);//等待传输完成信号量
for(i=0;i<FFT_LENGTH;i++)
{
fft.fft_input[2*i] = (float)fft.ADC_ConvertedValue[i]*3.3f/4096.0f;//实部为ADC采样值
fft.fft_input[2*i+1] = 0;//虚部为0
}
arm_cfft_radix4_f32(&scfft,fft.fft_input);//FFT运算
arm_cmplx_mag_f32(fft.fft_input,fft.fft_output,FFT_LENGTH);//计算每个点的模值
for(i=0;i<FFT_LENGTH;i++)
{
sprintf((char*)str,"%.2f\r\n",fft.fft_output[i]);
board.UART4Send(str,strlen((char*)str));//将数据打印至串口助手,便于观察
OSTimeDly(1,OS_OPT_TIME_DLY,&err);
}
OSTimeDly(500,OS_OPT_TIME_DLY,&err);
board.ADC1_DMA2Enable();//重新启动ADC转换和DMA传输
}
}
实验中,我用FPGA和DAC做了DDS信号发生器,生成波形函数为。用上述方法采集电压信号进行FFT运算,最后使用MATLAB绘制了部分幅频特性曲线。直流分量的理论幅值为6758.4,实际值7168.2;基波分量的理论幅值为3379.2,实际值3454.3。
不足之处请大佬指正。
代码下载: STM32F4 ADC采样FFT运算测试代码
版权声明
本文为[Chenxr32]所创,转载请带上原文链接,感谢
https://blog.csdn.net/QDchenxr/article/details/97624652
边栏推荐
- 创下国产手机在海外市场销量最高纪录的小米,重新关注国内市场
- Wechat payment iframe sub page has no response
- 什么是软件验收测试,第三方软件检测机构进行验收测试有什么好处?
- ROS series (II): ROS quick experience, taking HelloWorld program as an example
- Common auxiliary classes
- CRF based medical entity recognition baseline
- ROS series (4): ROS communication mechanism series (4): topic communication practice
- 作为一名码农,女友比自己更能码是一种什么体验?
- 【测绘程序设计】坐标反算神器V1.0(附C/C#/VB源程序)
- What is software acceptance testing? What are the benefits of acceptance testing conducted by third-party software testing institutions?
猜你喜欢
[AI vision · quick review of today's sound acoustic papers issue 1] Thu, 14 APR 2022
QtSpim手册-中文翻译
Cause analysis of incorrect time of AI traffic statistics of Dahua Equipment Development Bank
51 single chip microcomputer: D / a digital to analog conversion experiment
ROS series (I): rapid installation of ROS
一个函数秒杀2Sum 3Sum 4Sum问题
创下国产手机在海外市场销量最高纪录的小米,重新关注国内市场
A function second kill 2sum 3sum 4sum problem
Writing latex with vscode - the latest tutorial 2022 / 4 / 17
将编译安装的mysql加入PATH环境变量
随机推荐
ROS series (III): introduction to ROS architecture
Process seven state transition diagram
How Zotero quotes in word jump to references / hyperlink
使用大华设备开发行AI人流量统计出现时间不正确的原因分析
Mysql出现2013 Lost connection to MySQL server during query
Activity supports multi window display
What is software acceptance testing? What are the benefits of acceptance testing conducted by third-party software testing institutions?
列表、元组、字典和集合的区别
【ICCV 2019】MAP-VAE:Multi-Angle Point Cloud-VAE: Unsupervised Feature Learning for 3D Point Clouds..
Summary of knowledge map (I)
【ICCV 2019】MAP-VAE:Multi-Angle Point Cloud-VAE: Unsupervised Feature Learning for 3D Point Clouds..
Wechat payment iframe sub page has no response
Network principle | connection management mechanism in TCP / IP important protocol and core mechanism
变量、常量、运算符
matlab读取多张fig图然后合并为一张图(子图的形式)
【测绘程序设计】坐标反算神器V1.0(附C/C#/VB源程序)
Raspberry pie 3B logs into the wired end of Ruijie campus network through mentohust, creates WiFi (open hotspot) for other devices, and realizes self startup at the same time
The difference between lists, tuples, dictionaries and collections
Concepts of objects and classes
Summary of knowledge map (3)