Stap 3: De Code schrijven
RFID Reader gegevensindeling
De Parallax RFID-lezer verzendt gegevens met een vaste, glaciale tempo van 2400 baud. Een RFID-tag is 10 bytes. Zodat voor fout detectie/correctie, omdat de lezer van willekeurige ruis kan worden verrekend, wordt de 10-byte RFID begrensd door een begin- en eindtijd sentinel. De start-sentinel is regelinvoerteken (0x0A) en de stop-sentinel is regelterugloop (0x0D). Het kijkt als dit:
[Start Sentinel |Byte 1|Byte 2|Byte 3|Byte 4|Byte 5|Byte 6|Byte 7|Byte 8|Byte 9|Byte 10| Stop Sentinel]
Dit zijn de drie primaire stappen.
Weten wanneer er een tag is ingediend
Ik gebruikte een Pin wijzigen onderbreken op de AVR die waarschuwt de firmware die een verandering is opgetreden op een gecontroleerde pin. Configureren van de AVR voor dit is eenvoudig en vereist de vlag instelt, de MCU vertellen welke pin die u wilt controleren en de global interrupt-bit.
PCINT configureren
BSET(PCICR,PCIE2); // pin change interrupt control register pcie2 BSET(PCMSK2,PCINT18); // enable pin change interrupt for PCINT18 (PD2) BSET(SREG,7); // Set SREG I-bit
Uw interrupt service routine schrijven
U wilt bewaren uw korte ISR dus in mijn interruptvector ik lees de gehele byte, stukje bij beetje, en de byte in een mondiale volatiele karakter array opslaan. Ik doe het volgende op elke interrupt:
- Controleer ik op een startbit
- Centreren van de timing op de middelste pols op 2400 baud (de snelheid van de RFID-lezer)
- Overslaan van de startbit en pauzeer aan het midden van de volgende bits
- Elke bit in een niet-ondertekende integer lezen
- Wanneer ' 8 bits got youve, zet de byte in een karakter array
- Wanneer ik heb verzameld 12 bytes, laten de MCU weet dat de tag is gelezen voor foutdetectie.
Ik wijzigde SoftSerial code van Mikal Hart die code van David Mellis voor de experimenteel bepaalde vertragingen in de seriële routines heeft gewijzigd.
Parseren van de RS232-Output
De PCINT-routine bevat de code voor het lezen van de RS232-output van de RFID-lezer.
Toen ik 12 bytes (10-byte RFID plus sentinels) heb gekregen ik bDataReady ingesteld op 1 en laat de hoofdlus gegevens verwerken en weer te geven.
// this is the interrupt handlerISR(PCINT2_vect){ if (BCHK(PIND,RFID_IN)) // Start bit goes low return; uint8_t bit = 0; TunedDelay(CENTER_DELAY); // Center on start bit for (uint8_t x = 0; x < 8; x++) { TunedDelay(INTRABIT_DELAY); // skip a bit, brother... if (BCHK(PIND,RFID_IN)) BSET(bit,x); else BCLR(bit,x); } TunedDelay(INTRABIT_DELAY); // skip stop bit RFID_tag[rxIdx] = bit; ++rxIdx; if (rxIdx == 12) bDataReady = 1;}
Uw label weergeven
In de main() controleren tijdens de for(ever) loop, ik om te zien als bDataReady is ingesteld, signalering dat de gehele structuur van RFID is verstuurd. Ik dan check om te zien of het een geldige code (dwz start en stop karakters zijn 0x0A en 0x0D, respectievelijk), en als zo, ik stuur het uit mijn RS232 verbinding.
for (;;){ if (bDataReady) {#ifdef __DEBUG__ USART_tx_S("Start byte: "); USART_tx_S(itoa(RFID_tag[0],&ibuff[0],16)); ibuff[0] = 0; ibuff[1] = 0; USART_tx_S("\nStop byte: "); USART_tx_S(itoa(RFID_tag[11],&ibuff[0],16));#endif if ( ValidTag() ) { USART_tx_S("\nRFID Tag: "); for(uint8_t x = 1; x < 11; x++) { USART_tx_S(itoa(RFID_tag[x],ibuff,16)); if (x != 10) USART_tx(':'); } USART_tx_S("\n"); } rxIdx = 0; bDataReady = 0; }}