STM32CubeMX配置ADC采样(轮询、中断、DMA)

这篇具有很好参考价值的文章主要介绍了STM32CubeMX配置ADC采样(轮询、中断、DMA)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32CubeMX能够极大减小STM32外设配置的工作量,因此作者也借助空闲时间对STM32CubeMX相关配置进行了学习,本文介绍如何利用STM32CubeMX配置ADC采样,记录了作者学习过程中遇到的问题及解决办法,使大家少走弯路,并方便以后复习

1、单通道轮询

hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
先选择所使用的MCU,这里我使用的是STM32F407ZGT系列
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
修改一下DEBUG功能,否则后续无法调试
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
修改时钟,采用外部晶振
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
配置一串口,用于打印采集的ADC值
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
这里我采用ADC1的通道0,并开启连续采样模式,否则每次开启ADC采样后只进行一次采样
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
开启ADC全局中断(如果只采用轮询采样就不用开启,这里开启是为了方便后面演示中断采样
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
修改一下ADC全局中断的优先级
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
在HCLK处输入其时钟最高频率168,按回车,其余时钟会自动配置好,一般情况下无需改动
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
勾选上后,每个外设会单独保存至一个.c文件,便于查看
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
生成并打开文件
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
在main.h中包含头文件stdio.h
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
在usart.c文件中加入fputc函数,加入后才能使用printf函数进行打印数据
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机

在while循环中添加以上代码,由于开启了连续转换模式,即hadc1.Init.ContinuousConvMode = ENABLE;因此每次转换完成后都要调用HAL_ADC_Stop来关闭ADC;如果不想每次都调用该函数来关闭ADC,可以关闭连续转换模式,即hadc1.Init.ContinuousConvMode = DISABLE,这样每次开启ADC转换以后只会进行一次采样,这样就不需要每次都关闭ADC了
实验现象如下图:
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机

2、单通道中断

单通道中断采样配置过程与单通道轮询采样相同,利用cubemx配置完成后有两种开始ADC采样的方法
方法一
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
在主函数中加入上述代码,__HAL_ADC_ENABLE_IT(&hadc1,ADC_IT_EOC);用于打开ADC转换完成中断,HAL_ADC_Start(&hadc1);用于开启ADC采样,这两个函数一定要放到外设初始化函数的后面,否则串口函数初始化未完成,在ADC中断中使用printf函数可能会卡死
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
在adc.c文件中加入上面代码,HAL_ADC_ConvCpltCallback是ADC中断的回调函数,其原型是个弱函数,重新定义后原来的函数就失去作用了
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
最后将adc.c文件中的通道转换结束标准修改为ADC_EOC_SEQ_CONV,否则只会进入一次中断
ADC_EOC_SEQ_CONV:在所有通道转换完成后进入中断
ADC_EOC_SINGLE_CONV:单个通道转换完成后进入中断
多个通道时,两种均可采用,单通道采样时需使用ADC_EOC_SEQ_CONV才能连续进入中断(经测试)

最后将程序下载到单片机中,现象如下:
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
方法二
我们利用HAL_ADC_Start_IT开启adc中断,该函数比较特殊,调用一次该函数就打开了ADC转换完成中断开启ADC采样
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
在主函数中直接调用HAL_ADC_Start_IT即可

3、单通道DMA

dma有两种模式,分别为circular和normal
circular模式:dma的circular模式只需要调用一次dma开启函数,dma就会持续的搬运数据,提高了数据的刷新速度,但是在circular模式下,不管adc新的一轮数据采集是否完成,有可能直接将旧数据搬运走
normal模式:该模式下,dma启动函数调用一次,dma通道只会搬运一次数据,这样每调一次dma启动函数,dma只会搬运一次数据,等待数据传输完成后再次开启dma启动函数,这样更能保证adc数据采集的可靠性
circular模式:
cubemux配置步骤如下(时钟配置等已略去):
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
这里我们同样用ADC1的通道IN0来测试,开启adc连续采集模式
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
修改ADC采样时间,通常采样时间越长,adc采样精度越高
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
选用dma的circular模式
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
返回开启dma连续请求(若不开启,只能进入一次dma采集完成中断函数

 uint16_t AD_value=0;
 float f_AD_value;

打开工程文件,在文件中添加上面代码,AD_value用于保存测量的adc原值,f_AD_value保存计算得到的电压值

 HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&AD_value,sizeof(AD_value));

在主函数中调用HAL_ADC_Start_DMA开启adc采样,同时开启dma传输数据(调用一次即可
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
最后在dma中断函数中添加上述代码,将adc采集完成的数据打印出来
normal模式:
normal模式下,我们的想法是调用一次HAL_ADC_Start_DMA函数,adc进行一次数据采集,dma搬运一次数据,我们在上面配置完成的代码中做简单修改就能实现
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
关闭adc连续采集模式,这样开启一次adc,只会进行一次数据采集
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机

将dma模式修改为normal
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
修改dma中断函数

 HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&AD_value,sizeof(AD_value));

最后在主函数中调用HAL_ADC_Start_DMA开启adc采样,同时开启dma传输数据(每调用一次只会采集一次数据

4、多通道轮询

hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
这里用ADC1的通道IN0、IN1、IN2、IN3四个通道作演示,多个通道时必须开启间断模式,并且每个间断组中只有一个通道,否则每次只能读取到每组最后一个通道的值
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
设置通道转换顺序

uint16_t AD_value[4]={0};

打开工程文件,创建一数组用于存储四个通道的ADC值

for(i=0;i<4;i++){
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,10);
AD_value[i]=HAL_ADC_GetValue(&hadc1);
printf("PA%d:%d\r\n",i,AD_value[i]);
printf("PA%d:%.3f v\r\n",i,AD_value[i]*3.3/4096);
}
HAL_Delay(500);

在主循环中添加上述代码,HAL_ADC_Start必须放在for循环中,否则只能采集第一个通道的ADC值;HAL_ADC_PollForConversion用于轮询转换,是一个阻塞函数,等待转换完成,参数10是阻塞时间

5、多通道中断

多通道情况下使用中断来读取数据理论上是可行的,但是读取的数据会混淆,即无法确定读取的数据是属于哪一个通道的,因此我们不使用

6、多通道DMA

hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机

hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机

hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
开启DMA并采用circular模式

uint16_t AD_value[4]={0};

定义一数组用于保存ADC采样值
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
在外设初始化函数下面调用 HAL_ADC_Start_DMA(&hadc1,(uint32_t*)AD_value,sizeof(AD_value));启动ADC转换和DMA数据传输
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
最后在DMA接收完成中断中将采集到的ADC数据打印出来
经测试:DMA接收中断在数据接收缓冲区满了后触发,这里的缓冲区是数据AD_value[4]

注意:
通常为了方便使用一些滤波算法,我们可以将缓冲区数据创建的更大一些(为通道数的整数倍),这里我们采用了4个通道,我们可以将缓冲数组创建为AD_value[40]
则AD_value[0]、AD_value[4]、AD_value[8]…AD_value[36]均为通道IN0的值
AD_value[1]、AD_value[5]、AD_value[9]…AD_value[37]均为通道IN1的值,
AD_value[2]、AD_value[6]、AD_value[10]…AD_value[38]均为通道IN2的值,
AD_value[3]、AD_value[7]、AD_value[11]…AD_value[39]均为通道IN3的值,

hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
我们同样在dma接收完成中断中将数据打印出来
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
实验现象如上,只打印了一次数据,表示只进入了一次DMA中断中,并且主循环中的程序也不再继续执行,程序卡死了
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
可以在进入DMA中断函数时调用HAL_ADC_Stop_DMA来关闭ADC采集,当需要采集ADC的时候再调用 HAL_ADC_Start_DMA即可,这里为了演示在中断函数结束时又重新开启了ADC
hal_adc_start_dma,STM32,单片机,嵌入式,stm32,单片机
这样就能连续采集打印数据了文章来源地址https://www.toymoban.com/news/detail-780285.html

到了这里,关于STM32CubeMX配置ADC采样(轮询、中断、DMA)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【STM32+HAL库+CubeMX】UART轮询收发、中断收发、DMA收发方法及空闲中断详解

    Author: DrinkCat(szt@drinkcat.com) Copyright © 2023 DrinkCat Original link: DrinkCat’s Blog UART是一种异步串行通信接口,常用于通过串口与外部设备进行通信。它通过发送和接收数据帧来实现数据传输,使用起来相对简单。UART通常包含发送器(Transmitter)和接收器(Receiver),通过两根信号线

    2024年02月10日
    浏览(37)
  • 【STM32】CUBEMX之串口:串口三种模式(轮询模式、中断模式、DMA模式)的配置与使用示例 + 串口重定向 + 使用HAL扩展函数实现不定长数据接收

    目录   总览 使用CUBEMX创建工程的基本配置 CUBEMX中的配置 Keil中的配置 实物连接 串口轮询模式 轮询模式HAL库函数 特点 实验一:发送数据给单片机并让其返回相同值 串口重定向 串口中断模式 在CUBEMX中打开串口中断 中断模式HAL库函数 特点 实验二:使用中断回调完成实验一

    2024年04月10日
    浏览(65)
  • 搭建stm32电机控制代码框架(三)——Stm32CubeMx配置ADC采样

    电机控制另一个关键的模块就是ADC采样,这个模块配置的好坏决定了采样电流和电压的精准度,因此有必要对其进行深入学习。 简介: STM32 在片上集成的ADC 外设非常强大。STM32F103xC、STM32F103xD 和STM32F103xE增强型产品内嵌3个12位的ADC,每个ADC 共用多达 21 个外部通道,可以实现

    2024年02月13日
    浏览(40)
  • 电机FOC控制(三)STM32 CUBEMX 配置ADC采样

    本文在电机FOC控制(二)STM32 CUBEMX 配置三相PWM互补输出基础上,继续讲述如何STM32 CUBEMX 配置ADC寄存器,使TIMER1 PWM互补输出CC4触发ADC注入采样的过程。 打开Clock Configuration界面,将ADC设置为42.5MHz。 设定ADC1通道7和通道8为单端输入: 设定ADC2通道6和通道7为单端输入: ADCs_Comm

    2024年04月23日
    浏览(40)
  • STM32CubeMX配置-ADC多通道配置(DMA) (STM32G070)

    一、写在前面         ADC通道采集数据的两种方式:         1)ADC轮询采集数据直接放到数组中;         2)采用中断方式,ADC采集完成进入中断,中断关闭ADC采集,取数据之后再打开ADC采集。 以下按第一种方式实现: 二、ADC多通道配置 1)配置通道及参数     如果要控

    2024年02月05日
    浏览(49)
  • STM32 cubemx配置DMA+空闲中断接收不定长数据

    本篇文章给大家讲解一下DMA+串口空闲中断接收串口不定长数据,之前我们也是讲解过串口接收不定长数据的,那么本篇文章的话将使用DMA来接收不定长数据。 串口空闲中断是指在串口接收到数据后,在数据的传输结束之后,在一段连续的空闲时间内没有接收到新数据时触发

    2024年02月19日
    浏览(53)
  • STM32初学入门笔记(3):STM32CubeMX配置STM32实现多通道ADC+DMA读取模拟量

    模拟信号的读取是我们在做很多项目是都要用到的,而模拟量的读取就要依赖于ADC数模转换器。对于初学者,学习使用ADC可以很大的帮助以后的STM32学习。 目录 ADC简介 : DMA简介:  工程开始: STM32CubeMX配置区: 配置外部时钟: 配置调试: 配置ADC: 配置DMA: 配置串口: 配

    2024年02月09日
    浏览(46)
  • STM32CubeMX配置STM32G031多通道ADC + DMA采集(HAL库开发)

     时钟配置HSI主频配置64M  勾选打开8个通道的ADC  使能连续转换模式  添加DMA  DMA模式选择循环模式  使能DMA连续请求 采样时间配置160.5 转换次数为8  配置好8次转换的顺序  配置好串口,选择异步模式 配置好需要的开发环境并获取代码  修改main.c 串口重定向  串口重定向

    2024年02月08日
    浏览(54)
  • STM32CubeMx配置ADC(多通道采集+DMA读取数据)(HAL库开发)

    目录 1、函数配置过程(这是标准库配置过程): 2、STM32CubeMx配置过程  3、main函数源文件 采集5路ADC数据,并用串口printf()函数打印出来。 实验现象:  ADC转换的初始条件: 1、使能 2、触发源条件完成(这个需要自己配置)利用:HAL_ADC_Start_DMA()函数; ADC中HAL开发优势就是,

    2023年04月08日
    浏览(74)
  • STM32 ADC单/多通道采样+DMA搬运

    通过介绍我们可以了解到,ADC是12位的转换器,所以采样值范围是0~4095。18个通道可同时进行转换,也可以单独转换某个通道。 使用ADC的流程应为: 初始化IO口。 我这里使用的是PA1进行采样,也就是ADC1的通道1 初始化ADC。 转换、获取采样值。 多通道的时候我们一般用DMA来搬

    2024年02月14日
    浏览(47)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包