在进行USART通信时,了解所使用的微控制器(MCU)类型至关重要,因为不同的MCU可能拥有不同数量的USART端口,甚至可能需要不同的通信设置。尽管目前无法通过程序直接读取Arduino的型号(例如,它是Arduino UNO还是MEGA2560),但仍然可以通过检测使用的MCU类型来实现这一点。
每个ATmega微控制器(以及其他型号)都有一个签名码。这个签名码并不是每颗芯片独有的,但对每种MCU类型来说是唯一的。AVR编程环境提供了三个常量:SIGNATURE_0、SIGNATURE_1和SIGNATURE_2,分别代表签名码的三个字节。因此,检测MCU类型就像读取这三个常量并将其值与已知的芯片类型进行比较一样简单。以下Arduino草图可以检测使用的是ATmega328P还是ATmega2560的MCU,并通过串行控制台显示这些信息:
char *mcuType;
void setup() {
// 启用USART0端口的串行通信
Serial.begin(115200);
// 这是Atmel芯片吗?
if (SIGNATURE_0 == 0x1E || SIGNATURE_0 == 0x00) {
if (SIGNATURE_1 == 0x95 && SIGNATURE_2 == 0x0F) {
mcuType = "ATmega328P";
} else if (SIGNATURE_1 == 0x98 && SIGNATURE_2 == 0x01) {
mcuType = "ATmega2560";
} else {
mcuType = "Unknown Atmel";
}
} else {
mcuType = "Unknown";
}
}
void loop() {
Serial.print("\nYour MCU type is: ");
Serial.println(mcuType);
}
以下表格解释了三个字节签名码的含义:
地址 | 常量 | 代码 | 有效代码 |
---|---|---|---|
$00 | SIGNATURE_0 | 厂商代码 | $1E表示由Atmel制造 |
$01 | SIGNATURE_1 | 部件家族和闪存大小 | $9n表示AVR具有2^n kB闪存内存 |
$02 | SIGNATURE_2 | 部件编号 | 标识家族中的确切芯片 |
MCU类型 | 签名码 |
---|---|
ATtiny13 | 1E9007 |
ATtiny2313 | 1E910A |
ATmega48P | 1E920A |
ATmega8 | 1E9307 |
ATmega168 | 1E9406 |
ATmega32 | 1E9502 |
ATmega328P | 1E950F |
ATmega328-PU | 1E9514 |
ATmega64 | 1E9602 |
ATmega644 | 1E9609 |
ATmega128 | 1E9702 |
ATmega1280 | 1E9703 |
ATmega2560 | 1E9801 |