幾乎所有的嵌入式系統(tǒng)都最少需要1個(gè)傳感器與MCU接口,如溫度傳感器、位置傳感器、光電傳感器等。這些傳感器感測自然界的模擬量,并輸出模擬電壓值。
然而,STM32F103C8T6 or Arduino等MCU卻是數(shù)字物種,無法識(shí)別模擬變量。這就需要模數(shù)轉(zhuǎn)換器(ADC),如早期的8051 MCU單片機(jī)就使用了ADC0804之類的外接ADC芯片,把模擬變量轉(zhuǎn)化成數(shù)字信號(hào)。新的MCU,如Arduino or STM32F103C8T6都集成了ADC核心,根本不需要外部元器件。
以下我們就連接一個(gè)最簡單的可變模擬電壓源——電位器,先配置一個(gè)讀模擬量的引腳,再用ADC將其轉(zhuǎn)化成數(shù)字值,并顯示在LCD顯示屏上。
認(rèn)識(shí)STM32藍(lán)丸的ADC
根據(jù)STM32F103C8T6 MCU數(shù)據(jù)表,其ADC為12-bit的逐次逼近型(SAR),支持16個(gè)外部通道的模擬信號(hào)測量。但是,STM32藍(lán)丸的ADC只有10個(gè)通道,也就是,我們只能使用10個(gè)引腳來測量10個(gè)不同的模擬電壓。
STM32藍(lán)丸的ADC分辨率為12-bit,STM32F103C8T6的電壓為0-2^12,即0-4095。
基于模擬電壓,數(shù)字電壓按步數(shù)逐步增加。電壓/步數(shù)之比就是ADC分辨率,公式如下:
電壓/步數(shù) = 參考電壓/2^12
?
這里的參考電壓一般為3.3V,MCU能夠檢測到的最小電壓為:
電壓/步數(shù) = ?3.3/4096 = 0.8056mV /步
輸入電壓 = (ADC讀數(shù) / ADC分辨率) * 參考電壓
電路配置
本項(xiàng)目電路很簡單,所需元件如下:
STM32藍(lán)丸板
16×2 LCD Display
10KΩ電位器 x 2
USB-UART轉(zhuǎn)換器(如果通過UART進(jìn)行編程的話)
杜邦線
?
STM32藍(lán)丸板有10個(gè)模擬輸入:PA0-PA7(ADC0-ADC7)、PB0、PB1(ADC8和ADC9)。本項(xiàng)目使用ADC0,即PA0作為模擬輸入引腳,我們?cè)诖艘_連接10KΩ電位器的抽頭,其他兩腳連接3.3V和GND。
輸出采用16×2 LCD Display,如果電路中的STM32藍(lán)丸板看不清楚的話,可參考下方的大圖。
對(duì)STM32藍(lán)丸板編程
首先,需要對(duì)LCD引腳和ADC引腳進(jìn)行初始化,將出現(xiàn)介紹類信息。
接著,使用analogRead函數(shù)從模擬引腳(PA0)讀取模擬電壓,并將讀數(shù)保存在analogVal變量里。
現(xiàn)在,使用上述公式,可計(jì)算出輸入電壓。使用浮點(diǎn)變量保持計(jì)算出的輸入電壓。
float inputVoltage = ((float) analogVal) / 4096 * 3.3
這樣,就可在LCD上顯示計(jì)算出的模擬電壓和ADC值。繼續(xù)改變電位器,STM32F103C8T6的ADC就會(huì)持續(xù)進(jìn)行模擬電壓讀數(shù),計(jì)算數(shù)值大小,并顯示在LCD顯示屏上。相關(guān)代碼如下:
/*
* 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);
}
?
評(píng)論
查看更多