原创 STM32F103C8T6蓝丸板的ADC功能基础

2022-5-31 10:06 2715 6 3 分类: MCU/ 嵌入式 文集: 技术

几乎所有的嵌入式系统都最少需要1个传感器与MCU接口,如温度传感器、位置传感器、光电传感器等。这些传感器感测自然界的模拟量,并输出模拟电压值。

然而,STM32F103C8T6 or Arduino等MCU却是数字物种,无法识别模拟变量。这就需要模数转换器(ADC),如早期的8051 MCU单片机就使用了ADC0804之类的外接ADC芯片,把模拟变量转化成数字信号。新的MCU,如Arduino or STM32F103C8T6都集成了ADC核心,根本不需要外部元器件。

以下我们就连接一个最简单的可变模拟电压源——电位器,先配置一个读模拟量的引脚,再用ADC将其转化成数字值,并显示在LCD显示屏上。


认识STM32蓝丸的ADC


根据STM32F103C8T6 MCU数据表,其ADC为12-bit的逐次逼近型(SAR),支持16个外部通道的模拟信号测量。但是,STM32蓝丸的ADC只有10个通道,也就是,我们只能使用10个引脚来测量10个不同的模拟电压。

STM32蓝丸的ADC分辨率为12-bit,STM32F103C8T6的电压为0-2^12,即0-4095。

基于模拟电压,数字电压按步数逐步增加。电压/步数之比就是ADC分辨率,公式如下:

电压/步数 = 参考电压/2^12

这里的参考电压一般为3.3V,MCU能够检测到的最小电压为:
电压/步数 = 3.3/4096 = 0.8056mV /步
输入电压 = (ADC读数 / ADC分辨率) * 参考电压


电路配置


本项目电路很简单,所需元件如下:
STM32蓝丸板
16×2 LCD Display
10KΩ电位器 x 2
USB-UART转换器(如果通过UART进行编程的话)
杜邦线

STM32蓝丸板有10个模拟输入:PA0-PA7(ADC0-ADC7)、PB0、PB1(ADC8和ADC9)。本项目使用ADC0,即PA0作为模拟输入引脚,我们在此引脚连接10KΩ电位器的抽头,其他两脚连接3.3V和GND。

输出采用16×2 LCD Display,如果电路中的STM32蓝丸板看不清楚的话,可参考下方的大图。


对STM32蓝丸板编程


首先,需要对LCD引脚和ADC引脚进行初始化,将出现介绍类信息。

接着,使用analogRead函数从模拟引脚(PA0)读取模拟电压,并将读数保存在analogVal变量里。

现在,使用上述公式,可计算出输入电压。使用浮点变量保持计算出的输入电压。

float inputVoltage = ((float) analogVal) / 4096 * 3.3

这样,就可在LCD上显示计算出的模拟电压和ADC值。继续改变电位器,STM32F103C8T6的ADC就会持续进行模拟电压读数,计算数值大小,并显示在LCD显示屏上。相关代码如下:

/*
* LCD VSS pin to GND
* LCD VDD pin to 5V
* LCD VO pin to POT
* LCD RS pin to digital pin PB11
* LCD RW pin to GND
* LCD EN pin to digital pin PB10
* LCD D0 to D3 pins not used
* LCD D4 pin to digital pin PB0
* LCD D5 pin to digital pin PB1
* LCD D6 pin to digital pin PA7
* LCD D7 pin to digital pin PA6
* LCD LED+ pin to 5V
* LCD LED- pin to GND
*/
#include
const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PA7, d7 = PA6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const int analogInput = PA0;
void setup()
{
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(“Electronics Hub”);
lcd.setCursor(0, 1);
lcd.print(” ADC in STM32 “);
delay(2000);
lcd.clear();
}
void loop()
{
int analogVal = analogRead(analogInput);
float inputVoltage = (float(analogVal)/4096) * 3.3;
lcd.setCursor(0, 0);
lcd.print(“ADC Value:”);
lcd.print(analogVal);
lcd.setCursor(0, 1);
lcd.print(“Voltage:”);
lcd.print(inputVoltage);
}

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /2 下一条