Ich hab zwei kleine Fragen zum Compare-Match-Interrupt des
Hi-Speed-Timers 4 (mit dem Overflow-Interrupt sieht es übrigens genauso
aus) und zwar hab ich da heute den ganzen Tag probiert aber es klappt
nicht wie ich mir das vorstelle (und mit Datenblatt/Google bin ich auch
nicht weiter gekommen). Unten seht ihr mein Programm, ich benutze als
Testboard ein Arduino Leonardo. Fuses sind wie beim Leonardo-Board
eingestellt. PWM klappt übrigens hervorragend, daher weiß ich, dass der
Timer zumindest läuft (beachte 2. Frage).
1. Anhand meines Tests weiß ich, dass die ISR nicht angesprungen wird
denn PB5 toggelt nicht so wie ich will (mit 50 kHz), aber was habe ich
hier vergessen zu konfigurieren? Es geht mir hierbei nicht darum einen
OC4x-Pin anzusteuern.
2. Die while-Schleife, in der ich das PLOCK Polle (soll man lt.
Datenblatt) funktioniert auch nicht (egal ob auf 1 oder 0 geprüft).
Nehme ich, wie es unten steht, die Zeile 27 rein bleibt das Programm da
hängen. Kommentiere ich es aus, dann läuft auch das Programm weiter.
Verstehe ich irgendwie auch nicht wirklich. Sieht jemand was da das
Problem ist?
Es sind wahrscheinlich völlig lächerliche Probleme aber ich hab nen
Knoten im Kopf und sehe das Problem nicht. Das Programm unten liefert
mir ein ca. 800 Hz Signal, sollte so aber eigentlich ein 50 kHz Signal
generieren.
1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 |
|
4 | void setCompareValue(uint8_t compareValue){
|
5 | uint8_t sreg = SREG;
|
6 | cli();
|
7 | TC4H = (compareValue >> 8);
|
8 | OCR4A = (compareValue & 0xff);
|
9 | SREG = sreg;
|
10 | }
|
11 |
|
12 | void main(void){
|
13 | // Testpin sei PB5
|
14 | DDRB |= (1 << PB5);
|
15 |
|
16 | //PLL einstellen
|
17 | // uC laeuft mit 16MHz, PINDIV daher setzen (Kapitel 6.11.5)
|
18 | PLLCSR = (1 << PINDIV);
|
19 |
|
20 | // PLL fuer Timer einstellen (Kapitel 15.3.1)
|
21 | // Enable PLL
|
22 | PLLCSR = (1 << PLLE);
|
23 | // wait 100us for stabilize PLL
|
24 | _delay_us(100);
|
25 | // pull PLOCK-Bit until it is set
|
26 | while( !(PLLCSR & (1 << PLOCK)) );
|
27 | // Postscaler auf 1, PLL fuer 72 MHz konfigurieren
|
28 | PLLFRQ |= (1 << PLLTM0)|(1 << PDIV2)|(1 << PDIV1)|(1 << PDIV0);
|
29 |
|
30 | // Timer einstellen
|
31 | // TOP-Value Timer einstellen
|
32 | TC4H = 720 >> 8;
|
33 | OCR4C = 720 & 0xff;
|
34 | // Compare-Value einstellen
|
35 | setCompareValue( 0x32 );
|
36 | // Compare Match Interrupt einschalten
|
37 | TIMSK4 = (1 << OCIE4A);
|
38 | // Timer starten
|
39 | TCCR4B = (1 << CS40);
|
40 | // Interrupts einschalten
|
41 | sei();
|
42 |
|
43 | for(;;){
|
44 | // nix zu tun, Test HS-Timer-ISRs
|
45 | }
|
46 | }
|
47 |
|
48 | ISR(TIMER4_COMPA_vect){
|
49 | PORTB ^= (1 << PB5);
|
50 | }
|