Όπως έχουμε δει στα παραδείγματα των προηγούμενων ενοτήτων, το μέγεθος της χρονικής καθυστέρησης που παράγεται, εξαρτάται από δυο παράγοντες: την συχνότητα του εσωτερικού κρυσταλλικού ταλαντωτή και την τιμή του 8bit TCNT0 καταχωρητή. Μέγιστη χρονική καθυστέρηση έχουμε όταν ο καταχωρητής TCNT0 έχει τιμή μηδέν. Τι γίνεται όμως εάν αυτό δεν είναι αρκετό; Μπορούμε να κάνουμε την κατάλληλη επιλογή prescaler στον καταχωρητή TCCR0B για να αυξήσουμε την καθυστέρηση. Η επιλογή prescaler του TCCR0B μας επιτρέπει να διαιρούμε τη συχνότητα του σήματος ρολογιού που τροφοδοτεί τον timer με ένα παράγοντα από 0 έως 1024. Ο ορισμός prescaler του Timer/Counter0 φαίνεται στο ακόλουθο σχήμα:
Παράδειγμα: Στο πρόγραμμα της προηγούμενης ενότητας, όρισε το περιεχόμενο του TCNT0 ώστε να έχουμε την μέγιστη δυνατή καθυστέρηση.
INITSTACK ; add its definition from previous example
LDI R16, (1<<3)
SBI DDRB, 3 ; PB3 as an output
LDI R17, 0
OUT PORTB, R17
BEGIN: RECALL DELAY
EOR R17, R16 ; toggle D3 of R17
OUT PORTB, R17 ; toggle PB3
RJMP BEGIN
;------------- Timer0 Delay
DELAY: LDI R20, 0x00
OUT TCNT0, R20 ; load Timer0 with zero
LDI R20, 0x00
OUT TCCR0A, R20 ; Normal mode
LDI R20, 0x01
OUT TCCR0B, R20 ; Nomal mode, int clk, no prescaler
AGAIN: SBIS TIFR0, TOV0 ; if TOV0 is set skip next instruction
RJMP AGAIN
LDI R20, 0x00
OUT TCCR0B, R20 ; stop Timer0
LDI R20, (1<<TOV0)
OUT TIFR0, R20 ; clear TOV0 flag
RET
Για να πάρουμε την μέγιστη δυνατή καθυστέρηση θέτουμε τον TCNT0 ίσο με μηδέν. Αυτό σημαίνει ότι ο timer απαριθμεί από το 00 έως το 0xFF και μετά κυλίεται στο 00 ανεβάζοντας σε 1 τη σημαία TOV0. Σαν αποτέλεσμα το σύστημα περνά συνολικά από 256 βήματα. Επομένως η χρονική καθυστέρηση είναι (256 – 0) x 0,0625μs = 16μs. Αυτό δίνει τη μικρότερη συχνότητα τετραγωνικού σήματος ίση με 1 / (2×16μs) = 1/(32μs) = 31,250KHz.
Όμως έχουμε δει μέχρι στιγμής ότι, με την επιλογή no prescaler, το σήμα του κρυσταλλικού ταλαντωτή τροφοδοτεί κατευθείαν τον Timer0. Ενεργοποιώντας τον prescaler με τα κατάλληλα bits του TCCR0B καταχωρητή, μπορούμε να διαιρέσουμε το σήμα ρολογιού προτού τροφοδοτηθεί στον Timer0. Τα χαμηλότερα 3 bits του TCCR0B, ορίζουν τον αριθμό με τον οποίο θα διαιρεθεί το σήμα ρολογιού. Όπως φαίνεται στο σχήμα, αυτός ο αριθμός μπορεί να είναι 8, 64, 256 ή 1024
Παράδειγμα: Βρες την συχνότητα και την περίοδο ρολογιού που τροφοδοτεί τον timer, για διάφορα συστήματα AVR, για τις ακόλουθες συχνότητες κρυσταλλικού ταλαντωτή. Υποθέστε ότι χρησιμοποιείται prescaler 1:64
(α) 8MHz (β)16ΜΗz (γ)10MHz
Απάντηση: (α) 1/64 x 8MHz = 125KHz λόγω prescaler και T=1/125KHz = 8μs
(β) 1/64 x 16MHz = 250KHz λόγω prescaler και T=1/250KHz = 4μs
(γ) 1/64 x 10MHz = 156,2KHz λόγω prescaler και T=1/156KHz =6,4μs
Παράδειγμα: Βρες την τιμή που πρέπει να πάρει ο TCCR0B εάν θέλουμε να προγραμματίσουμε τον Timer0 στην κατάσταση Normal με prescaler 1:64 χρησιμοποιώντας την εσωτερική πηγή ρολογιού.
Απάντηση: Από το σχήμα ορισμού των bits του TCCR0B της προηγούμενης ενότητας προκύπτει ότι: TCCR0B = 0b0000 0011 με εσωτερικό σήμα ρολογιού και prescaler 1:64
Παράδειγμα: Εξετάστε το επόμενο πρόγραμμα και βρες το μέγεθος της χρονικής καθυστέρησης που παράγεται σε δευτερόλεπτα. Υποθέστε ότι XTAL=16MHz
INITSTACK
LDI R16, (1<<3)
SBI DDRB, 3 ; PB3 as an output
LDI R17, 0
OUT PORTB, R17
BEGIN: RCALL DELAY
EOR R17, R16 ; toggle D3 of R17
OUT PORTB, R17 ; toggle PB3
RJMP BEGIN
;----------------- Timer0 Delay
DELAY: LDI R20, 0x10
OUT TCNT0, R20
LDI R20, 0x00
OUT TCCR0A, R20 ; Normal mode
LDI R20, 0x03
OUT TCCR0B, R20 ; Timer0, Normal mode, int clk, prescaler 64
AGAIN: SBIS TIFR0, TOV0 ; IF TOV0 is set skip next instruction
RJMP AGAIN
LDI R20, 0x00
OUT TCCR0B, R20 ; stop Timer0
LDI R20, 1<<TOV0
OUT TIFR0, R20
RET
Απάντηση: TCNT0=0x10 = 16 στο δεκαδικό και 256-16=240. Έχουμε 240 x 64 x 0,0625μs = 960μs
Παράδειγμα: Υποθέστε ότι XTAL = 16MHz (α) Βρες την περίοδο του σήματος ρολογιού που τροφοδοτεί τον Timer0 εάν έχουμε prescaler 1:1024 (β) Δείξτε ότι είναι το μεγαλύτερο δυνατό μέγεθος καθυστέρησης που παίρνουμε με αυτή την τιμή prescaler στον Timer0.
Απάντηση: (α) 16MHz x 1/1024 = 15625Hz λόγω του λόγου prescaler 1:1024 και T = 1/15625Hz = 64μs = 0,064ms
(β) Για να πάρουμε την μεγαλύτερη δυνατή διάρκεια καθυστέρησης, φορτώνουμε τον TCNT0 με 0. Κάνοντας τον TCNT0 μηδέν σημαίνει ότι ο timer θα απαριθμεί από 00 έως 0xFF και με την κύλιση του στο 0, η σημαία TOV0 γίνεται 1. Συνεπώς η χρονική καθυστέρηση περνά από 256 βήματα. Επομένως έχουμε καθυστέρηση ίση με (256 – 0) x 64μs = 16,384μs = 0,016384 δευτερόλεπτα.
Παράδειγμα: Υποθέστε ότι έχουμε XTAL = 16MHz. Γράψτε ένα πρόγραμμα που να παράγει μια τετραγωνική κυματομορφή συχνότητας 250Ηz στο pin PORTB.3 Χρησιμοποιείστε Timer0, Normal mode, prescaler=256
Απάντηση: Ακολουθούμε τα ακόλουθα βήματα:
(α) Τ=1/250Ηz = 4ms είναι η περίοδος του τετραγωνικού σήματος
(β) ½ από αυτό δηλ. 2ms είναι η διάρκεια κάθε τμήματος high και low του σήματος
(γ) (2ms / 0,0625μs) / 256 = 125 και 256 – 125 = 131 στο δεκαδικό και 0x83 στο δεκαεξαδικό
(δ) TCNT0 = 0x83
.MACRO INITSTACK ; set up stack
LDI R20, HIGH(RAMEND)
OUT SPH, R20
LDI R20, LOW(RAMEND)
OUT SPL, R20
.ENDMACRO
INITSTACK
LDI R16, (1<<3)
SBI DDRB, 3 ; PB3 as an output
LDI R17, 0
BEGIN: OUT PORTB, R17 ; PORTB = R17
CALL DELAY
EOR R17, R16 ; toggle D3 of R17
RJMP BEGIN
;-------------------- Timer0 Delay
DELAY : LDI R20, 0x83
OUT TCNT0, R20 ; load Timer0
LDI R20, 0x00
OUT TCCR0A, R20 ; Normal mode
LDI R20, 0x04
OUT TCCR0B, R20 ; Normal mode, int clk, prescaler = 256
AGAIN: SBIS TIFR0, TOV0 ; if TOV0 is set skip next instruction
RJMP AGAIN
LDI R20, 0x00
OUT TCCR0B, R20 ; stop Timer0
LDI R20, 1<<TOV0
OUT TIFR0, R20 ; clear TOV0 flag
RET
Assemblers και αρνητικές τιμές
Επειδή ο Timer0 λειτουργεί σε κατάσταση 8bit μπορούμε να αφήσουμε τον Assembler να υπολογίσει την τιμή για τον TCNT0. Για παράδειγμα με την εντολή «LDI R20, -100» ο Assembler θα υπολογίσει -100=9C και θα θέσει R20=9C στο δεκαεξαδικό. Με τον τρόπο αυτό έχουμε μεγάλη ευκολία.
Παράδειγμα: Βρες τις τιμές (στο δεκαεξαδικό) που πρέπει να φορτώσουμε στον TCNT0 σε κάθε μια από τις ακόλουθες περιπτώσεις:
(α) LDI R20, -200
OUT TCNT0, R20
(β) LDI R17, -60
OUT TCNT0, R17
(γ) LDI R25, -12
OUT TCNT0, R25
Απάντηση: Μπορούμε να χρησιμοποιήσουμε το επιστημονικό κομπιουτεράκι των Windows για να επαληθεύσουμε τα αποτελέσματα που δίνει ο Assembler. Στο κομπιουτεράκι των Windows επιλέγουμε decimal και πληκτρολογούμε 200. Μετά επιλέγουμε hex και μετά +/- για να πάρουμε την αρνητική τιμή. Παίρνουμε τα ακόλουθα αποτελέσματα:
Decimal 2's complement(TCNT0 value)
-200 0x38
-60 0xC4
-12 0xF4
Παράδειγμα: Βρες (α) τη συχνότητα του τετραγωνικού σήματος που παράγεται από τον ακόλουθο κώδικα και (β) το duty cycle αυτού του τετραγωνικού σήματος. Υποθέστε: XTAL= 16MHz
LDI R16, HIGH(RAMEND)
OUT SPH, R16
LDI R16, LOW(RAMEND)
OUT SPL, R16
SBI DDRB, 5 ; PB5 as an output
LDI R18, -150
BEGIN: SBI PORTB, 5 ; PB5 = 1
OUT TCNT0, R18 ; load Timer0 byte
CALL DELAY
OUT TCNT0, R18 ; reload Timer0 byte
CALL DELAY
CBI PORTB, 5 ; PB5=0
OUT TCNT0, R18 ; reload Timer0 byte
CALL DELAY
RJMP BEGIN
;---------- Delay using Timer0
DELAY: LDI R20, 0x00
OUT TCCR0A, R20 ; Normal mode
LDI R20, 0x01
OUT TCCR0B, R20 ; start Timer0, Normal mode, int clk, no prescaler
AGAIN: SBIS TIFR0, TOV0
RJMP AGAIN
LDI R20, 0x00
OUT TCCR0B, R20 ; stop Timer0
LDI R20, 1<<TOV0
OUT TIFR0, R20 ; clear TOV0 flag bit
RET
Απάντηση: Για τον TCNT0 σε κατάσταση λειτουργίας 8bit, η μετατροπή γίνεται από τον Assembler, εφόσον έχουμε εισάγει στην εντολή αρνητικό αριθμό. Αυτό κάνει τον υπολογισμό εύκολο. Επειδή χρησιμοποιούμε 150 κύκλους ρολογιού έχουμε για την χρονική καθυστέρηση στην DELAY ρουτίνα: 150 x 0,0625μs = 9,375μs. Το high τμήμα του τετραγωνικού σήματος είναι διπλάσιο από το low τμήμα (66% duty cycle). Επομένως έχουμε Τ=high portion + low portion = 2 x 9,375μs + 9,375μs = 28,125μs και συχνότητα F = 1/28,125μs = 35,555kHz