Förvandla din Arduino till en magnetisk kortläsare! (6 / 9 steg)
Steg 6: Identifiera kortet lämnar läsaren
Upptäcker när ett kort har gått
Formellt, man skulle prova /CARD_PRESENT stiftet för att se om det har gått hög igen, men vi behöver inte någon steenkin' / CARD_PRESENT tar upp en annan I/O port. Det är där dessa timers kommer in.
Varje gång avbrottet kallas eftersom vi har upptäckt en fallande kant på /STROBE, vi stoppa en timer, rensa timer värdet och börja läsa. När vi har avslutat behandlingen starta vi timern igen. Upprepa annons nauseum, eller tills timern når ett visst värde. Det betyder att senaste avbrottet har kallats och inga mer data har kommit med, så vi antar att det är det och börja bearbeta de data vi har samlat in.
För timers använder vi TIMER1, dvs 16-bitars timern. Jag använder en 16 Mhz resonator externt till min AVR. Om du använder en arduino, då är du förmodligen, alltför. Så, jag har valt en prescaler värdet av 1024 vilket innebär att varje (16,000,000 / 1024) gånger timern ökar värdet. Det vill säga, kommer att det "kryssa" 15,625 gånger i sekunden. /CARD_PRESENT går hög om kortet har lämnat läsaren om 150ms efter den senaste data lite. Att veta detta, jag bara bestämde mig att checka om varje 1/4 sekund. Som ser ut ungefär så här:
(((F_CPU) / PRESCALER) / 4)
som visar sig vara cirka 3900. Så, när räknaren timer TCNT1 når 3900, då vet jag det har varit ca 300 MS och kan jag ganska säkert dra slutsatsen att kortet har lämnat läsaren. Enkelt.
#define PRESCALER 1024 #define CHECK_TIME ((F_CPU / PRESCALER) / 4) / / 250 ms #define StartTimer() BSET(TCCR1B,CS10), BSET(TCCR1B,CS12) / / 1024 prescaler #define StopTimer() BCLR(TCCR1B,CS10), BCLR (TCCR1B, CS12) #define ClearTimer() (TCNT1 = 0)
Du har sett i ISR där timern startas, stoppas och rensat på varje avbrott. Nu, i huvudsak loop vi bara kolla att se om räknaren timer har nått våra målvärde, och i så fall börja behandling.
för (;) {om (TCNT1 > = CHECK_TIME) {
StopTimer();
ClearTimer();
ProcessData();
ReadData();
IDX = 0;
bit = 6;
bDataPresent = 0;
MEMSET (& buff, 0, MAX_BUFF_SZ1);
}
}
Nu är det säkert att behandla uppgifterna.