STM32的HAL库开发系列 - ADC寄存器
ADC_DR - 规则数据寄存器
ADC规则组数据寄存器ADC_DR只有一个,是一个32位的寄存器,只有低16位有效并且只是用于独立模式存放转换完成数据。因为ADC的最大精度是12位,ADC_DR是16位有效,这样允许ADC存放数据时候选择左对齐或者右对齐,具体是以哪一种方式存放,由ADC_CR2的11位ALIGN设置。假如设置ADC精度为12位,如果设置数据为左对齐,那AD转换完成数据存放在ADC_DR寄存器的[4:15]位内;如果为右对齐,则存放在ADC_DR寄存器的[0:11]位内。
规则通道可以有16个这么多,可规则数据寄存器只有一个,如果使用多通道转换,那转换的数据就全部都挤在了DR里面,前一个时间点转换的通道数据,就会被下一个时间点的另外一个通道转换的数据覆盖掉,所以当通道转换完成后就应该把数据取走,或者开启DMA模式,把数据传输到内存里面,不然就会造成数据的覆盖。最常用的做法就是开启DMA传输。
如果没有使用DMA传输,我们一般都需要使用ADC状态寄存器ADC_SR获取当前ADC转换的进度状态,进而进行程序控制。
ADC_CDR - 通用规则数据寄存器
规则数据寄存器ADC_DR是仅适用于独立模式的,而通用规则数据寄存器ADC_CDR是适用于双重和三重模式的。独立模式就是仅仅适用三个ADC的其中一个,双重模式就是同时使用ADC1和ADC2,而三重模式就是三个ADC同时使用。在双重或者三重模式下一般需要配合DMA数据传输使用。
ADC_HandleTypeDef结构体定义在stm32f4xx_adc.h文件内,具体定义如下:
typedef struct {
ADC_TypeDef *Instance; /*寄存器基地址指针*/
ADC_InitTypeDef Init; /*ADC初始化参数结构体*/
__IO uint32_t NbrOfCurrentConversionRank;//正在转换序列的ADC数目
DMA_HandleTypeDef *DMA_Handle; /* DMA处理程序指针 */
HAL_LockTypeDef Lock; /*ADC锁定对象 */
__IO uint32_t State; /*ADC通信状态*/
__IO uint32_t ErrorCode; /*ADC错误码 */
} ADC_HandleTypeDef;
- *Instance:ADC寄存器基地址指针,所有参数都是指定基地址后才能正确写入寄存器。
- Init:ADC初始化结构体,下面会详细讲解每一个成员。
- *DMA_Handle:DMA处理程序指针。
- Lock:ADC锁定对象。
- State:ADC转换状态。
- ErrorCode:ADC错误码。
HAL库函数对每个外设都建立了一个初始化结构体xxx _HandleTypeDef (xxx为外设名称), 结构体成员用于设置外设工作参数,并由HAL库函数HAL_xxx_Init()调用这些设定参数进入设置外设相应的寄存器,达到配置外设工作环境的目的。
结构体xxx__HandleTypeDef和库函数HAL_xxx_Init配合使用是HAL库精髓所在, 理解了结构体xxx_HandleTypeDef每个成员意义基本上就可以对该外设运用自如了。 结构体xxx_HandleTypeDef定义在stm32f4xx_hal_xxx.h文件中,库函数HAL_xxx_Init定义在stm32f4xx_hal_xxx.c文件中, 编程时我们可以结合这两个文件内注释使用。
ADC工作模式配置参考举例:
static void Rheostat_ADC_Mode_Config(void)
{
// 开启ADC时钟
RHEOSTAT_ADC_CLK_ENABLE();
// -------------------ADC Init 结构体 参数 初始化-----------------------
// ADC1
ADC_Handle.Instance = RHEOSTAT_ADC;
// 时钟为fpclk 4分频
ADC_Handle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
// ADC 分辨率
ADC_Handle.Init.Resolution = ADC_RESOLUTION_12B;
// 禁止扫描模式,多通道采集才需要
ADC_Handle.Init.ScanConvMode = DISABLE;
// 连续转换
ADC_Handle.Init.ContinuousConvMode = ENABLE;
// 非连续转换
ADC_Handle.Init.DiscontinuousConvMode = DISABLE;
// 非连续转换个数
ADC_Handle.Init.NbrOfDiscConversion = 0;
//禁止外部边沿触发
ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
//使用软件触发,外部触发不用配置,注释掉即可
//ADC_Handle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
//数据右对齐
ADC_Handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
//转换通道 1个
ADC_Handle.Init.NbrOfConversion = 1;
//使能连续转换请求
ADC_Handle.Init.DMAContinuousRequests = ENABLE;
//转换完成标志
ADC_Handle.Init.EOCSelection = DISABLE;
// 初始化ADC
HAL_ADC_Init(&ADC_Handle);
//-------------------------------------------------------------------
ADC_Config.Channel = RHEOSTAT_ADC_CHANNEL;
ADC_Config.Rank = 1;
// 采样时间间隔
ADC_Config.SamplingTime = ADC_SAMPLETIME_56CYCLES;
ADC_Config.Offset = 0;
// 配置 ADC 通道转换顺序为1,第一个转换,采样时间为3个时钟周期
HAL_ADC_ConfigChannel(&ADC_Handle, &ADC_Config);
HAL_ADC_Start_IT(&ADC_Handle);
}
参考和引用:STM32F4xx参考手册、STM32F4xx规格书、野火开源项目、库帮助文档