Mal wieder Timer (Forum-Suche nicht Lösungsgleich!)

Gast #1142279
Lesenswert?

Hallo Mikrocontroller-Gemeinde,

ich bin gerade auf der Suche nach einem vermutlich banalen Fehler. GGf. 
könnt ihr mir ja weiter helfen. Ich versuche derweil für eine weitere 
Funktion einen Timer einzubinden. Hierzu gebe ich zum testen eine LED 
zum Blinken am PORTC aus. Der Code sieht aus wie folgt:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3

4
#define QRGFREQ 8    //Angabe in Mhz
5
#define IRQT 100    // IRQ in t=x sec. (IRQTIME *10ms) (also eig. 1s!)
6

7

8
volatile unsigned int get_ADC =1,tenhsec=0;    
9

10
void main(void)
11
{
12

13
DDRC = 0xFF,
14
PORTC = 0xff;
15
// initialisation of timer and interrupts
16

17

18
TCCR1A = 0;  //Timer innerhalb des uC, keine externe Hardware
19

20

21
TCCR1B =0x01;   // Kein Prescaler  (Freq/1)
22

23
//Vergleichswert
24
OCR1AH = (QRGFREQ *1000) >>8;    // 10ms
25
OCR1AL = (QRGFREQ *1000) & 0xff;  // 10ms
26

27

28
// IRQ Enable
29
TIMSK1  = (1<<OCIE1A);//|(1<<TOIE3);
30

31
//Global freigeben
32
sei();    
33
  while(1)
34
    {
35
    
36
    }
37
}
38

39
//-------------------------------------------------------
40
ISR (TIMER1_COMPA_vect) 
41
{//Jede 10ms aufgerufen
42

43
tenhsec++;
44
if (tenhsec ==IRQT) 
45
  {tenhsec =0;
46
  get_ADC ^= 1;
47
  PORTC = get_ADC;
48
  }
49
}

Eigentlich sollte ja nach 1s der CompareValue erreicht sein und die LED 
entsprechend blinken. Dies macht sie ja auch! Allerdings ändere ich den

//Vergleichswert
OCR1AH = (QRGFREQ *1000) >>8;    // 10ms
OCR1AL = (QRGFREQ *1000) & 0xff;  // 10ms

auf andere Werte so ergibt sich die gleiche Geschwindigkeit des Taktes 
der LED. Das heißt also, dass der Compare-Wert woandersraus gebildet 
wird?
(Forum etc schon nachgestöbert!)

Ggf. banale Lösung ??

Danke schonmal
#1142285
Lesenswert?

Diplomand_A wrote:

> auf andere Werte so ergibt sich die gleiche Geschwindigkeit des Taktes
> der LED.

Das wundert mich nicht weiter.
Du hast keinen Timer Modus eingestellt. Das bedeutet so viel wie der 
Timer zählt munter vor sich hin. Immer von 0 bis 65536

Das eine mal kriegst du halt deinen Interrupt, wenn der Timer bei 300 
angelangt ist, das andere mal kriegst du ihn wenn er bei 28000 angelangt 
ist. Aber immer noch braucht der Timer exakt 65536 Zyklen bis er die 300 
bis 28000 das nächste mal wieder erreicht.

Nur weil du den OCIE1A Interrupt eingeschaltet hast, fängt der Timer ja 
nicht beim Auslösen des Interrupts wieder bei 0 an zu zählen. Der 
Interrupt macht genau das was er aussagt: Eine Information darüber, dass 
der Zählerstand einen bestimmten Wert erreicht hat. Nicht mehr und nicht 
weniger. Und wenn du sonst nichts tust, dann dauert es genau 65536 
Timerticks bis dieser Wert wieder erreicht wird.
#1142289
Lesenswert?

Übrigens kann man in C sehr komfortabel auf 16-Bit-I/O-Register als 
ganzes zugreifen, ohne den ganzen Rotz mit (z.B.) OCR1AH und OCR1AL und 
Bitgeschiebe. Schreib einfach den Wert in OCR1A und sei glücklich, dass 
der Compiler sich höchstselbst um die Zugriffsreihenfolge und das 
Bitgepfriemel kümmert.
Gast #1143016
Lesenswert?

Hallo Jungs,

ich danke auch bestens für die Antwort von allen :-)

der Vollständigkeithalber für ggf. weiter hilfesuchende Personen:
1
TCCR1B =(1<<CS10)|(1<<WGM12);

Manchmal kann es so einfach sein :-)

gruß

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren