Stap 4: Detecteren wanneer een kaart is gejat
Formeel, zou men het controleren van de pin van de /CARD_PRESENT om te zien als deze laag wordt neergezet. Gelukkig is dit niet echt nodig. We controleren voor geldige kaart later. Afwisselend, kon u het lezen van uw strobe pin om te zien wanneer flitsers hebben gebracht op de pin, echter dit zal je net veel klokt zero's. De lezer zal sturen over 60-70 voorloopnul is u te laten weten dat de gegevens is ongeveer te worden voorgelegd. Echter, we gonna de aard van de binaire gegevens gebruiken om te bepalen wanneer te beginnen met opnemen van bits. De start-sentinel (SS) voor track een is het percentage teken (%). Het is een binaire waarde is 0010 0101 wat betekent dat het zal worden opgeslagen (en lezen) als 1010 001 (is het 7-bits zodat de 8e bit is niet verzonden). Nu, de oplettende lezer zal merken dat hoewel de gegevens achterstevoren, het komt niet overeen met de binaire ASCII-waarde. Dat is omdat het 0x20 off van hex. Het symbool % is 0x25 en 0100 0101 is 0x05. Kaartgegevens heeft 0x20 afgetrokken van de waarde. Dat een opknoping daar in het hoge knabbelen is de oneven pariteitsbit. Het komt er dus dat er een oneven aantal "1" s in de waarde. Dus omdat we weten dat een geldige kaart begint altijd met deze start sentinel, en omdat het pariteitsbit is een 1, dan wanneer we de eerste hoge naar lage overgang op de data pin detecteren, dan we dat we net zijn begonnen de Schildwacht van de start van een kaart ontvangen weten. Nu dit niet altijd gaat om waar te zijn, en een waterdicht plan zou zijn om te controleren de /CARD_PRESENT kaart om te zien als het laag verder is gegaan. De eenvoudigste manier om het detecteren van het begin van de SS, is het creëren van een externe interrupt geactiveerd op de dalende rand van de /STROBE. De gegevens zijn geldig 1.0 ons vóór de vallende rand, dus wanneer u de dalende rand heb bemonsterd, dan weet je dat kunt u lezen de /DATA1 pin en krijgen een geldige waarde. Hier is de code voor het maken van uw externe interrupt geactiveerd op een dalende rand.
voidInitInterrupt(void){ // Setup interrupt BSET(EIMSK,INT0); // external interrupt mask BSET(EICRA,ISC01); // falling edge BCLR(EICRA,ISC00); // falling edge BSET(SREG,7); // I-bit in SREG}
In mijn common.h die ik in al mijn programma's omvatten, kunnen de definities van Ja en BCLR worden gevonden. Verwijzen naar dat bestand moet u vragen hebt over het instellen van de bits. Nu, wanneer de interrupt wordt geactiveerd, wij willen genieten van de /DATA1 (in mijn code gedefinieerd als CARD_DATA) en een beetje in een algemene doel IO register instellen. Als we op de 7e bit, sla uit het register als een teken in onze globale buffer. Ik gebruik een GPIOR0 register omdat het spiffy snelle toegang. De pseudocode is zoiets als dit:
Stop 16-bit timer Clear timer If DATA is LOW Set BIT=1 in REGISTER Decrement BIT Set flag so we don't skip any more 0's else DATA is HIGH Set BIT=0 in REGISTER Decrement BIT If BIT is 0 Add byte to buffer Increment index Reset BIT
Als u jezelf waarom vragen verlagen in plaats van increment, vergeet niet dat de gegevens in de achteruit, zodat in plaats van het opnemen van de bits zoals we ze van LSB aan MSB krijgen, wij redden hen van MSB aan LSB zodat we niet hoeven te draaien van de bits later wanneer verwerking van de gegevens. Als je echt wilde, kon u ook toevoegen 0x20 hex hier, maar aangezien het over 5us op deze flitsers, ik ben het bijhouden van de verwerking in deze interrupt service routine tot een minimum te beperken.
ISR(INT0_vect){ StopTimer(); ClearTimer(); if ( !BCHK(PIND,CARD_DATA1) ) // inverse low = 1 { BSET(GPIOR0,bit); --bit; bDataPresent = 1; } else if (bDataPresent) { BCLR(GPIOR0,bit); --bit; } if (bit If you're wondering what the timing business is about, that's covered in the step in determining when the card has left the reader.