1、ADC是什么
ADC全称Analog to Digital Converter:模拟数字转换器。拥有12位测量范围,可以通过STM32上GPIO端口的输入模式实现对外部传感器的测量,测量范围为0-3.3V(0-4096)
2、ADC介绍
1、ADC总共有以下寄存器
(1) ADC状态寄存器/Status register ADC_SR
(2)ADC控制寄存器1/Control registier 1 ADC_CR1
(3)ADC控制寄存器2/Control register 2 ADC_CR2
(4)ADC采样时间寄存器1/Sample Time rigister 1 ADC_SMPR1
(5)ADC采样时间寄存器2/Sample Time rigister 2 ADC_SMPR2
(6)ADC注入通道数据偏移寄存器/Injected Channel Data Offset register ADC_JOFRx
(7)ADC看门狗高阈值寄存器/Watching High Threshould register ADC_HTR
(8)ADC看门狗低阈值寄存器/Watching Low Threshould register ADC_LTR
(9)ADC规则序列寄存器1/Regular sequence register ADC_SQR1
(10)ADC规则序列寄存器2/Regular Sequence register ADC_SQR2
(11)ADC规则序列寄存器3/Regular Sequence register ADC_SQR3
(12)ADC注入序列寄存器/Injected Sequence register ADC_JSQR
(13)ADC注入数据寄存器x/Injecter Data registerx ADC_JDRx
(14)ADC规则数据寄存器/Regular Data register ADC_DR
ADC初始化结构体
typedef struct
{
uint32_t ADC_Mode;//工作模式
FunctionalState ADC_ScanConvMode;//扫描(多通道)或者单次(单通道)模式使能
FunctionalState ADC_ContinuousConvMode;//单次转换或者连续转换模式
uint32_t ADC_ExternalTrigConv;//转换触发信号选择
uint32_t ADC_DataAlign;//数据寄存器对齐模式
uint8_t ADC_NbrOfChannel;//采集通道数
}ADC_InitTypeDef;
ADC_Mode:配置ADC_CR1寄存器的位19:16(DUALMOD)
可以选择:
0000:独立模式
0001:混合的同步规则+注入同步模式
0010:混合的同步规则+交替触发模式
0011:混合同步注入+快速交叉模式
0100:混合同步注入+慢速交叉模式
0101:注入同步模式
0110:规则同步模式
0111:快速交叉模式
1000:慢速交叉模式
1001:交替触发模式
ADC_ScanConvMode:配置ADC_CR1寄存器的位8(SCAN),扫描模式为单通道扫描模式或者多通道扫描模式
ADC_ContinuousConvMode:配置ADC_CR2的位1(CONT),ADC转换模式为连续转换(1)或单一模式(0)
ADC_ExternalTrigConv:配置ADC_CR2的位19:17(EXTSEL),选择外部事件用于启动规则通道转换
ADC1和ADC2的触发配置如下
000:定时器1的CC1事件 100:定时器3的TRGO事件
001:定时器1的CC2事件 101:定时器4的CC4事件
110: EXTI线11/ TIM8_TRGO事件,仅大容量产
品具有TIM8_TRGO功能
010:定时器1的CC3事件
011:定时器2的CC2事件 111: SWSTART
ADC3的触发配置如下
000:定时器3的CC1事件 100:定时器8的TRGO事件
001:定时器2的CC3事件 101:定时器5的CC1事件
010:定时器1的CC3事件 110:定时器5的CC3事件
011:定时器8的CC1事件 111: SWSTART
ADC_DataAlign:配置ADC_CR2的位11(ALIGN),数据寄存器的对齐模式,左对齐(1)或右对齐(0)
ADC_NbrOfChannel:配置ADC_SQR1的位23:20(L),规则通道序列长度0-16个
3、程序设计思路
初始化配置
- 开时钟GPIO和ADC
- 配置ADC所使用的的GPIO端口:配置为模拟输入(GPIO_Mode_AIN)
- 配置ADC初始化结构体
- ADC使能,ADC_Cmd
- ADC使能复位校准等待复位完成后
- 开启AD校准等待校准结束
获取ADC的测量值
- 设置指定ADC的规则通道 ADC_RegularChannelConfig()
- 使能指定通道的软件转换启动
- 等待ADC测量中断,读取ADC_DR寄存器的数据
4、ADC数据转换方法
STM32中ADC为12位,所以ADC的数据计数阈值为0-4096,电压阈值为0-3.3V
3.3/4096 = 0.0008056641
即ADC的测量可以精确到小数点后三位,对于一般的使用,精度已经够用了。
5、ADC量程扩展办法
如果直接连接GPIO端口的话,输入电压最高不可以超过3.3V,那么如果想测量超过3.3V的电压该怎么办呢?
我们可以通过增加电阻的方法,按GPIO的端口电压和测量电压的比例增加电阻,保证输入GPIO的电压最大值恒为3.3V,然后通过一定的计算即可达到测量更高电压的办法
6、代码示例
本次使用ADC1通道5,单通道无DMA模式
/**
* 功能:ADC1_IN5(PA5)初始化
* 入口参数:无
* 返回值:无
*/
void ADC_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1 ,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2独立工作模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//单/多通道使能
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//转换触发方式:软件控制
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//数据对齐:右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1;//顺序进行规则通道转换的ADC通道数目:1
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
}
/**
* 功能:获得ADC值
* 入口参数:ch:通道值 0~17(若不是ADC1,则为0~15)
* 返回值:ADC的值
*/
u16 Get_Adc(u8 ch)
{
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}