Bootstrap

STM32外设天造地设的一对:ADC和DMA

STM32外设天造地设的一对:ADC和DMA

引言:这篇文章主要介绍ADC和DMA配置的注意事项,适合懂得如何配置最基本的ADC和DMA,但是对它们两个的模式不是太理解的朋友们看,本文将重点介绍ADC和DMA模式的注意事项


DMA是CPU的小助手,负责完成数据转运的任务,一般的数据转运可以在主函数完成,但是如果数据量巨大,就不适合在main函数中转运了,因为那样会占用大量CPU进程。
ADC(数模转换器,这可不是lol里面的射手哦)就是一个例子,ADC需要不断采集模拟信号,交给CPU处理,数据量巨大,所有ADC如果出现了,那一般都会给它配置一个DMA来完成数据转运。

STM32的ADC和DMA配置有一些注意事项,在此强调一下:


ADC配置的注意事项:

扫描和非扫描:

要注意ADC可以选择扫描和非扫描,如果同时需要采集多个引脚的模拟信号,那就选择扫描;如果只有一个引脚负责采集,那就选择非扫描

连续和单次
单次模式:

如果选择单次转换,那每次转换完成(这里的“转换完成指的是:如果选择扫描,那么所有通道都转换完成了,才算转换完成;如果选择非扫描,那转换一次就叫做转换完成”),都需要调用ADC_ClearFlag(ADCx,ADC_FLAG_EOC)函数来手动清除转换完成标志位,并且再调用ADC_SoftwareStartConvCmd(ADCx,ENABLE)函数来开启下一次转换(如果你需要的话)

连续模式

这个模式只需要在配置完ADC之后,调用一次ADC_SoftwareStartConvCmd(ADCx,ENABLE)函数,之后就会一直进行ADC转换,不需要手动清除ADC_FLAG_EOC标志位


DMA配置注意事项:

DMA配置的地址自增问题就不用多说了 ,大家应该都会
这里重点说以下三个问题:

第一,DMA请求映像:

stm32的DMA硬件触发必须和DMA通道对应,这就是请求映像,请求映像可以在手册中查到,配置DMA硬件请求必须参照这个映像表!

第二,DMA_M2M模式

  • // 如果DMA选择M2M,则当使能DMA之后,DMA会立刻以最快的速度完成转运任务,将传输计数器
    // 变为0。然后就不再转运,如果此时想再次让其转运,需要给传输计数器重新赋值,
    // STM32手册规定,给传输计数器赋值必须先失能DMA再赋值。完成这两个操作之后,再次使能
    // DMA会继续立刻触发DMA转运,以此类推

//  给DMA失能,赋值传输计数器,给DMA使能三个操作如下:
	DMA_Cmd(DMA1_Channel1,DISABLE);//DMA失能,因为只有在失能状态下,才能给传输计数器重新赋值
	DMA_SetCurrDataCounter(DMA1_Channel1,4);//给传输计数器重新赋值
	DMA_Cmd(DMA1_Channel1,ENABLE);//DMA使能
  • // 在此说明以下DMA选择M2M的一个注意事项:如果选择M2M,则一旦给DMA上电,DMA会以最快的速度传输完成。
    // 传输计数器也会相应地变为0了,如果选择传输计数器重装,那就会立刻再次触发DMA转运,然后再重装再转运,因此, 程序就会一直卡死在DMA转运。所以,千万要注意:
    // M2M模式下,禁止选择传输计数器重装

第三,DMA_M2M_Disable模式:

这个模式就是硬件触发DMA转运,比如定时器CCR事件触发(当CNT<CCR,REF的电平为低电平,与PWM模式1相反)要想成功触发,要做3件事情:

  1. 配置好相应的触发事件,例如配置好定时器的CCR事件(初始化时基单元,配置TIM_OCInitTypeDef结构体等步骤)
  2. 调用触发DMA的相关外设函数(例如TIM_DMA,ADC_DMA等等)
  3. DMA_InitTypeDef的成员DMA_M2M要选择DMA_M2M_Disable(非软件触发,即硬件触发)
;