stm32f103c8t6adc多通道dma hal库
时间: 2025-04-29 07:51:23 浏览: 34
### STM32F103C8T6 ADC 多通道 DMA HAL 库实现
对于STM32F103C8T6,在使用ADC进行多通道采样并利用DMA传输数据时,可以借助HAL库简化配置过程。通过初始化结构体`ADC_HandleTypeDef`来设置ADC参数,并启用DMA模式以确保每次转换结束时自动将结果转移到指定缓冲区。
#### 初始化ADC与DMA
为了使能多个通道的同时采样而不丢失任何样本值,需先定义一个足够大小的数组用于暂存各路输入信号的结果:
```c
uint16_t aADCxConvertedData[NUMBER_OF_CHANNELS];
```
接着创建两个句柄变量分别对应于ADC外设和DMA流/通道对象:
```c
ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;
```
随后按照如下方式完成硬件资源分配及属性设定[^1]:
- 配置ADC工作模式为连续扫描序列下的规则组;
- 设置待测物理量对应的引脚作为模拟输入端口加入到该序列之中;
- 开启循环请求功能使得DMA能够在全部项目处理完毕之后重新启动新一轮读取操作直至程序显式终止之;
具体代码片段展示如何基于上述原则构建起完整的初始化流程:
```c
static void MX_ADC_Init(void)
{
__HAL_RCC_ADC1_CLK_ENABLE(); // Enable ADC clock
hadc.Instance = ADC1; // Select the ADC instance to be used.
/* Configure the global features of the ADC (Clock prescaler, Resolution,
Data Alignment and number of conversion). */
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.ScanConvMode = ENABLE; // Enable scan mode for multiple channels
hadc.Init.ContinuousConvMode = ENABLE; // Continuous conversion mode enabled
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.NbrOfConversion = NUMBER_OF_CHANNELS;
hadc.Init.DMAContinuousRequests = ENABLE; // Enable continuous requests for DMA transfers
hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if(HAL_ADC_Init(&hadc)!= HAL_OK){
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = CHANNEL_TO_BE_CONFIGURED; // Replace with actual channel configuration
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if(HAL_ADC_ConfigChannel(&hadc,&sConfig) != HAL_OK){
Error_Handler();
}
}
```
针对DMA部分,则要特别注意其优先级、方向以及回调函数的设计以便及时响应中断事件更新全局状态标志位或者触发其他必要的动作逻辑:
```c
static void MX_DMA_Init(void)
{
/* Init DMAs low Level Driver */
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_adc.Instance = DMA1_Channel1;
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc.Init.Mode = DMA_CIRCULAR;
hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
hdma_adc.XferCpltCallback = TransferComplete_CallBack;
hdma_adc.XferErrorCallback = TransferError_CallBack;
if(HAL_DMA_Init(&hdma_adc) != HAL_OK){
Error_Handler();
}
__HAL_LINKDMA(&hadc,DMA_Handle,hdma_adc);
}
void TransferComplete_CallBack(DMA_HandleTypeDef *hdma)
{
// Handle transfer complete event here
}
void TransferError_CallBack(DMA_HandleTypeDef *hdma)
{
// Handle error events here
}
```
最后一步就是调用`HAL_ADC_Start_DMA()`开启整个链路的工作周期,此时只要保持系统电源供给正常即会持续不断地获取来自各个传感器接口处传入的新鲜测量数值直到人为干预停止为止。
阅读全文
相关推荐


















