模数转换子系统用于将传感器采集的模拟信号转换为数字信号。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 }
时间: 2024-10-20 10:16:13