当前位置:网站首页>STM32单片机ADC规则组多通道转换-DMA模式
STM32单片机ADC规则组多通道转换-DMA模式
2022-04-23 03:56:00 【Chenxr32】
模数转换器(Analog To Digital Converter)简称ADC(也可以写成A/D),是指将连续变化的模拟信号转换为离散的数字信号的器件。
直接存储器存取技术(Direct Memory Access)简称DMA。DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省CPU的资源可以做其他操作。DMA传输的本质是地址到地址的操作,可以把DMA理解为CPU的“秘书”。
ADC的参考电压是ADC的一个重要指标。STM32芯片只有100及以上引脚的型号才具备外部参考电压引脚VREF+和VREF-;64及小于64脚的型号,参考电压引脚在芯片内部默认连接到ADC的电源引脚VDDA和VSSA。
|
图 1 ADC电源和基准电源电路 |
由于ADC规则组多通道转换时,只能读取到最后一个通道的数据,因此ADC的多通道转换天生适合DMA模式,当每个通达转换完毕后,发送DMA请求,通过DMA直接传输到设定的内存缓存区中,从而解决了ADC多通道转换数据被覆盖的问题,同时CPU不需要频繁读取ADC的数据,大幅提高执行效率。
通过查阅STM32F1的参考手册,我们可以知道ADC1的DMA传输通道映射到了DMA1的Channel1。ADC1可由TIM3_TRGO事件触发转换。本文通过TIM3的更新事件触发ADC规则组4路通道转换。实际项目中,我们使用这4路ADC读取四个霍尔角度传感器的输出电压进而计算机械臂的角度,采用外部触发ADC规则组转换可以避免因ADC循环转换模式造成的资源浪费。接下来上代码。
void Timer_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period=1000-1;
TIM_TimeBaseStructure.TIM_Prescaler=72-1;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_Cmd(TIM3, ENABLE);
TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Update);//设置更新事件作为触发输出
}
void ADC_DMA_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72M/6=12M
//init GPIO
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//init DMA
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr=(unsigned int)&(ADC1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr=(unsigned int)&ADCBuffer[0];
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize=4;
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority=DMA_Priority_High;
DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel1,ENABLE);
//init ADC1
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode=ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T3_TRGO;//设置外部信号TIM3_TRGO出发
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel=4;
ADC_Init(ADC1,&ADC_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6,1,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7,2,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_8,3,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_9,4,ADC_SampleTime_239Cycles5);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
//calibrate ADC1
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
//enable ADC1 external trigger
ADC_ExternalTrigConvCmd(ADC1,ENABLE);
}
在main函数中调用初始化函,TIM3、ADC、DMA配置好后,TIM3将每1ms触发一次ADC规则组通道转换,转换的结果将有DMA转移至预先定义的缓冲区ADCBuffer,只要及时读取ADCBuffer中的数据便可得到各ADC通道转换的数值。如果读取数据不及时,容易出现读取数据被覆盖的现象,为此可以将ADCBuffer及DMA通道缓存(DMA_BufferSize)设置成被测数据的2倍大小,当第一次规则组4通道依次转换完毕后,DMA将数据依次传输到缓冲区的前半区,同时设置DMA传输过半标志位,此时可以读取当前4通道转换的数据。同时规则组继续转换,当第二次4个通道依次转换完毕时,转换数据被存储到缓冲区的后半区,同时设置DMA传输完成标志位,此时可以读取第二次转换的数据。
版权声明
本文为[Chenxr32]所创,转载请带上原文链接,感谢
https://blog.csdn.net/QDchenxr/article/details/83959733
边栏推荐
- Let matlab2018b support the mex configuration of vs2019
- UDP protocol and TCP protocol
- 网络原理 | TCP/IP中的连接管理机制 重要协议与核心机制
- Use the thread factory to set the thread name in the thread pool
- [latex] differences in the way scores are written
- (valid for personal testing) compilation guide of paddedetection on Jetson
- Concepts of objects and classes
- Second kill all interval related problems
- The difference between lists, tuples, dictionaries and collections
- 列表、元组、字典和集合的区别
猜你喜欢

Software testing process

ROS series (IV): ROS communication mechanism series (2): Service Communication

Xshell、Xftp连接新创建的Unbutu系统虚拟机全流程

VSCode配置之Matlab极简配置

What if win10 doesn't have a local group policy?

MySQL is completely uninstalled and MySQL service is cleaned up

Add the compiled and installed Mysql to the path environment variable

Hard core chip removal

The whole process of connecting the newly created unbutu system virtual machine with xshell and xftp

使用大华设备开发行AI人流量统计出现时间不正确的原因分析
随机推荐
Who will answer the question?
将编译安装的mysql加入PATH环境变量
VS Studio 修改C语言scanf等报错
[AI vision · quick review of today's sound acoustic papers issue 1] Thu, 14 APR 2022
ROS series (IV): ROS communication mechanism series (1): topic communication
Xshell、Xftp连接新创建的Unbutu系统虚拟机全流程
Basic introduction to spot gold
MATLAB lit plusieurs diagrammes fig et les combine en un seul diagramme (sous forme de sous - Diagramme)
使用大华设备开发行AI人流量统计出现时间不正确的原因分析
A function second kill 2sum 3sum 4sum problem
Seekbar custom style details
Process seven state transition diagram
秒杀所有区间相关问题
QtSpim手册-中文翻译
Operating skills of spot gold_ Wave estimation curve
[latex] formula group
抽象类、接口、常用关键字
ERROR: Could not find a version that satisfies the requirement win32gui
ROS series (II): ROS quick experience, taking HelloWorld program as an example
[AI vision · quick review of NLP natural language processing papers today, issue 28] wed, 1 Dec 2021
