Οι AVR διαθέτουν μετρητές
(Timers/Counters) με δυνατότητα
σύγκρισης και διακοπής. Ο χρονισμός τους μπορεί να είναι σύγχρονος ή ασύγχρονος,
από το ρολόι συστήματος ή από εξωτερική πηγή και υπάρχει δυνατότητα διαίρεσης
της συχνότητας χρονισμού με prescaler ώστε να επιτευχθεί ο επιθυμητός ρυθμός μέτρησης. Οι μετρητές
χρησιμοποιούνται για ακριβή χρονισμό ή διακοπή μετά το πέρας κάποιου
συγκεκριμένου χρονικού διαστήματος και για παραγωγή παλμών διαμόρφωσης πλάτους
(PWM).
Ο ATmega16 διαθέτει τρεις μετρητές Timer/Counter0:2. Οι Timer/Counter0 και Timer/Counter2 είναι 8-bit, ενώ ο Timer/Counter1 είναι 16-bit
και είναι διπλός Α και Β. Οι Timer/Counter0 και Timer/Counter1 έχουν
σύγχρονη λειτουργία ενώ ο Timer/Counter2 ασύγχρονη. Οι μετρητές κάνουν μέτρηση και
σύγκριση μεταξύ των καταχωρητών τους. Ο καταχωρητής μέτρησης είναι ο TCNTn (n:
0, 1A, 1B, 2) και μεταβάλλει το
περιεχόμενό του προς τα πάνω ή προς τα κάτω, από το ελάχιστο όριο Bottom έως το μέγιστο Max ή Top,
ανάλογα με τον τρόπο λειτουργίας του μετρητή. Το περιεχόμενό του συγκρίνεται με
το περιεχόμενο του καταχωρητή σύγκρισης OCRn και όταν υπάρξει ισότητα ή κατά την υπερχείλιση του TCNTn, προκαλείται μια διακοπή. Η διακοπές που
προκαλούνται και οι σημαίες που τοποθετούνται στα όρια διαμορφώνουν κάποιες
λειτουργίες. Το όριο Bottom είναι
σε όλους τους μετρητές 0 (0x0), το όριο Max εξαρτάται από τα bit του μετρητή και το Top από τον τρόπο λειτουργίας του
και από τον OCRn.
Οι τρόποι λειτουργίας των μετρητών καθορίζονται από τα WGMnx bit του καταχωρητή TCCRn. Ο πιο
απλός τρόπος λειτουργίας είναι ο Normal Mode όπου
ο TCNTn μετράει προς τα
πάνω μέχρι το μέγιστο και ξεκινάει πάλι από την αρχή. Όταν φτάσει στο μέγιστο
τοποθετείται η σημαία υπερχείλισης TOVn και προκαλείται η αντίστοιχη διακοπή[1], η οποία
μηδενίζει την TOVn.
Στη λειτουργία Clear Timer on Compare Match (CTC) Mode ο TCNTn
μετράει προς τα πάνω και συγκρίνεται με το περιεχόμενο του καταχωρητή OCRn. Όταν υπάρξει ισότητα τοποθετείται η σημαία OCn και προκαλείται η αντίστοιχη
διακοπή[2],
ενώ ταυτόχρονα μηδενίζει ο TCNTn και ξεκινάει το
μέτρημα ξανά. Την κατάσταση της OCn μπορούμε να
πάρουμε ως κυματομορφή στο αντίστοιχο pin του PORT, εφόσον το ενεργοποιήσουμε ως
έξοδο και ρυθμίσουμε την OCn από
τα bit COMnx του καταχωρητή TCCRn να αλλάζει την λογική της κατάσταση στο σημείο σύγκρισης (Toggle). Η κυματομορφή εξόδου θα είναι συμμετρικοί παλμοί
όπου η συχνότητα εξαρτάται από τη συχνότητα του ρολογιού του συστήματος, τον prescaler και από την τιμή του OCRn. Στη συνέχεια παρουσιάζεται ένα παράδειγμα χρήσης
του Timer/Counter1A γραμμένο σε γλώσσα
προγραμματισμού C (η ρουτίνα της διακοπής εκτελείται με
συχνότητα 250Hz):
#include <avr/io.h>
#include <avr/interrupt.h>
void Timer1_init() //
Initialize Timer1A
{
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC
mode
TCCR1B |= (3 << CS10); // clk/64
TIMSK |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A = 500; // Set CTC for 250Hz at 8MHz clock
sei();
// Enable global interrupts
}
ISR(TIMER1_COMPA_vect)
{
/* Your code here */
}
int main(void) // Main program
{
/* Your code here */
Timer1_init();
While (1)
{
/* Your code here */
}
}
Η ρουτίνα Timer1_init() είναι υπεύθυνη για το initialization του Timer, όπου ρυθμίζεται να
λειτουργεί σε CTC κατάσταση, ο
χρονισμός να είναι από το ρολόι συστήματος διαιρεμένος με το 64, ενεργοποιείται
η διακοπή από CTC, ενεργοποιούνται οι διακοπές γενικά
και ορίζεται τιμή σύγκρισης στον OCR1A 500 ώστε να προκαλούνται διακοπές με συχνότητα 250Hz. Ακολουθεί το διάνυσμα της διακοπής ISR(TIMER1_COMPA_vect)
όπου ο κώδικας που είναι γραμμένος στο μπλοκ κάτω από τον τίτλο του εκτελείται
κάθε φορά που προκαλείται διακοπή από τη σύγκριση. Στο κυρίως πρόγραμμα τέλος,
καλείται η ρουτίνα για το initialization πριν τον κυκλικό βρόχο.
Στη λειτουργία Fast PWM Mode ο TCNTn
μετράει προς τα πάνω και συγκρίνεται με το περιεχόμενο του καταχωρητή OCRn. Όταν υπάρξει ισότητα τοποθετείται (ή μηδενίζει στην
ανάστροφη λειτουργία) η σημαία OCn και
προκαλείται η αντίστοιχη διακοπή[3]
χωρίς να μηδενίζει ο TCNTn, ο οποίος συνεχίζει
το μέτρημα μέχρι το Max. Όταν φτάσει στο Max μηδενίζει (ή τοποθετείται) η OCn,
μηδενίζει ο TCNTn και ξεκινάει το μέτρημα ξανά,
τοποθετείται η σημαία υπερχείλισης TOVn και προκαλείται η αντίστοιχη διακοπή[4] η οποία
μηδενίζει την TOVn. Την κατάσταση της OCn μπορούμε να πάρουμε ως κυματομορφή στο αντίστοιχο pin του PORT,
εφόσον το ενεργοποιήσουμε ως έξοδο και ρυθμίσουμε κατάλληλα την OCn από τα bit COMnx του
καταχωρητή TCCRn σε
κανονική, ανάστροφη ή Toggle λειτουργία.
Η κυματομορφή εξόδου θα είναι παλμοί με σταθερή συχνότητα και διαμόρφωση εύρους
(duty cycle)
από 0-100% (PWM). Η συχνότητα εξαρτάται από τη
συχνότητα του ρολογιού του συστήματος και τον prescaler ενώ το duty cycle από την τιμή του OCRn. Στη συνέχεια παρουσιάζεται ένα παράδειγμα παραγωγής
παλμών PWM στο pin PB3
γραμμένο σε γλώσσα προγραμματισμού C:
#include <avr/io.h>
unsigned char pwmout;
void PWM0_init() // Initialize PWM0
{
DDRB |= (1 << PB3); // PWM PB3 OC0
TCCR0 |= (3 << WGM00); // FPWM
TCCR0 |= (3 << COM00); // Set output
to high on compere match
TCCR0 |= (1 << CS00); // clk/64
}
int main(void) // Main program
{
/* Your code here */
PWM0_init();
While (1)
{
/* Your code here */
OCR0 = pwmout; // Set PWM duty cycle
/* Your code here */
}
}
Η ρουτίνα PWM0_init() είναι υπεύθυνη για το initialization του Timer, όπου ρυθμίζεται το PB3 ως
έξοδος για το PWM,
ρυθμίζεται να λειτουργεί σε FPWM κατάσταση,
κανονική λειτουργία (η έξοδος να γίνεται 1 κατά την ταύτιση) και ο χρονισμός να
είναι από το ρολόι συστήματος διαιρεμένος με το 64. Στο κυρίως πρόγραμμα
τέλος, καλείται η ρουτίνα για το initialization πριν τον κυκλικό βρόχο. Μέσα στον κυκλικό βρόχο μπορούμε να
δίνουμε τιμές στον OCR0 ώστε να μεταβάλλεται το duty cycle των
παλμών PWM.
Η λειτουργία Phase Correct PWM Mode είναι
σχεδόν ίδια με την Fast PWM με τη διαφορά ότι όταν ο TCNTn φτάσει στην ανώτερη τιμή δε
μηδενίζει, αλλά αρχίζει να μετράει αντίστροφα (ελαττώνεται) μέχρι να φτάσει στο
μηδέν όπου ξεκινάει να αυξάνει ξανά. Όταν υπάρξει ισότητα τοποθετείται (ή μηδενίζει
στην ανάστροφη λειτουργία) η OCn όταν ο TCNTn βρίσκεται στην ανοδική φάση και το αντίθετο στην
καθοδική. Η TOVn τοποθετείται
όταν κατά την ελάττωση φτάσει στο μηδέν.
Ο Timer/Counter1
διαθέτει περισσότερους τρόπους λειτουργίας από τους άλλους δύο Timers και για αυτό το λόγο ο έλεγχος γίνεται από 4 bit (WGM13:0). Επίσης,
μολονότι είναι διπλός (Α και Β) διαθέτει έναν καταχωρητή μέτρησης
TCNT1. Οι επιπλέον
τρόπου λειτουργίας εντοπίζονται κυρίως στις PWM λειτουργίες όπου ο TCNT1
αυξάνει μέχρι το Top το οποίο
μπορεί να είναι 8, 9 ή 10 bit ή
να εξαρτάται από τον OCR1A/B ή ICR1[5]. Υπάρχει
επίσης η λειτουργία Phase and Frequency Correct PWM Mode όπου η μοναδική
διαφορά της με την Phase Correct PWM Mode είναι
ότι στην πρώτη ο καταχωρητής OCR1A/B ενημερώνεται
από τον αντίστοιχο buffer όταν
ο TCNT1 βρίσκεται στο Top ενώ στη δεύτερη στο Bottom.
©2017 Πορλιδάς Δημήτριος
|