洋桃电子STM32F407单片机入门教程笔记七:ADC模数转换功能

本文详细介绍了STM32F407单片机的ADC功能,包括其工作原理、分辨率、多通道转换、硬件电路配置,以及如何通过STM32CubeMX进行初始化和使用HAL库进行数据读取。通过实例演示了如何利用ADC读取模拟电压和环境光线强度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 此文档作为对洋桃电子STM32F407单片机视频的整理,B站链接:第23集)ADC模数转换功能_哔哩哔哩_bilibili

        ADC是将模拟信号转换成数字信号的功能,可以读出端口上的电压值,是常用的单片机内部功能。

        GPIO端口功能只有高电平和低电平两种输入状态,适用于按键之类的输入电平,只有开和关两种状态的数字信号。输入到单片机时以1和0表示,但还有一些电路输入的是线性电压值,电压是0V~3.3V之间的任意值,这时就需要ADC功能来读取这种模拟电压值,输入到单片机时,在12位分辨率下以0~4095之间的数值表示。通过简单的算法就可以得出真实的电压值。

        ADC功能的应用非常广泛,读光敏电阻可以得出光线强弱数值,读热敏电阻可得出温度值,读电池电压可得出电池电量状态。

1. F4单片机ADC简介

        STM32F407系列单片机内部有3个独立ADC功能,每个ADC有16个外部输入通道,可设置12位、10位、8位、6位多种转换分辨率,可设置单次和连续转换模式,可以在多通道之间自动轮回采样。

        ADC功能除了16个外部模拟电压输入通道,其中通道16 (ADC_IN16)可读取单片机内部的温度传感器,芯片内置的温度传感器是一个热敏电阻,可提供温度的模拟电压值,我们使用ADC采集此电压值便可得出粗略的芯片内部温度值。通道17(ADC_IN17)连接的是内部参考电压电路,VREFINT可提供一个相对恒定的电压值,用单片机ADC读取这个电压值可用于校准ADC的采样精度。

        VDDA和VSSA是单片机内部模拟电路部分(包括ADC功能)的电源,通常会将其与逻辑电源VDD和VSS并联,VREF+和VREF-是模拟参考电压输入端口,ADC转换的电压范围将由这两个端口提供,在应用中通常会将VREF-与VSSA连接在一起,将VREF+与VDDA连接在一起。使模拟电源电压作为参考电压使用,这里需要注意VREF+端口上的电压值必须大于1.8V且不超过VDDA的电压值。ADCx_IN是从0~15共16个模拟输入通道,可在CubeMX端口视图中将通道映射到复用的GPIO端口。

        假如VREF与3.3V逻辑电源连接,则ADC可读取的电压范围是0V~3.3V,每个ADC功能都具有12位分辨率,即4096级精度。0V~3.3V电压转换成对应的数值范围是0~4095。

2. ADC硬件电路

        图中可以看出共有两路ADC输入源,开发板上的手调电位器连接到单片机的PC3端口,当可调电阻调到阻值最小值时,PC3输入电压等于0V 转化数值为0。当可调电阻调到阻值最打值时,PC3输入电压等于3.3V 转化数值为4095。当旋钮在最小和最大值之间旋转,PC3输入电压值在0V~3.3V之间线性变化,转化数值在0~4095之间线性变化。

        开发板上的光敏电阻可以接收环境光线,光敏电阻连接到单片机的PC2端口。当环境无光时光敏电阻RG1达到最大电阻值,由于电阻上拉作用使PC2端口输入的电压值升高。当环境光线强时光敏电阻RG1达到最小电阻值,由于电路的分压作用使PC2端口输入的电压下降。

        从以上原理可以看出,只要读取PC2和PC3端口的ADC数值就能判断环境光线强弱变化和电位器的旋钮角度。

3. STM32cubeMX初始化

        时钟树视图中ADC功能时钟连接在APB2外设时钟,比时钟最大不超过84MHz 我在这里设置为72MHz。

        根据电路原理图中的引脚定义来设置单片机端口。

4. 运行函数

        在第105~106行自动生成了ADC1和ADC2的初始化函数,在CubeMX中设置的参数都变成了这里的初始化代码,单片机上电时会执行这两条初始化程序,把设置内容写入ADC功能寄存器,使PC2和PC3端口变成模拟输入状态,使ADC功能准备就绪。

        在adc.h文件中是宏定义和函数声明,其中不仅包含了ADC读取函数,还有平均值算法和电压值算法的内容。当前只学习ADC的简单数据读取,暂时不需要考虑adc.h文件中的内容。

        第13~20行的ADC Read函数,函数的参数是ADC功能的句柄,当参数是&hadc1表示读取的是ADC1的数据,当参数是&hadc2表示读取的的ADC2的数据,函数的返回值是最终读出的12位ADC转换数值。

        函数内部第14行是调用HAL库函数开启ADC1的转换,此程序执行后单片机内部的ADC功能电路开始采集端口的电压值将其转换为12位数值。由于转换的过程需要等待一段时间,所以第15行调用另一个HAL库函数等待ADC转换工作结束。执行这一条程序后程序在此循环等待。当ADC转换结束才继续执行第16行,第16行依然是调用HAL库函数读取ADC转换完成标志位,如果标志位判断为真说明转换成功。转换得出的数值存放到相应寄存器,接下来第17行调用读取ADC数据寄存器的HAL库函数,把数值送到返回值并退出函数。如果第16行判断为假,表示读取失败则不会执行第17行,会执行第19行使返回值等于0xFFFF。因为正常的12位ADC转换数据不会出现OXFFFF这个结果,所以当读取数值是0xFFFF 就表示读取失败。

        在主函数开始处的第82行定义数组ADC_BUF,用于临时存放转换后的ADC数值。

        在主循环程序里加入读取ADC数值的程序,在main.c文件的第115~116行调用两次ADC_Read函数,得到的返回值分别存入ADC BUF数组,第117行调用USART1_printf函数把两个数值显示到超级终端,其中“%04d”的意思是用四位十进制显示数值,数值不足四位的用0补充,这样使ADC数值显示为0000~4095,参数中的两个“%04d”按先后顺序对应着逗号后面的ADC_BUF[0]和ADC_BUF[1]两个数值。

5. 实验现象

### 配置和读取STM32 Vrefint值 #### 使用CubeMX配置Vrefint 为了通过STM32CubeMX配置并读取内部参考电压(Vrefint),需遵循特定设置流程。首先,在STM32CubeMX图形化界面中启动项目,选择目标MCU型号后进入Pinout & Configuration模块。 在Configuration标签页下找到RCC (Reset and Clock Control)选项卡内的`Internal Voltage Reference`部分[^1]。激活此功能通常涉及勾选启用框以及调整相关参数来满足具体应用需求。对于某些系列如STM32H7, 可能会遇到UI显示数值与实际不符的情况,例如默认显示为2.048V但实际上应为2.5V的设定值[^3]。 接着转到ADC外设配置页面,确保启用了至少一个ADC通道用于测量Vrefint信号源。这一步骤可能需要指定采样时间、分辨率以及其他影响精度的因素。值得注意的是,不同版本或类型的STM32器件间可能存在细微差异,因此建议参照官方文档获取最准确指导[^4]。 完成上述硬件抽象层(HAL)库初始化代码生成之后,可以在应用程序层面实现具体的读数逻辑: ```c #include "stm32f4xx_hal.h" // 假定已正确设置了系统时钟和其他必要的初始化工作... float Read_VREFINT(void){ ADC_ChannelConfTypeDef sConfig = {0}; /* 启动ADC校准 */ if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK){ Error_Handler(); } /* 设置要使用的ADC通道 */ sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; // 或者是其他定义好的宏表示Vrefint对应的通道编号 sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_92CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){ Error_Handler(); } /* 开始一次单独转换 */ HAL_ADC_Start(&hadc1); uint32_t rawValue = HAL_ADC_GetValue(&hadc1); float vdd = 3.3F; // 这里假设供电电压为3.3伏特,请根据实际情况修改 const float vRefIntCalibTrim = *(uint16_t*)VREFINT_CALIBRATION_ADDR / 4096 * vdd; return ((rawValue * vdd) / 4096) / vRefIntCalibTrim; } ``` 这段程序展示了如何利用HAL函数执行单次AD转换操作,并计算得到相对精确的Vrefint电平值。注意这里的vdd变量应当反映板载电源的实际供给情况,而VREFINT_CALIBRATION_ADDR则指向存储于闪存中的出厂预设校正值地址。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值