热度 3
2022-5-31 10:06
2716 次阅读|
0 个评论
几乎所有的嵌入式系统都最少需要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); }