当前位置: 首页 > java >正文

stm32 --- ADC,DMA,多路,单次/连续转换(标准外设库)

今天回答一个朋友的问题吧,ADC如何使用DMA采集多通道模拟电压。

 

一. 写在前面

这个问题其实之前写过一些相关文章,原理我之前也有相关描述。如果想要彻底弄明白其原理,建议阅读《参考手册》、结合标准外设库来理解。

 

现在很多人习惯使用STM32CubeMX来直接生成初始化代码,如果没有掌握STM32CubeMX、HAL库,使用STM32CubeMX生成的代码,或许就不能满足你的应用。

 

同时,STM32CubeMX生成的代码,想要根据代码进一步了解其原理,其实很难

 

ADC转换一些基础原理,我这里就不过多描述了,请直接看下面标准外设库源码、及后面给的注释。

 

下面写2点:ADC软件单次触发转换,和连续转换。

 

 

二. ADC,DMA,单次触发转换

这里以ADC,使用DMA,通过软件单次触发转换为例。主要需注意几个相关参数即可。

 

1.GPIO配置

 

2.DMA配置

 

3.ADC配置

 

4.ADC单次触发转换

 

5.源代码

/* 静态变量 ------------------------------------------------------------------*/
static volatile uint16_t sADC_Buf[3];/************************************************
函数名称 : ADC_GPIO_Configuration
功    能 : ADC引脚配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_GPIO_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* 使能时钟 */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                      //模拟输入GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(GPIOA, &GPIO_InitStructure);
}/************************************************
函数名称 : ADC_DMA_Configuration
功    能 : ADC DMA配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_DMA_Configuration(void)
{DMA_InitTypeDef DMA_InitStructure;/* 使能时钟 */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);/* 配置DMA */DMA_InitStructure.DMA_Channel = DMA_Channel_0;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC1->DR));//外设地址DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&sADC_Buf[0]);  //内存地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;            //传输方向:外设 -> 内存DMA_InitStructure.DMA_BufferSize = 3;                              //传输长度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_Normal;                      //正常模式DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;              //优先级DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;DMA_Init(DMA2_Stream0, &DMA_InitStructure);
}/************************************************
函数名称 : ADC_Configuration
功    能 : ADC参数配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_Configuration(void)
{ADC_InitTypeDef       ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;/* 使能时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);/* ADC配置 */ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;ADC_CommonInit(&ADC_CommonInitStructure);ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;ADC_InitStructure.ADC_ScanConvMode = ENABLE;                       //浏览模式(多通道)ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                //连续转化模式ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;             //数据右对齐ADC_InitStructure.ADC_NbrOfConversion = 3;                         //转换通道数ADC_Init(ADC1, &ADC_InitStructure);/* 通道配置 */ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_3Cycles);ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_3Cycles);ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);ADC_DMACmd(ADC1, ENABLE);                                          //使能ADC的DMA功能ADC_Cmd(ADC1, ENABLE);                                             //使能ADC
}/************************************************
函数名称 : ADC_Initializes
功    能 : ADC初始化
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_Initializes(void)
{ADC_GPIO_Configuration();ADC_DMA_Configuration();ADC_Configuration();
}/************************************************
函数名称 : ADC_Get
功    能 : 转换
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_Get(void)
{DMA_Cmd(DMA2_Stream0, DISABLE);                                    //关闭DMA//内存地址DMA_MemoryTargetConfig(DMA2_Stream0, (uint32_t)sADC_Buf, DMA_Memory_0);DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0);                       //清除标志位DMA_Cmd(DMA2_Stream0, ENABLE);                                     //使能DMAADC_SoftwareStartConv(ADC1);                                       //启动转换while(RESET == DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TCIF0));   //等待转换完成//得到3条通道转换结果:sADC_Buf//进行相关换算,处理...
}

 

提示:以上源代码只为方便学习和理解,请结合实际应用修改、或增减代码。

 

 

三. ADC,DMA,连续转换

我这里写的连续,是ADC连续转换,同时,DMA循环存储。大部分配置和上面差不多,这种方式也用的比较多,写给大家。

 

1.DMA配置

 

2.ADC配置

 

3.源代码

 

/* 静态变量 ------------------------------------------------------------------*/
static volatile uint16_t sADC_Buf[3];/************************************************
函数名称 : ADC_GPIO_Configuration
功    能 : ADC引脚配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_GPIO_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* 使能时钟 */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                      //模拟输入GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(GPIOA, &GPIO_InitStructure);
}/************************************************
函数名称 : ADC_DMA_Configuration
功    能 : ADC DMA配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_DMA_Configuration(void)
{DMA_InitTypeDef DMA_InitStructure;/* 使能时钟 */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);/* 配置DMA */DMA_InitStructure.DMA_Channel = DMA_Channel_0;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC1->DR));//外设地址DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&sADC_Buf[0]);  //内存地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;            //传输方向:外设 -> 内存DMA_InitStructure.DMA_BufferSize = 3;                              //传输长度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_Medium;              //优先级DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;DMA_Init(DMA2_Stream0, &DMA_InitStructure);
}/************************************************
函数名称 : ADC_Configuration
功    能 : ADC参数配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_Configuration(void)
{ADC_InitTypeDef       ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;/* 使能时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);/* ADC配置 */ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;ADC_CommonInit(&ADC_CommonInitStructure);ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;ADC_InitStructure.ADC_ScanConvMode = ENABLE;                       //浏览模式(多通道)ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                 //连续转化模式ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;             //数据右对齐ADC_InitStructure.ADC_NbrOfConversion = 3;                         //转换通道数ADC_Init(ADC1, &ADC_InitStructure);/* 通道配置 */ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_3Cycles);ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_3Cycles);ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);ADC_DMACmd(ADC1, ENABLE);                                          //使能ADC的DMA功能ADC_Cmd(ADC1, ENABLE);                                             //使能ADCADC_SoftwareStartConv(ADC1);                                       //启动转换
}/************************************************
函数名称 : ADC_Initializes
功    能 : ADC初始化
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_Initializes(void)
{ADC_GPIO_Configuration();ADC_DMA_Configuration();ADC_Configuration();
}/************************************************
函数名称 : ADC_Get
功    能 : 转换
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void ADC_Get(void)
{//得到3条通道转换结果:sADC_Buf//进行相关换算,处理...
}

 

这种方式比较简单,直接去读取转换结果就行。实际应用需要滤波,求平均之类的操作。

http://www.xdnf.cn/news/10860.html

相关文章:

  • 大学生网页设计制作作业实例代码 (全网最全,建议收藏) HTML+CSS+JS (1)
  • txplatform.exe分析及病毒解决
  • 让 Google 搜索到自己的博客
  • snake 模型
  • 电脑知识:DOS命令使用
  • 【网络安全】简单的免杀方法(基本知识)
  • Xilisoft Video Converter Ultimate 6.05多语言版(含简中)绿色版
  • 多种解决:“Word无法启动转换器mswrd632.wpc”方法
  • Ghost 使用详解
  • 圣天诺(LDK)加密锁 云授权,不用使用硬件的加密锁(加密狗)
  • SP业务新人启蒙
  • android 动态向Gallery中添加图片及倒影3D效果
  • Jenkins环境配置篇-更换插件源
  • GFS - The Google File System
  • 各类免费经典网址
  • 【JavaWeb】SpringBoot原理
  • 【深入 LangChain 的 Model I/O】提示设计、模型调用与输出解析全解析
  • 建设指南 | Cloud Apps + AI Apps端到端智能应用开发平台
  • wsl===windows下安装Linux系统
  • 检索增强的大模型工具调用:语义驱动的精准API选择技术
  • 《Pytorch深度学习实践》ch5-Logistic回归
  • 百万级临床试验数据库TrialPanorama发布!AI助力新药研发与临床评价迎来新基石
  • Rhino插件大全下载指南:解锁犀牛潜能,提升设计效率
  • C++11:unique_ptr的基本用法、使用场景和最佳使用指南
  • 利用lightgbm预测adult数据集
  • 支持TypeScript并打包为ESM/CommonJS/UMD三种格式的脚手架项目
  • MYSQL索引详解及索引优化、分析
  • Cyber Weekly #58
  • 低成本单节电池风扇解决方案WD8001
  • switch-while day6