STM32 ADC+定时器+DMA+FFT

这篇具有很好参考价值的文章主要介绍了STM32 ADC+定时器+DMA+FFT。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本次实现的功能为单片机DAC输出一个正弦波,然后ADC定时采样用DMA输出,最后对DAC输出的波形进行FFT。

单片机STM32F103ZET6

内部时钟

一、配置ADC

ADC端口为PA1,采用DMA输出,定时器3触发

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档
stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档
stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档
stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

定时器时钟64M,分频后为102.4KHz

ADC采样时间为102.4KHz/100=1.024KHz

二、配置DAC

DAC端口PA4

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

DMA传输

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

定时器6

定时器时钟64M,分频后为1MHz

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

三、配置DSP

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档
stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

四、配置时钟

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

四、代码

注意生成的代码里初始化中DMA要在ADC之前

FFT需要#include "arm_math.h"头文件

需添加include

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档
stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档
stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

在define后面补全USE_HAL_DRIVER,STM32F103xE,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING,__FPU_PRESENT=1

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

main中加入ADC、DAC与FFT代码

uint16_t ad_value;          
uint16_t adc_buffer[1] = {0};

HAL_TIM_Base_Start(&htim3);
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adc_buffer,1);

HAL_TIM_Base_Start(&htim6);
SineWave_Data(n,DualSine12bit,1.6);
HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,(uint32_t *)DualSine12bit,n,DAC_ALIGN_12B_R);

arm_cfft_radix4_instance_f32 scfft;        //FFT对应结构体变量
arm_cfft_radix4_init_f32(&scfft,fft_adc_n,0,1); //初始化scfft结构体,设置FFT相关参数

SineWave_Data是产生正弦波的点(子函数)

#include "math.h"
#define n 100
uint16_t DualSine12bit[n];
//num:要在一个正弦波中采集多少点
//*D:创建的一个数组用来存放正弦波各个点的数值的
//U:输出电压的峰值(0~1.5V)
//Pi:3.1415926 自己定义
void SineWave_Data( uint16_t num,uint16_t *D,float U)
{
    uint16_t i;
    for( i=0;i<num;i++)
    {
        D[i]=(uint16_t)((U*sin(( 1.0*i/(num-1))*2*3.14159265358979)+U)*4095/3.3);
    }
}

FFT定义

#define fft_adc_n 1024    // 采1024个点
uint16_t i;
float adc_data[fft_adc_n*2]={0};        // 存ADC值
float fft_in_adc_data[fft_adc_n*2]={0}; // FFT输入,实部是ADC值,虚部补0
float fft_out_adc_data[fft_adc_n]={0};  // FFT输出

/*********************************************************************
    Name          : FFT_deal0(short int *data, float *fft_in,int data_length)
    Funcation :对波形数据进行补零操作
    Parameter :    short int *data        波形信号
                float *fft_in            输入信号(信号长度应是输出信号的2倍)
                int data_length        输出信号长度(与波形信号长度保持一致)
    Return    无
********************************************************************/
void FFT_deal0(float *data, float *fft_in,int data_length)
{
        for(int i = 0;i < data_length;i++)
        {
            fft_in[2*i] = data[i];
            fft_in[2*i+1]=0;
        }
}

在ADC回调函数中加入标志位

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    ad_flag=1;
}

主函数

        while(i<fft_adc_n)  //等待1024个点
        {
            if(ad_flag==1)
            {
                i++;
                ad_flag=0;
                ad_value=HAL_ADC_GetValue(&hadc1);
                adc_data[i]=ad_value;
            }
        }
        
        for(i=0;i<fft_adc_n;i++)   //打印采集到得ADC值
        {
            printf("%.2f\r\n",adc_data[i]);
        }
        
        //FFT
        FFT_deal0(adc_data,fft_in_adc_data,fft_adc_n);                                //对采集后的数据进行补0,补足虚部
        arm_cfft_radix4_f32(&scfft,fft_in_adc_data);                                            //FFT计算(基4)
        arm_cmplx_mag_f32(fft_in_adc_data,fft_out_adc_data,fft_adc_n);            //把计算结果复数求模得幅值 
        
        printf("ffffffffffffffffffff\r\n");
        //打印FFT输出
        for(i=0;i<fft_adc_n;i++)
        {
            fft_out_adc_data[i]=fft_out_adc_data[i]*0.0008056640625;
            printf("%.2f\r\n",fft_out_adc_data[i]);
        }
        while(1);

将采集到得ADC放入Excel打印出来

波形频率50Hz

1.024KHz采样频率采集1024个点,刚好50个波形

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

FFT分析后得波形

stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档
stm32 定时器dma,stm32,单片机,嵌入式硬件,Powered by 金山文档

可以看到频率为50左右,还是比较精准的文章来源地址https://www.toymoban.com/news/detail-543849.html

到了这里,关于STM32 ADC+定时器+DMA+FFT的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】定时器1触发ADC多(规则)通道采样+DMA(CUBEMX配置)

    在用单片机做电源控制时不得不提ADC采集,离散系统是有固定的执行周期的,所以我们采样也是要固定时间去采样。然后就是我希望pwm波(定时器1产出)的频率与采样频率一致。 我下面演示的是G431CBU6,当然其他芯片也大差不差了。 说一下大致流程,TIM1触发ADC采样,然后

    2024年02月01日
    浏览(42)
  • STM32定时器DMA连续传送功能示例

    在STM32定时器应用中,定时器事件配合DMA连续传输可对定时器的多个寄存器进行读写访问。 定时器事件可以请求DMA,分为以下几种;并不是所有定时器都支持以下事件, 高级定时器是支持的。其他定时器按功能部分支持,例如基础定时器因为没有输出输入通道,所以只有更新

    2024年02月11日
    浏览(37)
  • STM32 HAL库定时器触发DMA并口数据传输

    STM32与FPGA通讯,通过8位并口线进行通讯,16byte的数据在10us之内通过8位并口数据线传给FPGA,FPGA读取该数据。 时钟采用80MHz,由于16byte的数据要在10us之内传完,那么10/(16*2)=0.3125us/次,也就是传输频率得≥3.2MHz。 定时器设置:为了方便起见,先选用了4MHz的传输频率。80MHz

    2024年02月02日
    浏览(63)
  • STM32 HAL库 Timer(定时器)+DMA输出PWM底层配置过程学习

    本文使用的芯片型号是STM32G030,写本文的目前是想记录学习下Timer借助DMA生成可变占空比PWM时的底层配置过程。 使用TIM1,配置就只改了图上的配置,系统时钟用的16M,分频选择15(16-1),自动重装载寄存器ARR选择999(1000-1),那么生成的就是1kHz的PWM,这里为什么要减1,因为这俩是

    2024年04月09日
    浏览(55)
  • STM32 DMA1和DMA2通道一览表、STM32F103C8T6定时器通道对应的引脚

    TIM1_BRK_IRQn               = 24,      TIM1_UP_IRQn                = 25,      TIM1_TRG_COM_IRQn           = 26,     TIM1_CC_IRQn                = 27,     TIM2_IRQn                   = 28,     TIM3_IRQn                   = 29,    这个函数TIM_SetCompare1,这个函数有四个,分别是TIM_SetC

    2024年02月05日
    浏览(37)
  • STM32G0 定时器PWM DMA输出驱动WS2812配置 LL库

    优点:不消耗CPU资源 缺点:占用内存较大 定时器配置 定时器通道:TIM3 CH2 分频:0 重装值:79,芯片主频64Mhz,因此PWM输出频率:64Mhz/79 ≈ 800Khz,满足芯片要求。 auto-reload preload 要关闭 output compare preload 要打开 DMA配置 外设一定要选择TIM3_UP,不要选TIM_CHx 方向是内存到外设,

    2024年02月10日
    浏览(34)
  • 软件STM32cubeIDE下STM32F1xx使用定时器(TIM8)+DMA+PWM点亮灯带WS2812-基础样例

    好长时间不调试灯带ws2812了,最近项目上,要在STM32F1上进行点灯带ws2812,虽然自己之前做了很多了,但是人有个性质,一旦某个事情做完了,你不在去惦记它了,基本会完全抛在脑后。所以才体现记录的重要性,本次在做STM32F1上验证时,即使之前有经验的情况下,还是掉坑

    2024年02月01日
    浏览(53)
  • Note10:基于STM32H7+HAL+CubeMX+DMA+SPI+串口中断+定时器+RTC的多传感器数据采集系统(2*ADXL355和ADXL375通过Sync时序同步)

    本文的初衷一方面是将我的一些关于STM32开发方面浅显的个人经验分享给初学者、并期望得到大佬的批评指正,另一方面是记录自己的实验过程便于回顾。 我预感应该要写很多,不过鉴于之前的数篇笔迹中,对于SPI/DMA/ADXL3XX系列加表的使用已经详细描述过了,所以这篇博客只

    2024年02月10日
    浏览(44)
  • STM32 ADC转换+DMA传输(详解)

            最近刚入坑,看了半个多月的入门视频并动手了一些简单的实验,但看工程项目的代码总是很费劲,便想以一个有难度的课题来进一步入门嵌入式开发。这个选题充分使用了STM32的各种片上外设,包括定时器、ADC模/数变换、GPIO口和DMA的使用,配合外部资源如LCD屏幕来

    2024年02月03日
    浏览(30)
  • STM32 ADC采集 DMA中断处理

    //============================================ //函数名称:ADC1_Mode_Config(void) //功能描述:配置ADC1的工作模式为MDA模式 //输入:无 //输出:无 //============================================ void ADC1_Mode_Config(void) {         DMA_InitTypeDef DMA_InitStructure;         ADC_InitTypeDef ADC_InitStructure;              

    2024年02月14日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包