AVR Assembler Övningsexempel 7 (7 / 12 steg)
Steg 7: Skriva avbrottshanterare
I det sista steget såg vi att vi har inrättat det så att en stigande kant upptäckt på PD2 utlöser en analog till digital konvertering på PC0 och när konverteringen är klar kommer det att kasta ett ADC konvertering komplett avbrott. Nu vill vi göra något med detta avbrott.
Om du undersöker tabell 12-6 på sidan 65 visas en lista över möjliga avbrotten. Vi har redan sett på RESET avbryta på adress 0x0000 och Timer/Counter0 Overflow avbrottet på adress 0x0020 i föregående Tutorials. Nu vill vi titta på är ADC avbrottet som vi ser i tabellen på adress 0x002A. Så i början av vår assembler kod behöver vi en rad som lyder:
.org 0x002A
rjmp ADC_int
som hoppar till våra avbrottshanterare märkt ADC_int när ADC har avslutat en konvertering. Så hur ska vi skriva vår avbrottshanterare?
Det sätt som ADC fungerar är genom att utföra följande beräkning:
ADC = Vin x 1024 / Vref
Låt oss se vad som händer om jag trycker på "återuppringning"-knappen på knappsatsen. I så fall spänningen på PC0 ändras till något värde, säger 1.52V, och eftersom Vref vid 5V får vi:
ADC = (1.52V) x 1024 / 5V = 311.296
och så det skulle dyka upp som en 311. Om vi ville konvertera den tillbaka till en spänning skulle vi bara vända beräkningen. Vi behöver inte göra detta men sedan vi är inte intresserade av de faktiska spänningarna bara i att skilja mellan dem.
När konverteringen är klar, resultatet lagras i ett 10-bitars tal i ADCH och ADCL register och vi ha lett till att vara "vänster justerad" vilket innebär att de 10 bitarna börjar på bit 7 ADCH och gå ner bit 6 av ADCL (det finns 16 bitar totalt i dessa två register och vi använder endast 10 av dem dvs 1024 kanaler). Vi kunde ha resultatet "rätt justerad" om vi ville genom att avmarkera ADLAR bet i ADMUX register. Anledningen väljer vi lämnade är justerat att våra signaler är tillräckligt långt ifrån varandra att de två sista siffrorna i kanalnumret inte är relevanta och förmodligen bara buller så vi kommer att skilja knapptryckningar använder endast de övre 8 siffrorna, med andra ord, vi behöver bara titta på ADCH att lista ut vilken knapp trycktes.
Så våra avbrottshanterare bör helt enkelt läsa numret ur ADCH registret, konvertera nummer till en knappsats värde, och sedan skicka detta värde till våra register analyzer lysdioder så att vi kan kontrollera att skjuta en "9" säger, kommer att orsaka lampa motsvarar "00001001" att lysa upp.
Innan vi gå så långt men vi måste först se vad dyker upp i ADCH när vi trycka på de olika knapparna. Så låt oss bara skriva en enkel avbrottshanterare som bara skickar innehållet i ADCH till analyzer displayen.
Så är här vad vi behöver:
ADC_int:
LDS analyzer, ADCH, ladda värdet av ADCH i vår analyzer
SBI EIFR, 0; tydliga yttre mellanjobb flaggan så att den är redo att gå igen
Reti
Vid det här laget bör du kunna bara kopiera koden från våra analyzer i handledning 5 och lägga till detta avbrott och växla inställningar och köra den.
Övning 2: Skriva koden och köra den. Se att du får ADCH visning på skärmen analyzer. Försök trycka samma knapptryckning flera gånger. Får du alltid samma värde i ADCH?