最近在研究 Loenrado 的USB,在\arduino-1.8.4\hardware\arduino\avr\cores\arduino\CDC.cpp 中发现有趣的代码:
// We check DTR state to determine if host port is open (bit 0 of lineState). if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { #if MAGIC_KEY_POS != (RAMEND-1) // Backup ram value if its not a newer bootloader. // This should avoid memory corruption at least a bit, not fully if (magic_key_pos != (RAMEND-1)) { *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos; } #endif // Store boot key *(uint16_t *)magic_key_pos = MAGIC_KEY; wdt_enable(WDTO_120MS); }
这段代码是用来实现 Leonrado 刷新的:通过设置当前USB 传输速度为 1200,然后让板子重启进入Bootloader响应刷写指令而无需使用板载的 Reset按钮(未来会做更具体的分析)。
_usbLineInfo.dwDTERate 这里就是当前设定的USB 通讯速度,因此我们在这里添加代码根据当前速度设定LED On Off。加入的代码段如下:
#if MAGIC_KEY_POS != (RAMEND-1) // For future boards save the key in the inproblematic RAMEND // Which is reserved for the main() return value (which will never return) if (_updatedLUFAbootloader) { // horray, we got a new bootloader! magic_key_pos = (RAMEND-1); } #endif //LABZ_DEBUG_START if (300 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { digitalWrite(2,HIGH); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); } if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { digitalWrite(2,LOW); digitalWrite(3,HIGH); digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); } if (2400 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { digitalWrite(2,LOW); digitalWrite(3,LOW); digitalWrite(4,HIGH); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); } if (4800 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { digitalWrite(2,LOW); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,HIGH); digitalWrite(6,LOW); digitalWrite(7,LOW); } if (9600 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { digitalWrite(2,LOW); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,HIGH); digitalWrite(7,LOW); } if (19200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { digitalWrite(2,LOW); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,HIGH); } //LABZ_DEBUG_ENd // We check DTR state to determine if host port is open (bit 0 of lineState). if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { #if MAGIC_KEY_POS != (RAMEND-1) // Backup ram value if its not a newer bootloader. // This should avoid memory corruption at least a bit, not fully if (magic_key_pos != (RAMEND-1)) { *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos; } #endif // Store boot key *(uint16_t *)magic_key_pos = MAGIC_KEY; wdt_enable(WDTO_120MS); }
这样,当设定不同速度时, D2-D7 上的LED会分别亮起来。
编写一个简单的 Arduino代码
void setup() { // put your setup code here, to run once: pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); pinMode(6,OUTPUT); pinMode(7,OUTPUT); digitalWrite(2,LOW); digitalWrite(3,LOW); digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,LOW); digitalWrite(7,LOW); } void loop() { // put your main code here, to run repeatedly: }
比如当前的IDE 的 Serial Monitor 设定为 4800, D5上面的LED会亮