STM32 ADC
ADC介绍
逐次逼近型ADC芯片ADC0809
通过地址锁存器和译码器电路实现对通道的选择,每一次转换通道选择开关只能一个通道的信号
使用逐次逼近的方法来测量电压。
电压比较器可以判断两个输入信号电压的大小关系,输出一个高低电平指示谁大谁小
两个输入端一个是待测电压另一个是DAC的电压输出端
给DAC一个数据它就可以输出数据对应的电压,若DAC输出的电压比较大就调小DAC数据,若DAC输出电压比较小就增大DAC数据,直到DAC输出电压和外部通道输入的电压近似相等,这样DAC输入的数据就是外部电压的编码数据了,这就是DAC的实现原理,这个电压调节的过程就是逐次逼近SAR来完成的。
转换结束后,DAC的输入数据就是未知电压的编码,通过8位数字输出端口(D0~D7)进行输出。
结构图上方的EOC(End Of Convert)是转换结束信号。
该芯片通过START端口控制转换开始(给一个输入脉冲,开始转换)
CLOCK是ADC时钟控制ADC内部的转换工作频率。
V ref ( + ) 和V ref ( − ) 是DAC的参考电压,定义数据对应的电压范围
STM32的ADC框图
输入通道
STM32的ADC基本结构总结
输入通道,16个GPIO口外加两个内部通道
规则组最多可以选中16个通道。其中规则组有1个数据寄存器
注入组最多可以选择4个通道.注入组有4个数据寄存器
触发控制提供了开始转换的START信号,触发控制可以选择软件触发和硬件触发,
硬件触发主要来自定时器,也可以选择外部中断引脚,
ADC时钟CLOCK来自RCC
可以布置一个模拟看门狗用于检测转换结果的范围,如果超出设定的阈值就通过中断输出控制向NVIC申请中断,
规则组和注入组转换完成后会有个EOC信号会置一个标志位,也可以通向NVIC,
开关控制,在库函数中就是ADC_Cmd函数用于给ADC上电,
STM32的ADC规则组的四种转换模式
STM32中的ADC规则组的转换模式有以下四种:
单次转换 非扫描模式
连续转换 非扫描模式
单次转换 扫描模式
连续转换 扫描模式
单次转换: 每触发一次,转换结束就会停下来,下次转换就得再触发才能开始。
连续转换: 一次转换完成后不会停止,而是立刻开始下一轮的转换,并持续下去。
非扫描模式:只对存放在序列1的通道起作用。
扫描模式:用到“菜单”列表,可以在菜单里点菜,每个菜单列表位置是通道几是可以任意指定的并且可以重复,然后初始化结构体有个通道数目的参数(表明用了几个通道)
扫描模式下转换到数据寄存器的过程中,用DMA防止数据被覆盖,DMA进行数据及时转移
数据对齐
AD转换时间
即STM32 ADC总转换时间 = 采样时间 + 12.5个ADC周期
ADC库函数
1.RCC_ADCCLKConfig
示例 RCC_ADCCLKConfig(RCC_PCLK2_Div2);
2.ADC_RegularChannelConfig
3.ADC_Init
ADC_Mode
ADC_ScanConvMode
规定了模数转换工作在扫描模式(多通道)还是单次(单通道)模式。可以设置这个 参数为 ENABLE
或者
DISABLE
。
ADC_ContinuousConvMode
规定了模数转换工作在连续还是单次模式。可以设置这个参数为
ENABLE
或 者 DISABLE
。
ADC_ExternalTrigConv使用外部触发来启动规则通道的模数转换
ADC_DataAlign
ADC_NbreOfChannel 规定了顺序进行规则转换的 ADC 通道的数目。
4.ADC_Cmd
5.ADC_GetConversionValue
6.ADC_GetFlagStatus
// 对模拟看门狗进行配置
// 是否启动模拟看门狗
void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
// 配置模拟看门狗高低阈值
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);
// 配置看门通道
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
实现单通道转换
1.开启时钟
2.配置GPIO
3.将指定的GPIO端口接入规则组列表中
4.配置ADC
5.配置中断/看门狗
6.开关控制
7.对ADC进行校准
ADC_ResetCalibration(ADC1); // 复位校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET); // 等待复位校准完成
ADC_StartCalibration(ADC1); // 开始校准
while (ADC_GetCalibrationStatus(ADC1) == SET); // 等待校准完成
作者:不会锐萌萌