STM32——ADC模数转换器

一、AD

ADC模数转换器,将模拟信号转换为数字信号,STM32是数字电路,只有高低电平,ADC转换器可以通过读取引脚连续变化的模拟信号,转化为内存种存储的数字变量,通过对寄存器的读取,就可以获取模拟参量,建立了模拟电路到数字电路的桥梁;

数字电路到模拟电路:

1.PWM;

2.DAC;

二、AD外设

STM32的ADC是一个12位逐渐逼近型ADC,分辨率是0~4096,转换时间是1us;

输入电压范围是0~3.3v;

输入通道是有16个GPIO通道和两个内部通道温度传感器(测量CPU温度)和参考电压(1.2v参考电压不受连接电压影响,当外部连接不是标准的3.3V时,可以用来校准);

有规则组和注入组两个单元;

模拟看门狗自动监测输入电压范围;

三、8位ADC逐次逼近型

逻辑结构:外部待测信号通过8个输入引脚,通过通道选择开关选择一个输入,通过配置三位地址名称和一个译码选择待测通道,输入作为比较的一个输入,比较器另一个输入是DAC输出,通过SAR逐次比较寄存器配置,选择内经过ADC预分频器分频后的时钟CLOCK作为时钟源驱动比较,当触发源START触发时,在时钟驱动下通过二分法依次比较已知编码DAC和未知编码待测信号的值,如果DAC大于待测信号,则降低DAC大小,反之增大,经过比较得到8位的二进制数据,存放在锁存缓存器中,存在数据寄存器中,通过读取数据寄存器并线系转换后,即可获得模拟量,转换完成后至EOC标志位;

ADC连接VCC和GND,DAC连接参考电压VEF+,VEF-(二者通常连接在一起);

因为外部信号是持续变化的,对数据进行量化编码;这是需要时间的,而在转换进行比较的时候,外部信号依然在不断变化,所以当需要采样时,进行采样,然后关闭采样通道,保持一个固定的值,然后进行比较,量化,编码;

ADC转换时间:采样时间+12.5个ADC周期;

四、ADC结构图

通过16个GPIO的输入和两个内部输入组成18个输入通道,输入至模拟多路开关(数据选择器),经过开关选择后,进行待测通道配置 ,分为注入组和规则组(注入组一次可测量四个数据,存放在四个数据寄存器中,规则组一次可测量多个数据,存放在一个数据选择器中,但是后一个数据会覆盖前一个数据,需要DMA及时转运;)

通过触发源选择选择是外部触发源(EXTI和定时器内部信号,使用定时器定时触发测量)还是软件触发,通过来自ADC预分频器的APB2时钟驱动模数转换器进行转换,转换完成后,将转换的值放在16位数据寄存器中,并置标志位EOC,可以连通NVIC申请中断,同时可以申请DMA转移,也可以配置模拟看门狗检测指定通道的电压(原理是:设计一个阈值范围,如果超过阈值,置标志位,产生中断至NVIC,执行某些程序);

其中,12位逐渐逼近型ADC,比较后得到12位,存放在16位寄存器中,通过左,右对齐方式;

左对齐,会使结果放大2的四次方;

触发控制:

 

 

 

五、AD流程图

ADC和GPIO开启时钟使能配置后,外部待测信号通过GPIO(内部温度传感器和参考电压),输入到AD待测通道,配置待测通道(注入组还是规则组,顺序以及个数),选择触发方式和时钟源分频后,进行转换,转换完成后将数据存放在数据寄存器中,置EOC标志位可以通过中断输出控制,连接NVIC,可以配置模拟看门狗置NVIC,最后使能AD,可以通过读取数据寄存器的值,在进行线系转换得到模拟量;

 

六、规则组

单次转换,非扫描模式

每次转换时,需要单独触发,触发后等待转换完成,判断EOC标志位,读取数据;

连续转换,非扫描模式

只需要触发一次,之后需要数据时,直接读取就行;

单次转换,扫描模式

每次转换需要单独触发,依次转换,所有数据转换完成后,才置标志位EOC;

需要及时读取,否则后面的数据会被前面的数据覆盖;

连续转换,非扫描模式 

只需要触发一次,依次转换,所有数据转换完成后,才置标志位EOC;

需要及时读取,否则后面的数据会被前面的数据覆盖;

七、AD校准

ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差 建议在每次上电后执行一次校准 启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期 

八、AD的硬件图

第一个是将ADC采集引脚,连接在电位器上;

第二个连接一个电阻和传感器分压,测量传感器电压;

第三个测量VIN电压值,通过分压电路;

VIN电压=R1/(R1+R2)*5V;

九、API

9.1AD单通道

9.1.1功能:通过软件触发方式,采集指定通道的模拟量,并转换为电压值,显示在OLED上‘

9.1.2思路:

驱动层:初始化ADC,获取采集AD值;

应用层:将采集的值转换为电压值,OLED显示;

驱动层:

1.RCC开启ADC和GPIO时钟;

2.配置ADC预分频器;

3.初始化GPIO,配置为模拟输入,读取引脚模拟量;

4.初始化ADC,选择扫描模式和转换模式,使能ADC,选择触发方式;

5.配置规则组列表;

6.使能ADC;

7.复位校准ADC;

8.选择软件触发,while等待标志位,读取AD值

应用层:

9.通过线性关系,将读取的AD值转换为模拟量;

10.通过OLED显示;

9.1.3库函数

void ADC_DeInit(ADC_TypeDef* ADCx);//复位
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);//初始化
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);//初始化结构体
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//使能ADC
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);//DMA转运初始化
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);//中断到NVIC
void ADC_ResetCalibration(ADC_TypeDef* ADCx);//复位校准
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);//获取复位校准状态
void ADC_StartCalibration(ADC_TypeDef* ADCx);//开始校准
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//获取校准状态
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC软件触发模式
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);//
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);//配合间断模式,每隔几个
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//开启间断模式
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//给序列每个位置填写通道
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//ADC外部触发转换(是否允许外部触发ADC)
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);//获取ADC的值
uint32_t ADC_GetDualModeConversionValue(void);//获取双ADC转换值
void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);//注入组进行配置
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);
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);//配置看门通道
void ADC_TempSensorVrefintCmd(FunctionalState NewState);//内部通道
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//获得标志位状态,判断转换是否结束
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);//清除标志位
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);//获取中断标志位状态
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);//清除标志位

 9.1.4实现

1.RCC开启ADC和GPIO时钟;

2.配置ADC预分频器;

3.初始化GPIO,配置为模拟输入,读取引脚模拟量;

4.初始化ADC,选择扫描模式和转换模式,使能ADC,选择触发方式;

5.配置规则组列表;

6.使能ADC;

7.复位校准ADC;

8.选择软件触发,while等待标志位,读取AD值

应用层:

9.通过线性关系,将读取的AD值转换为模拟量;

10.通过OLED显示;

9.2AD多通道 ’

同时配置多通道,不使用DMA

 

  • 15
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32 ADC模数转换实验中,可能会遇到以下问题: 1. ADC采样值不正确 如果ADC采样值不正确,可能是因为ADC参数配置不正确或者采样时序不正确导致的。需要确认以下几点: - 确认ADC参数配置正确,包括采样时间、采样通道、采样分辨率等参数 - 确认ADC时钟已经使能 - 确认ADC采样时序正确,包括采样开始时间、采样保持时间和转换时间等参数 2. ADC采样速率不稳定或者出现噪声 如果ADC采样速率不稳定或者出现噪声,可能是因为ADC参考电压不稳定或者ADC输入信号不稳定导致的。需要确认以下几点: - 确认ADC参考电压稳定,可以使用稳压器等设备来提供稳定的参考电压 - 确认ADC输入信号稳定,可以使用滤波电路等方法来滤除噪声和干扰信号 解决方法: 在使用STM32 ADC模数转换时,可以采用以下步骤进行配置和编程: 1. 配置ADC参数 使用ADC_Init函数对ADC进行配置,设置相应的采样时间、采样通道、采样分辨率等参数。 2. 开启ADC采样 在程序中开启ADC采样,使得程序能够读取ADC转换结果。 3. 编写中断服务函数 根据需要编写中断服务函数,并在函数中进行相应的处理。需要注意的是,中断服务函数应该尽可能的简单,避免长时间占用CPU资源,否则可能会影响其他重要任务的执行。 4. 烧录程序 将程序烧录到STM32芯片中,通过读取ADC转换结果,观察ADC采样值的情况和中断服务函数的执行情况。 需要注意的是,在编写程序时需要遵循一些规范和最佳实践,如使用宏定义等方法来定义常量和变量,避免使用硬编码方式;使用滤波器等技术来提高ADC采样值的精度和稳定性等。同时,建议使用示波器等工具来观察ADC采样值的情况和中断服务函数的执行情况,以便进行调试和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值