ISBN-numren du fick, så är nog inte Grattes bok förstahandsvalet.
Jag ska försöka förklara koden i det förra inlägget med hänvisning till
AtMega328 datasheetVi börjar med funktionen initTimer1()
För
timer finns tre kontrolregister
Timer/
Counter
Control
Register, för timer1 heter dom TCCR1A, TCCR1B, TCCR1C. Dessa är kan man säga är ställen i processorn där man ställer in hur timern ska bete sig. För timer1 finns detta beskrivet i databladet på sidan 131.
Vi har också TCNT1 som är själva räknaren, det är den här som stegas.
TIMSK1, där ställer vi in hur den ska bete sig avseende på interrupt, beskrivet med början på sidan 135.
- Kod: Markera allt
TCCR1A = 0; // Clear TCCR1A
TCCR1B = 0; // Clear TCCR1B
TCCR1C = 0; // Clear TCCR1C
TCNT1 = 0; // Clear the timer
TIMSK1 = 0; // Clear the interrupt mask
Inte så mycket förklaring, men allt rensas.
- Kod: Markera allt
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt channel A:
TIMSK1 |= (1 << OCIE1B); // enable timer compare interrupt channel B:
Vi kika på sidan 135:
Här kan 4 bitar användas, 0, 1, 2 och 5. Bitar i ett register räknas från 0 och uppåt, i det här fallet till 7 (som är den 8:de biten). Bitarnas värde är 2 upphöjt till bitnummer.
2 upphöjt till 0 är 1, 2 upphöjt till 1 är 2, 2 upphöjt till 2 är 4, 2 upphöjt till 3 är 8, 2 upphöjt till 4 är 16, 2 upphöjt till 5 är 32, 2 upphöjt till 6 är 64 och 2 upphöjt till 7 är 128.
Ett annat sätt att upphöja 2 till något är att shifta, dvs flytta en bit ett antal gånger åt vänster.
(1 << 0) = 1 (första biten, bit 0, sätts)
(1 << 1) = 1 (andra biten, bit 1, sätts) osv.
Nu har dom som har gjort stödet för Atmega328 så smarta att bitarna har fått följande namn: ICIE1, OCIE1B, OCIE1A och TOIE1.
Dessa är definierade som:
ICIE1 =5
OCIE1B = 2
OCIE1A =1
TOIE1 = 0
så
- Kod: Markera allt
(1 << OCIE1A) blir 2, (1 << 1)
(1 << OCIE1B) blir 4, (1 << 2)
- Kod: Markera allt
TIMSK1 |= (1 << OCIE1A);
kan skrivas som
TIMSK1 = TIMSK1 | (1 << OCIE1A); // | är bitvis eller
|, bitvis eller, ger följande 1 eller 1 är 1, 1 eller 0 är 1 samt 0 eller 0 är 0. bitvi är för varje bit i talet, i det här fallet registret.
så
- Kod: Markera allt
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt channel A:
// TIMSK1 är ju 0
//TIMSK1 = B00000000 | B00000010, TIMSK1 = B00000010
TIMSK1 |= (1 << OCIE1B); // enable timer compare interrupt channel B:
// //TIMSK1 = B00000010 | B00000100, TIMSK1 = B00000110
Skulle kunna skrivas som
- Kod: Markera allt
TIMSK1 |= ((1 << OCIE1A) | (1 << OCIE1B));
Sedan har vi
- Kod: Markera allt
TCCR1A = B11110000; // Set OC1A/OC1B on Compare Match, clear OC1A/OC1B at BOTTOM
Här sätts bitarna utan beskriva vad de är, skulle kunna skrivas som följand:
- Kod: Markera allt
TCCR1A = ((1 << COM1A1) | (1 << COM1A0) | (1 << COM1B1) | (1 << COM1B0));
// se sidan 131
Blev det klarare, eller rör jag till det?