Stap 5: Korte intro over PIC en timers
De timers kunnen worden gebruikt voor heel wat taken: maken van tijd-bases, triggering periodiek evenementen, meten de tijd tussen twee gebeurtenissen (maatregel/bClk frequentie), en nog veel meer. In mijn kleine firmware gebruikte ik een timer om mezelf een tien milliseconden tijd-base. Tellen dat honderd keer gaf me een vlag die telkens één seconde doorgegeven kreeg. Dit was nodig, omdat ik wist dat ik wilde het apparaat op te laden voor 10 minuten en dat op maat voor 5 seconden – een standaardtijd-base moest een of andere manier bij het project betrokken worden.
Over PIC timers
Een processor kan het uitvoeren van duizenden instructies in fracties van een seconde, grotere tijd-bases zijn meestal gebouwd door milliseconden een meerdere honderden keren te tellen. Om te kunnen berekenen een kleine timing, zoals één van 1ms, willen we weten hoe snel de PIC echt prestatiestatus. De PIC12F683 heeft een interne oscillator van maximaal 8MHz, dit is wat ik gebruikt om de klok van het apparaat. Wetende dat de PIC moet vier klokken een enkele instructie uit te voeren, de instructie-cyclus is 2 MHz. op basis van dat, is de tijd die nodig is door de PIC een instructie uit te voeren 1/2.000.000 = 500ns. Dit zal de tijd-base die de interne timers zal vooraf met. Elke timer heeft een bijbehorende intern 8 of 16 bits register, dat de waarde verhoogt telkens wanneer deze 500ns passeert. Dit register kan worden gelezen en geschreven op elk gewenst moment. Wanneer de 8 of 16 bits registreert overstorten, is een vlag ingesteld op het signaal van deze gebeurtenis.
Prescalers en postscalers kunnen worden toegewezen aan timers, om langere temporizations. Een prescaler of postscaler is een teller op zijn eigen, configureerbare in een verscheidenheid van manieren. Simpel gezegd, verdeel deze de klok op hun inbreng met een waarde die kan worden gewijzigd door de software. Een prescaler 1:8 geeft een kloksignaal op haar uitvoer na elke 8-th klok bij de uitmonding. Dit betekent, dat het toevoegen van een prescaler 1:8 op een timer input zal vertragen de snelheid deze timer door 8 voorschotten. Postscalers werken op precies dezelfde manier, het is meestal de positie van deze circuits (in verband met de timer-register), die bepaalt of we over een prescaler of een postscaler praten. Prescalers vertragen het tarief van de vooruitgang van het register van de timer, postscaler vertraging het moment wanneer een overloop-gebeurtenis wordt geactiveerd. Met behulp van deze circuits kunnen we creëren tijdstempels voor langere periodes. De gebeurtenis die bij elke overloop optreedt wordt vaak beschreven als de "instelling van de interrupt-vlag".
Zie de configuratie van de timer in onze specifieke voorbeeld!
Configureren van de timer 0
In onze processor er drie timers beschikbaar zijn, zullen we gebruik maken van slechts één: timer nummer 0. De registers die worden geconfigureerd voor deze module moeten te werken zijn: OPTION_REG, INTCON.
Configuratie van OPTION_REG
De hogere knabbelen van dit register niet enig effect hebben op timer0, ik zal hen ingesteld op nullen. De lagere knabbelen bestaat uit de PSA-bit (bit 3) die waar de prescaler zal krijgen toegewezen bepaalt, aan de tijdopnemer 0 of aan de watchdog-timer. Ik wil het verdelen van het tarief van de vooruitgang van het register van de timer timer 0, dus we hebben te stellen op 0. Vervolgens wil ik stel deze in op het verdelen van de klok, zo veel als het kan 1:256. Om dit te bereiken, moet ik de PS2:PS0 bits ingesteld op 111. Dit resulteert in OPTION_REG wordt ingesteld op 0b00000111 = 0x07.
Configuratie van INTCON
Dit register heeft weinig te maken met timer 0 als een interrupt configuratie register, maar -aangezien we interrupt met timer 0 gebruiken – heb ik om het te vermelden. De drie bits die verband met timer 0 houden zijn de volgende: GIE, T0IF, T0IE.
GIE is de bit waarmee interrupts op mondiaal niveau, als deze is ingesteld op 0, geen interrupt zal worden geactiveerd. Natuurlijk, we moeten dit op 1.
T0IE is een interrupt bits te schakelen, maar dit is strikt er voor het inschakelen/uitschakelen van de timer 0-interrupt. We moeten dit op 1 ook.
T0IF is de tijdopnemer 0 interrupt vlag bit die elke keer dat de timer 0 registreren overstorten wordt ingesteld, moeten we duidelijk dit stukje bij het opstarten, het zal worden ingesteld door hardware zodra het timer-register de maximale waarde bereikt en overloopt. Vandaar is het T0IF worden ingesteld op 0.
We moeten INTCON ingesteld op 0b11100000 = 0xE0 zodat deze timer werken op de manier die wij willen.
Andere dingen die gedaan moet worden
Als u wilt maken het exacte tijdstip van één milliseconden, we gonna moet vooraf laden het timer-register. Het aantal timer stappen gedeeld door 256 (vanwege de prescaler die ik koos) toegevoegd aan deze preload waarde moet geven de waarde van de overloop van de timer-register. In ons geval is deze waarde 256, aangezien we een 8 bits timer gebruiken.
Het spul dat we weten:
- oscillator klok = 8 MHz
- instructie klok = 2 MHz
- instructie periode = 500 ns
- prescaler gebruikt = 1:256
- timing wij willen = 10 ms
De dingen die we willen om uit te vinden:
- timer register pre belasting waarde.
We weten dat we willen een 10 ms timing, en we weten dat onze timer tegen een koers van 256 * 500 stappen ns. Oplossen van die vermenigvuldiging vertelt ons dat het register van de tijdopnemer 0 wanneer zal vooraf 128 µs passeert. 10 ms / 128 µs = 78, dit aantal is belangrijk omdat het geeft uiting aan onze 10 ms in aantal timer stappen. We weten dat we willen dat de timer register overflow optreden na 10 ms, en we weten dat dit na de maximale 8-bit waarde, 255 gebeurt. Eenvoudig genoeg, we gewoon moeten 256 – 78 178 = in het timer-register, en wacht tot de vlag instellen. Dit zal gebeuren na 10 ms.
Dit is niet genoeg, dat we hebben ook voor het vernieuwen van het register van de timer met deze waarde na elke overloop. Als we niet doen, het timer-register zal tellen vanaf nul, en de tijdsinstellingen zullen volledig weg (128 µs * 256 is niet 10 ms).
Ik vermeld hoe deze overloop vlaggen kunnen leiden tot interrupts (kan en zal, omdat we deze functie ingeschakeld in het register INTCON). De interrupts worden verwerkt in een speciaal deel van het programma een interrupt service routine genoemd. Wanneer een interrupt wordt geactiveerd, wordt het programma springt naar dit speciale deel van het programma, en voert het. Nadat dat deel van de code (vaak aangeduid als de interrupt behandeld) wordt uitgevoerd, blijft het programma waar het gebleven was voordat de interrupt was gesignaleerd. Hierdoor kan een programmeur te reageren snel op dit soort evenementen, in feite, dit is de reden waarom interrupts "uitgevonden werden". De interrupt service routines dienstig is kort, zodat de uitvoering ervan snel genoeg is. Ik schreef het register van de timer herladen in de interrupt service routine, dit garandeert dat de timer 0 overflows na 10 ms over en weer treedt. De interrupt-vlag moeten ook worden gewist, of anders de processor zal "denken" dat wordt een interrupt wordt gesignaleerd-het zal blijven steken in de routine van de dienst en de belangrijkste code weer niet zal bereiken. Dit is een klassieke fout, en u terug voor een lange tijd kan houden.