幾乎所有的嵌入式系統都最少需要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);
}
?
評論
查看更多