ADC初始化,以HAL库为例:
MX_ADC1_Init(); //cube自动生成的初始化结构,会调用HAL_ADC_MspInit()初始化底层寄存器。
HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig) 设置通道参数:
typedef struct
{
uint32_t Channel;
uint32_t Rank;
uint32_t SamplingTime;
}ADC_ChannelConfTypeDef;
校准:
HAL_ADCEx_Calibration_Start(&hadc1);
启动转换:
HAL_ADC_Start() // 轮询模式
HAL_ADC_Start_IT(), // 中断模式
HAL_ADC_Start_DMA() // DMA模式
在HAL库中,对应方式的接收就是将Start改为Stop。
获取数据:
HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
DMA方式需要一个32位pData数组来接收,而不是16位,轮询方式:
HAL_ADC_Start(&hadc1);
while(__HAL_ADC_GET_FLAG(&hadc1,ADC_FLAG_EOC)==RESET);
uint16_t adc= HAL_ADC_GetValue(&hadc1);
HAL_ADC_GetValue在单通道转换没有问题,多通道时只会返回rank等级最高的数据,所以无法简单获取多个通道的AD值,常见的多通道方式可以是每次采集完成都通过HAL_ADC_ConfigChannel(&hadc1, &sConfig)重新选择通道,这个过程可以是在轮询中完成,也可以是在AD中断函数中中完成。但在所有的实现方式中,都应该在初始化ADC的时候,只选择单通道:
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
{
uint32_t DataAlign; /*!<to right (MSB on register bit 11) or to left (MSB on register bit 15)
uint32_t ScanConvMode; /*!< one channel converted, the one defined in rank 1. 多通道下需要使能
uint32_t ContinuousConvMode; /*!<一次触发,组内多通道连续转换
uint32_t NbrOfConversion; /*!< Min_Data = 1 and Max_Data = 16. */ 通道数
uint32_t DiscontinuousConvMode; /*!< This parameter can be set to ENABLE or DISABLE. */ 一次触发,大组内的小组转换一次
uint32_t NbrOfDiscConversion; /*!< Min_Data = 1 and Max_Data = 8. */ 大组内多少通道分为一个小组
uint32_t ExternalTrigConv; 触发方式
}ADC_InitTypeDef;
Discontinuous mode模式(DISCEN=1)下,需要硬件或软件的触发事件去启动定义在一个序列中的每次转换。DISCEN=0时,一个硬件或软件的触发事件就可以启动定义在一个序列中的所有转换,任何触发事件都会重新开始完整的序列转换。
在STM32中,启动的方式:
• Setting the ADSTART bit in the ADC_CR register
• Hardware trigger event
触发方式:
ADC_ExternalTrigConv_T1_CC1、
ADC_ExternalTrigConv_T1_CC2、
ADC_ExternalTrigConv_T1_CC3、
ADC_ExternalTrigConv_T2_CC2、
ADC_ExternalTrigConv_T3_TRGO、
ADC_ExternalTrigConv_T4_CC4、
ADC_ExternalTrigConv_EXT_IT11、
软件触发:ADC_SoftwareStartConvCmd(ADC1, ENABLE);
注入通道,选择EXTI_IT15和TIM8_CC4作为外部触发事件
规则通道,选择EXTI_IT11和TIM8_TRGO作为外部触发事件