stm32ADC的DMA模式

本文详细介绍了STM32微控制器中ADC模块的配置过程,包括GPIO配置、时钟配置、DMA初始化及ADC初始化等关键步骤。通过具体代码示例,展示了如何设置ADC通道、采样时间、转换模式等参数,以及如何使用DMA进行数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//变量定义

__IO uint16_t ADCConvertedValue[10];

//ADC 外设的数据寄存器

#define ADC1_DR_Address    ((uint32_t)0x4001244C)

//ADC_DR(ADC规则数据寄存器),偏移量=0x4c  ADC1(0x40012400-0x400127ff)

//ADC1_GPIO配置

void ADC1_GPIO_Configuration(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure PC.01 (ADC Channel11) as analog input -------------------------*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;        

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //adc模式必须是模拟输入

  GPIO_Init(GPIOC, &GPIO_InitStructure);//执行上面的操作

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;        

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //adc模式必须是模拟输入

  GPIO_Init(GPIOA, &GPIO_InitStructure);//执行上面的操作

  //注意,内部温度对应 16通道,无引脚,只需开启adc时钟即可。

  //内部参考电压,对应17 通道。无引脚。只需开启时钟

}

//============================================================================================

//外设ADC,DMA时钟开启

 void ADC1_DMA_RCC_Configuration(void)

{

  /* Enable peripheral clocks ------------------------------------------------*/

  /* Enable DMA1 clock */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* Enable ADC1 and GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC| RCC_APB2Periph_GPIOA, ENABLE);

}

//===============================================================================================

//ADC1  DMA 配置

void ADC1_DMA_Init(void)

{

ADC_InitTypeDef ADC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

/* DMA1 channel1 configuration ----------------------------------------------*/

  DMA_DeInit(DMA1_Channel1); //选择DMA的通道1

  //设定从ADC外设的数据寄存器(ADC1_DR_Address)转移到内存(ADCConcertedValue)

  //每次传输大小16位,使用DMA循环传输模式

  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue;//数据缓冲区的地址

  //外设为数据源

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  //数据缓冲区,大小2半字

  DMA_InitStructure.DMA_BufferSize = 10;

  // 外设地址固定

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  //内存地址增加,多组adc时,使能,数据传输时,内存增加

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  //半字

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

  //DMA循环传输

  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); 

  /* Enable DMA1 channel1 */

  DMA_Cmd(DMA1_Channel1, ENABLE); 

  /* ADC1 configuration ------------------------------------------------------*/

  //ADC独立模式         相对于双重模式

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

  //扫描模式用于多通道采集

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  //开启连续转换模式   当转换完本组(可能是一个)继续重新开始执行

  //相对于单次模式:转换一次后就结束

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  //不使用外部触发转换

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  //采集数据右对齐

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  //转换组的通道数目

  ADC_InitStructure.ADC_NbrOfChannel =10;

  //执行

  ADC_Init(ADC1, &ADC_InitStructure); 

  //配置ADC时钟,为PCLK2的8分频,即9Hz

  RCC_ADCCLKConfig(RCC_PCLK2_Div8);

  /* ADC1 regular channel11 configuration */

  //配置ADC1的通道11为55.5个采样周期

  //默认组,adc1 ,通道11,排序为1,55.5周期

  //ADC1,ch17,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_17,1, ADC_SampleTime_239Cycles5);

  //ADC1,ch16,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_16,2, ADC_SampleTime_239Cycles5);

  //ADC1,ch4,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_4,3, ADC_SampleTime_239Cycles5);

  //ADC1,ch5,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_5,4, ADC_SampleTime_239Cycles5);

  //ADC1,ch6,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_6,5, ADC_SampleTime_239Cycles5);

  //ADC1,ch7,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_7,6, ADC_SampleTime_239Cycles5);

  //ADC1,ch10,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_10,7, ADC_SampleTime_239Cycles5);

  //ADC1,ch11,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_11,8, ADC_SampleTime_239Cycles5);

  //ADC1,ch12,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_12,9, ADC_SampleTime_239Cycles5);

  //ADC1,ch13,序号1,55.5.。。

  ADC_RegularChannelConfig(ADC1, ADC_Channel_13,10, ADC_SampleTime_239Cycles5);

  //----------------------使能温度传感器----------------------------

  ADC_TempSensorVrefintCmd(ENABLE);

  /* Enable ADC1 DMA */

  //使能ADC_DMA

  ADC_DMACmd(ADC1, ENABLE); 

  /* Enable ADC1 */

  //使能ADC

  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibration register */

  //使能ADC1的复位校准寄存器 

  ADC_ResetCalibration(ADC1);

  /* Check the end of ADC1 reset calibration register */

  //等待校准完成

  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibration */

  //使能ADC1的开始校准寄存器

  ADC_StartCalibration(ADC1);

  /* Check the end of ADC1 calibration */

  //等待完成

  while(ADC_GetCalibrationStatus(ADC1));    

  /* Start ADC1 Software Conversion */

  //使用软件触发,由于没有采用外部触发

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

 

### STM32 ADC 配置 DMA 模式的教程 #### 一、硬件准备与初始化设置 为了确保ADCDMA能正常工作,在开始编写代码之前,需先完成必要的硬件连接并配置好相应的GPIO引脚。这一步骤通常涉及将待测电压源接入指定的模拟输入通道,并确认这些通道对应的物理引脚已被正确定义为模拟功能。 #### 二、库函数的选择与安装 推荐使用官方提供的HAL (Hardware Abstraction Layer) 库来简化编程过程。该库提供了丰富的API接口用于操作各种外设资源,其中包括对ADC以及DMA的支持[^1]。 #### 三、具体实现步骤 ##### 1. 初始化ADC模块 创建一个新的工程文件后,在`main.c`或其他适当位置调用如下语句以启动ADC: ```c /* 定义全局变量 */ extern ADC_HandleTypeDef hadc1; // 在主程序入口处或某个特定事件触发时执行下面的操作 if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)aBuffer, BUFFER_SIZE)!= HAL_OK){ // 错误处理逻辑... } ``` 上述代码片段展示了如何利用HAL库中的`HAL_ADC_Start_DMA()`函数开启一次性的DMA传输请求。这里传入的第一个参数是指向已实例化的ADC句柄结构体;第二个参数是要存储采样结果的目标缓冲区地址;第三个则是预期读取的数据量大小。 ##### 2. 设置DMA控制器属性 为了让DMA能够自动搬运来自ADC的数据至内存空间内,还需进一步设定其自身的特性。这部分可通过修改CubeMX生成项目的默认配置或是手动编辑相关寄存器位场达成目的。以下是部分关键选项说明: - **方向**:应选为“从外设到存储器”,即Peripheral to Memory; - **循环模式**:启用此开关可让DMA在每次完成一轮完整的数据搬移之后重新回到起始状态继续新一轮的任务; - **优先级等级**:根据实际应用场景调整合适的级别,一般情况下保持较低即可满足需求。 ##### 3. 编写回调函数响应中断事件 当DMA完成了预定数量的数据转移动作后会自动生成一个结束标志位,并由此引发相应类型的异常服务例程ISR(Interrupt Service Routine),此时可以在其中加入用户定义的动作比如更新显示界面或者保存记录等。 ```c void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){ /* 用户可以在此添加自己的业务逻辑 */ } void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma){ if (__HAL_DMA_GET_FLAG(hdma,DMA_FLAG_TCIF0)){ __HAL_DMA_CLEAR_FLAG(hdma,DMA_FLAG_TCIF0); HAL_ADC_ConvCpltCallback((ADC_HandleTypeDef *)hdma->Parent); } } ``` 以上就是关于STM32平台上基于DMA技术实施高速连续AD转换的大致流程介绍。值得注意的是,由于不同版本之间可能存在细微差异,因此建议开发者参照最新发布的文档资料来进行最终调试优化工作[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值