一。使用 DMA
由于常规通道组只有一个数据寄存器,因此,对于多个常规通道的转换,使用
DMA
非常有帮助。这样可以避免丢失在下一次写入之前还未被读出的 ADC_DR
寄存器中的数据。在使能 DMA 模式的情况下(
ADC_CR2
寄存器中的
DMA
位置
1
),每完成常规通道组中的 一个通道转换后,都会生成一个 DMA
请求。这样便可将转换的数据从
ADC_DR
寄存器传输到用软件选择的目标位置。
看下面这张图说明了,从ADC转换到Chanel的过程!
当有ADC读取到值后,发送DMA通道请求转换,然后单片机读取通道值进行存储和使用!
二。配置
看网上的讲解呢,说的都不太细,我这里尝试了下DMA,也遇到了些问题,把整个配置给大家看下,并标注注意的点!
(1) 配置参数
(2)设置dma循环扫描模式
(3)注意这里默认会为你开启:DMA channel1 全局中断,开了这个中断就意味着,当你开启DMA多通道转换后,全部转换完一遍后会自动调用这个中断的回调函数,
也就是它:
wake void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);
三。代码
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "gpio.h"
uint16_t adcBuf[2]; //存储2个adc的值
//回调处理
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
//获取
uint16_t adcValue1 = adcBuf[0];
uint16_t adcValue2 = adcBuf[1];
__NOP();
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
HAL_ADCEx_Calibration_Start(&hadc1); //启动adc校准,修正ADC的非线性误差
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adcBuf, 2); //启动dma转换
while (1)
{
}
}
四。演示效果
看下2个ADC的值,黄色选中的部分为哪个通道在转换
感谢您的支持,写的文章如对您有所帮助,开源不易,请您打赏,谢谢啦~