AVR: Watchdog som tidsinställda avbrott
I denna tutorial jag använder en Attiny85 mikrokontroller och jag vill ha en lysdiod blinka med ungefär 1 andra intervall.
Vanligtvis med Arduino och andra blink tutorials använda du bara en fördröjning av 1 andra eller 1000 millisekunder för att slå på och av. I den här guiden kommer vi att använda en speciell funktion för MCU som sällan får den uppmärksamhet det förtjänar.
WATCHDOG
Nu som låta hunden ut du kan säga, och jag skrattar... haha...
Watchdog används normalt som en säkerhetsåtgärd, för om MCU i en otillgänglig plats och det hänger av någon anledning, du har ingen möjlighet att återställa det och få det att fungera igen. Så vakthund är en nästan separat del av MCU, har den en klocka i sin egen (normalt en RC-krets) och en prescaler av denna klocka, nu vad den inte har är en timer jämföra eller ett sätt att ange en exakt timing. Det finns bara översvämningen.
Nu för en ATtiny85 finns 10 olika prescaling för att använda, från 16ms till 8 sekunder (se datablad s. 46 för detaljer). Watchdog används normalt för att återställa MCU men det kan också ställas in att köra en avbryta.
Först och främst, låt oss börja med att sätta upp vakthund.
Inaktivera alla avbrott
CLI();
/ * Rensa MCU Status Register. Egentligen inte behövs här som vi inte behöver veta varför MCU fick återställa. sida 44 av datablad * /
MCUSR = 0;
/ * Inaktivera och radera alla inställningar för Watchdog. Trevligt att få en kula när man arbetar med avbryter * /
WDTCR = (1 << WDCE) | (1 << Mimmi);
WDTCR = 0;
Setup vakthund för avbrott och återställs inte, och ett ungefärligt 500ms timeout s.45
WDTCR = (1 << WDIE) | (1 << WDP2) | (1 << WDP0);
Aktivera alla avbrott.
SEI();
Detta är det säkra sättet att ställa upp, anledningen till varför vi gör lite "städning" i början är att se till att vi får vad vi vill. statisk och vem vet vad kan röra upp en MCU så det är bra att göra det rätt, om du inte vill att vara säker, allt du behöver är denna linje
WDTCR = (1 << WDIE) | (1 << WDP2) | (1 << WDP1);
Nu har vi watchdog ställs in och gör ingenting, väl inte riktigt som vakthund är en säkerhetsåtgärd det har några intrikata flyttar. I detta fall vi säger till den att köra en ISR varje 500ms (ungefär) men vi har inte gjort en ISR för det ännu, och som sagt denna funktion har några intrikata sätt fungera så när ISR körs, watchdog automatiskt växlar från avbrottsläge återställa läget!
Om inte avbrottsläge aktiveras igen i ISR.
Så, låt oss göra en blinky ISR
ISR(WDT_vect) {
Flip bit 3 av PORTB
PORTB ^ = (1 << 3);
/ * Återaktivera watchdog avbrottet, som detta får återställa när du anger denna ISR och kan automatiskt Mimmi signalen som återställer MCU nästa gång timern flödar över * /
WDTCR | = (1 << WDIE);
}
Nu har vi en ISR som vänder den LED som du har anslutit till PORTB3 på och av varje 1/2 sekund och återaktiverar avbrottet.
Var inte enkelt?
Här är hela MrBlinky c-filen.