模數轉換子系統用於將傳感器采集的模擬信號轉換為數字信號。Arduino UNO R3主處理器ATMega328P的模數轉換子系統采用逐次逼近的方式完成模數轉換。
使用Arduino庫函數進行模數轉換十分簡單,下面的示例可以將A0引腳上的模擬信號轉換為數字信號,並將轉換結果打印到串口0上:
1 // ReadAnalogVoltage.ino 2 void setup() { 3 Serial.begin(9600); 4 } 5 6 void loop() { 7 int sensorValue = analogRead(A0); 8 float voltage = sensorValue * (5.0 / 1023.0); 9 Serial.println(voltage); 10 }
與模數轉換相關的Arduino庫函數有:
analogRead(pin):將指定引腳上的模擬信號轉換為數字信號
pin:指定模擬引腳
函數返回轉換結果,是一個無符號整數,取值為0~1023
ATMega328P的模數轉換子系統由2個相關寄存器控制。模數轉換多路選擇寄存器ADMUX的結構如下圖所示:
REFS1 |
REFS0 |
ADLAR |
|
MUX3 |
MUX2 |
MUX1 |
MUX0 |
輸入通道選擇MUX[3:0]位用於指定模擬信號輸入的引腳,Arduino UNO R3開發板上有6個模擬信號輸入引腳,它們分別是A0~A5,在ANALOG IN組中。
模數轉換控制和狀態寄存器ADCSRA的結構如下圖所示:
ADEN |
ADSC |
ADATE |
ADIF |
ADIE |
ADPS2 |
ADPS1 |
ADPS0 |
向模數轉換使能位ADEN寫入1則啟用模數轉換,寫入0則禁用;向模數轉換啟動轉換位ADSC寫入1則啟動模數轉換,寫入0則不啟動;模數轉換中斷標志位ADIF在被置1時模數轉換完成,可以向它寫1清0;模數轉換預分頻選擇位ADPS[2:0]用於設置模數轉換的時鍾源,它的設置如下表所示:
ADPS[2:0] |
時鍾源 |
000 |
系統時鍾2分頻 |
001 |
系統時鍾2分頻 |
010 |
系統時鍾4分頻 |
011 |
系統時鍾8分頻 |
100 |
系統時鍾16分頻 |
101 |
系統時鍾32分頻 |
110 |
系統時鍾64分頻 |
111 |
系統時鍾128分頻 |
模數轉換的結果保存在模數轉換數據寄存器ADCH和ADCL中。通過直接訪問寄存器改寫以上程序為:
1 // ReadAnalogVoltage_reg.ino 2 void setup() { 3 ADMUX = 0x00; 4 ADCSRA |= (1 << ADEN); 5 6 Serial.begin(9600); 7 } 8 9 void loop() { 10 ADCSRA |= (1 << ADSC); 11 while (!(ADCSRA & (1 << ADIF))); 12 13 int sensorValue = (ADCH << 8) | ADCL; 14 float voltage = sensorValue * (5.0 / 1023.0); 15 Serial.println(voltage); 16 ADCSRA |= (1 << ADIF); 17 }