STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

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

ADC+TIM+DMA采集交流

前言

本文主要讲解定时器触发ADC去采集交流信号,DMA把数据搬移到内存。

所需工具:

  • 开发板:STM32F103C8T6
  • STM32CubeMX
  • IDE: Keil-MDK

相关文章:

  • STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx(二)
  • STM32cubemx ADC+TIM+DMA超频采样

模式简介

ADC+TIM+DMA采集交流信号是电赛中使用范围最为广泛的一个技术。这个模式下单个ADC可以实现0-1M的任意可调采样率,采集20khz一下的信号轻轻松松。

F1的ADC支持许多触发信号,这里选择TIM3的TRGO事件作为触发信号,其中TRGO选择更新时间来引起。(这段新手看不懂没关系,不耽误使用)

工程建立

时钟配置

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

ADC配置

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

相对于ADC采集直流,这里的触发源不是软件上的一行代码来触发,而是选择外部触发,这里选择TIM3的TRGO信号。

对于新手来说这里可能有疑惑,换成硬件触发有什么好处吗?查看系列的上一篇文章,软件触发ADC采样一次,需要写几行代码,才能让他们采集一次,如果我们想实现100hz的采样率,可以设置一个100hz的定时器中断,在中断里用代码(软件)触发ADC采样,这样确实可以达到100hz采样的效果。可是如果100k采样呢?CPU代码执行的速度是有限的,100hz可以勉强达到,100k就来不及了。但是我让TIM这样的硬件去触发ADC采样,ADC采集完成后,DMA硬件搬运数据,整个采集过程不需要CPU参与。

直观上看就是你告诉ADC,TIM,DMA你们仨给我100k采样率采集1000个点.说完这句话后,他们三就去采集了,CPU只需要等他们采集完成就可以。采集过程CPU不管的,也就是不需要写任何代码。

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

DMA配置为normal模式。如果配置成circular的话,ADC采集完成指定个数后,不会停下来,不方便管理。读者可以修改成circular看看效果。

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

采样率控制在100kz,那么TIM就需要产生100khz的TRGO的信号,我们这里选择的更新时间产生TRGO信号,那么TIM3的计数器从0计算到ARR的频率为100khz。于是我们这里设置PSC=0,ARR=720-1。换算下: 72 M 720 = 100 k \frac{72M}{720}=100k 72072M=100k

配置串口

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

代码生成

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

代码编写

串口重定向

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

#include <stdio.h>

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

这里是串口重定向的主体部分

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

#include <stdio.h>

在mian.c里面包含stdio.h头文件,mian.c里面就可以printf了。别的.c文件同理。

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

勾选MicroLIB库,否则没法使用printf

ADC采集代码

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

uint16_t adc_buff[200];//存放ADC采集的数据
/* 
AdcConvEnd用来检测ADC是否采集完毕
0:没有采集完毕
1:采集完毕,在stm32f1xx_it里的DMA完成中断进行修改
 */
__IO uint8_t AdcConvEnd = 0;

在main.c里面定义两个变量,一个存放ADC采集到的数据,一个标志ADC是否采集完毕。

特别注意__IO修饰AdcConvEnd。他的含义是volatile。避免AdcConvEnd被MDK优化掉。

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

HAL_TIM_Base_Start(&htim3);                           //开启定时器3
HAL_ADCEx_Calibration_Start(&hadc1);                  //AD校准,F4不用校准没用这行函数。
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_buff, 200); //让ADC1去采集200个数,存放到adc_buff数组里
while (!AdcConvEnd)                                   //等待转换完毕
    ;
for (uint16_t i = 0; i < 200; i++)
{
    printf("%.3f\n", adc_buff[i] * 3.3 / 4095); //数据打印,查看结果
}

这里写的采集程序,如每一步的含义都在注释里写明了。

希望读者养成随手写注释的好习惯。
STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

extern uint8_t AdcConvEnd;//引入外部变量

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

AdcConvEnd = 1;

ADC采集,DMA搬运,当DMA搬运结束后,整个采集过程也就完成了。DMA搬运结束,程序会接收到DMA中断,就会执行DMA1_Channel1_IRQHandler函数,告诉CPU,采集完毕了。程序上则根据AdcConvEnd的变化,得知采集完毕。

硬件连接

引脚 连接对象 释义
PA9 CH340的RX 单片机的TX连接CH340的RX
PA10 CH340的TX 单片机的RX连接CH340的TX
PA0 信号发生器信号端 图中红线
GND 信号发生器地 跟信号发生器共地

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

上面总共有STlinkV2,ch340,供电线,信号发生器接过来的夹子线

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

运行结果

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

ADC去采集信号发生器产生的1k正弦信号,数据打印到VOFA上,结果如图。

STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx

为了验证采样率是否是100k,ADC去采集信号发生器产生的5k信号,打印到VOFA上,可以看到一个周期20个点。 5 k ∗ 20 = 100 k 5k*20=100k 5k20=100k采样率为100k验证完毕。

VOFA的使用可以在电赛小站里查看到教程。

练习

  1. 尝试在例程的基础上更改采样率200k、500k等,看看效果。

    练练手,打野怪刷熟练度。

  2. 思考如何借助均值滤波来提高采样精度,并付诸实践。

    这是最容易实现的降噪方法。你可以不会FIR、滑动滤波器等,这个还是要会的。元气骑士拿破旧的手枪也是可以通关的嘛。

    提示:如果你没什么思路请看这里。比如我们去采集1k的正弦,想采集一个周期100个点,你可以设置采样率为100k,那么采集100个点就结束了。也可以设置采样率为200k,然后一个周期采集200个点,然后每两个点取平均,这样就可以达到2次均值滤波。

    啥?还是不懂?就是数组的下标0和下标1取平均( X [ 0 ] + X [ 1 ] 2 = Y [ 0 ] \frac{X_{[0]}+X_{[1]}}{2}=Y_[0] 2X[0]+X[1]=Y[0])作为第一个采样点,下标2和下标3取平均( X [ 2 ] + X [ 3 ] 2 = Y [ 1 ] \frac{X_{[2]}+X_{[3]}}{2}=Y_{[1]} 2X[2]+X[3]=Y[1])作为第二个采样点。

    这个方法有个高级的称呼:过采样。H7自带硬件过采样STM32H7 ADC 过采样对精度的影响效果

  3. 先以100k的采样率采集一组信号,再通过程序更改定时的频率来将采样率改成200k,再采集一组数据。期间不能重新烧录代码

    学会动态更改采样率。

    提示一下可以采用这种方式更改:

    TIM1->ARR=...;
    TIM1->PSC=...;
    
  4. 如果你会测量频率,尝试控制采样率始终是待测信号的100倍。

    这技巧在FFT变化方面对提高精度有奇效。

后记

本文章收录于:

唐承乾的电赛小站

本文为系列文章中的冰山一角,欢迎进入小站查看。

配套程序:

STM32的ADC+DMA+TIM采集交流信号.zip-嵌入式文档类资源-CSDN文库文章来源地址https://www.toymoban.com/news/detail-435081.html

到了这里,关于STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32 CubeMX ADC采集 单通道,多通道,内部温度(轮询,DMA,中断)(HAL库)

    12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部 信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右 对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定

    2024年02月06日
    浏览(85)
  • 【STM32+HAL+Proteus】系列学习教程---ADC(查询、中断、DMA模式下的电压采集)

    1、学会STM32CubeMX软件关于ADC的配置 2、掌握ADC三种模式(查询、中断、DMA)编程 3、具体目标:1、将开发板单片机采集到的电压值上传至上位机串口调试助手显示。 ADC(Analog to Digital Converter)即模数转换器,用来将模拟信号转换为数字信号。 A/D转换过程 分辨率:  A/D转换器对

    2024年04月26日
    浏览(40)
  • 基于stm32+HAL库的ADC电压采集实验

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 只会用if的大神提醒您,敌军还有30秒到达战场,碾碎他们!白银局不要怕! 软件:keil5、stm32cubemx、串口调试助手 硬件:stm32f103系列的开发板、杜邦线*1、串口工具 仅此而已!!!正好6神 1、打开cube

    2023年04月15日
    浏览(44)
  • STM32基于hal库的adc以DMA的多通道采样以及所遇问题解决

    目录 准备 配置 步骤  总结   正点原子的STM32F103ZET6开发板(精英版) CUBEMX配置软件 KEIL5  右对齐就是正常的数据格式。左对齐除以16后得正常数据。(当输出非常大时考虑是否改了对齐方式,默认都是右对齐)  扫描模式,连续转换模式使能。(多通道下扫描模式自动使能

    2024年02月04日
    浏览(52)
  • STM32 HAL库 ADC+DMA

       软件触发:STM32 HAL库 软件触发ADC 多通道连续转换_随风飘零翼的博客-CSDN博客 配置如图      注意采样周期不要过小,不然频繁中断会导致在RTOS中卡死 写了部分关键代码,在两个任务中OLED和串口打印分别显示的通道值。 后来发现使用的杜邦线接触不良,固定好之后,接

    2024年02月14日
    浏览(41)
  • 基于STM32的ADC采样及各式滤波实现(HAL库,含VOFA+教程)_数据采集滤波算法stm32(3)

    2.2 VOFA+使用方法 VOFA+ 的数据协议引擎有 3种 : FireWater , JustFloat , RawData 。每种数据协议引擎都有自己特殊的使用效果,读者朋友可以根据自己的实际需要去选择使用。作者这里主要给大家演示一下 FireWater协议 下的VOFA+使用效果和方法。 FireWater协议 是 CSV风格 的字符串流,

    2024年04月23日
    浏览(48)
  • 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日
    浏览(50)
  • STM32Cubemx——ADC采集+DMA传输

    STM32F407VE核心板 STM32Cubemx 版本 6.0.1 Keil 版本 5.31 杜邦线 ST-Link 12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道,可测量来自 16 个外部源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续采样模式下进行。ADC 的结果存储在一个左

    2023年04月24日
    浏览(62)
  • STM32-单通道ADC采集(DMA读取)实验

    关于ADC的一些原理和实验我们已经有了2篇笔记,链接如下: 关于ADC的笔记1_Mr_rustylake的博客-CSDN博客 STM32-ADC单通道采集实验_Mr_rustylake的博客-CSDN博客 实验要求:通过ADC1通道1(PA1)采集电位器的电压,并显示ADC转换的数字量和换算后的电压值。 我们通过下表可以知道DMA1通道

    2024年02月16日
    浏览(56)
  • [HAL库]STM32 ADC功能和DMA读数据的方法

    这篇博客记录下 STM32F103R8T6 是怎么开ADC、用DMA搬数据的方法。方便日后使用的时候查资料。 DMA其实就是个搬运工,专门负责搬数据,没有DMA之前,搬数据是由MCU核心来负责,虽说都能完成搬数据的动作,但是MCU干这件事浪费资源且效率低,所以有DMA的场合尽量使用DMA来负责搬

    2024年02月14日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包