STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx_tim+adc+dma-程序员宅基地

技术标签: 冬令营  stm32  电赛模块  arm  单片机  

ADC+TIM+DMA采集交流

前言

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

所需工具:

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

相关文章:

模式简介

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

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

工程建立

时钟配置

image-20211213205147618

image-20211213205045357

ADC配置

image-20211213205305370

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

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

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

image-20211213205611953

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

image-20211213211113320

采样率控制在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

配置串口

image-20211213205856436

代码生成

image-20211213210039737

image-20211213210101284

image-20211213210118878

代码编写

串口重定向

image-20211213210432148

#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;
}

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

image-20211213210527822

#include <stdio.h>

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

image-20211213220835401

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

ADC采集代码

image-20211213215904440

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优化掉。

image-20211213220302661

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); //数据打印,查看结果
}

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

希望读者养成随手写注释的好习惯。
QQ图片20220225105335

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

image-20211213220458038

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 信号发生器地 跟信号发生器共地

在这里插入图片描述

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

在这里插入图片描述

运行结果

image-20211213214544474

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

image-20211213214752190

为了验证采样率是否是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文库

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34022877/article/details/121941236

智能推荐

通过网盘直链程序AList,挂载网络硬盘_alist挂载smb局域网的磁盘-程序员宅基地

文章浏览阅读737次。通过网盘直链程序AList,挂载网络硬盘_alist挂载smb局域网的磁盘

卷积神经网络Lenet-5详解_迭代次数 lenet-5-程序员宅基地

文章浏览阅读1.4k次。卷积神经网络Lenet-5实现原文地址:http://blog.csdn.net/hjimce/article/details/47323463作者:hjimce卷积神经网络算法是n年前就有的算法,只是近年来因为深度学习相关算法为多层网络的训练提供了新方法,然后现在电脑的计算能力已非当年的那种计算水平,同时..._迭代次数 lenet-5

C# Base64图片编码和解码_c# 图片base64-程序员宅基地

文章浏览阅读1w次,点赞7次,收藏13次。Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。 Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为..._c# 图片base64

autoresponsive-react实现瀑布流-程序员宅基地

文章浏览阅读1.9k次。import AutoResponsive from "autoresponsive-react"; componentDidMount() { this.setState({ containerWidth: (document.body.clientWidth || document.documentElement.clientWidth) - 3..._autoresponsive

IntelliJ IDEA 编辑时报错:找不到引用的jar包_idea springboot 编译找不到jar包类-程序员宅基地

文章浏览阅读3.1w次,点赞6次,收藏11次。记录一个奇怪的IDEA错误:编辑时一直报错,显示找不到引用的红色字体。我的情况:通过Maven来引用jar包,如Spring Boot。 External Libraries中明明能看到被引用的包,但是在编辑时却一直是表明引用不存在的红色字体(如@SpringBootApplication这个注解都找不到,提示:Cannot resolve symbol 'SpringBootAppli..._idea springboot 编译找不到jar包类

hashMap_hashmap中每一个槽位是带有链表信息么-程序员宅基地

文章浏览阅读2.7k次,点赞4次,收藏22次。HashMapHashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表 HashMap的实例有两个参数影响其性能:“初始容量”和“装填因子” HashMap实现不同步,线程不安全,HashTable的线程安全 HashMap中的key-value都是存储在Entry中的 HashMap可以存null键和null值..._hashmap中每一个槽位是带有链表信息么

随便推点

尚学堂是怎么让一窍不通的我学会编程的?-程序员宅基地

文章浏览阅读135次。尚学堂的教学质量怎么样,说实在的,让我叹服,来尚学堂参加培训是对的,在这里我进步的非常快。如今我入职了,进入了一家让我感激的公司。为什么让我感激,因为让我去复试,我傻子似的居然没去,幸好公司又给了我一个机会。所以,我得在这家好好干,Fighting! 说实在的,我是转行过来学java的。本来...

服务器上安装oracle隔夜老挂,[转自Oracle官方博客]一次服务器时间调整引发的实例宕机...-程序员宅基地

文章浏览阅读145次。问题描述:1. 数据库实例突然crash,原因是ASMB有200多秒没有响应:Mon Sep 04 15:07:47 2017 WARNING: ASMB has not responded for 200 seconds <<<<<<<<<<<2. 从system state dump上看,ASMB看起来没有什么问题:Curren..._oracle安装第二天不见了

我是如何通过一个 XSS 探测搜狐内网扫描内网并且蠕动前台到最后被发现的-程序员宅基地

文章浏览阅读348次。我是如何通过一个 XSS 探测搜狐内网扫描内网并且蠕动前台到最后被发现的!(附带各种 POC) | WooYun-2014-76685 | WooYun.orghttp://wooyun.org/bugs/wooyun-2014-076685传送门: 文章很精彩转载于:https://www.cnblogs.com/dongchi/p/4073410.html..._利用xss进行内网探测

基于Java+SpringMvc+Vue求职招聘系统详细设计实现_springmvc的互联网招聘求职系统-程序员宅基地

文章浏览阅读1w次,点赞112次,收藏165次。随着计算机网络的不断渗透,人们的生活与工作、学习的方式也在慢慢发生变化。传统的大学生兼职信息系统相关信息管理方式一般都采取人工的方式,信息的获取、整理、修改、存储等工作还停留在人工阶段。这种方式一方面需要花费大量的人力、物力和金钱,交互起来比较困难,而且会浪费时间;另一方面对用户等信息的管理,特别是随着用户数量的递增,查询、修改起来特别困难;最后由于用户等其他信息的不断增加,信息的存储也成为了难题。一些发达国家,网络发展比较快,已经很大程度上完成了从人工到计算机管理的转变。_springmvc的互联网招聘求职系统

C语言之进制转换_c语言进制转换-程序员宅基地

文章浏览阅读3.2w次,点赞106次,收藏708次。进制转换非常简单,但又非常重要,在初学过程中是必须掌握的基础知识_c语言进制转换

html+css知识点全面总结(三)_html里的css里的step-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏7次。博主本人在学习前端入门初期时做的总结及笔记(三)适合前端初学者。希望多多交流讨论~~~_html里的css里的step

推荐文章

热门文章

相关标签