Forum: Mikrocontroller und Digitale Elektronik 16 bit Timer atmega8


von Bert S. (kautschuck)


Lesenswert?

Hi,
ich versuche den 16bit Timer des atmega8 (8Mhz) zu benützen. Der Timer 
läuft, aber gibt mir nicht die richtige Zeit an. Ich wollte mit dem 
prescaler 1024 1 Sekunde Warten. Meine Rechnung ist also:

1s/(1024/8Mhz) = 7812 = 0x1E84

Doch die Wartezeit beträgt in etwa 8 Sekunden. Der atmega8 läuft 
garantiert auf den 8Mhz, sonst würde ja der USART nicht funktionieren.

Doch ich sehe nicht ein, was ich da falsch überlegt habe?

Gruss Bert
1
/*
2
 * _16bit_Timer.c
3
 *
4
 * Created: 15.05.2015 18:28:51
5
 *  Author: Sebi
6
 */ 
7
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
#include <avr/delay.h>
12
 
13
#define F_CPU 8000000UL
14
#define BAUD 9600UL
15
#define MYUBRR ((F_CPU+BAUD*8)/(BAUD*16)-1)
16
17
#define TIMER1_COMPA_vect _VECTOR(6)
18
19
ISR(TIMER1_COMPA_vect) {
20
  USART_Transmit('x');
21
}
22
23
void init();
24
void USART_Init( unsigned int ubrr);
25
void USART_Transmit(unsigned char data);
26
27
int main(void)
28
{
29
  init();
30
    while(1)
31
    {
32
    
33
    }
34
}
35
36
void init() {
37
  TIMSK |= (1<<OCIE1A);
38
  TCCR1B |= (1<<CS12) + (1<<CS10); 
39
  OCR1AH = 0x1E;
40
  OCR1AL = 0x84;
41
  sei();
42
  USART_Init(MYUBRR);
43
  
44
}
45
46
void USART_Init( unsigned int ubrr)
47
{
48
49
  UBRRH = MYUBRR >> 8;
50
  UBRRL = MYUBRR & 0xFF;
51
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
52
  UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
53
  
54
  sei();
55
}
56
57
58
void USART_Transmit( unsigned char data )
59
{
60
  while ( !( UCSRA & (1<<UDRE)) );
61
  UDR = data;
62
}

von container (Gast)


Lesenswert?

Bert Siegfried schrieb:
> Doch die Wartezeit beträgt in etwa 8 Sekunden. Der atmega8 läuft
> garantiert auf den 8Mhz, sonst würde ja der USART nicht funktionieren.

Welche Wartezeit. Nachdem der Timer1 losgelaufen ist, dauert es eine 
Sekunde bis zum CompareA Interrupt danach immer 8 Sekunden bis zu 
weiteren CompareA Interrupts - soweit ich das sehe.

von Bert S. (kautschuck)


Lesenswert?

Ja, genau so. Wo genau siehst du das? Wird etwa das OCR1A gelöscht?

Gruss Bert

von container (Gast)


Lesenswert?

Bert Siegfried schrieb:
> void init() {
>   TIMSK |= (1<<OCIE1A);
>   TCCR1B |= (1<<CS12) + (1<<CS10);
>   OCR1AH = 0x1E;
>   OCR1AL = 0x84;

Der Timer1 läuft hiermit immer von 0 bis 65536 und fängt wieder von 0 
an. Der erste CompareA Interrupt tritt bei TCNT1-Stand auf, der in OCR1A 
abgelegt ist. Der Timer1 läuft aber weiter und braucht nun etwas mehr 
als 8 Sekungden bis er einmal rum ist.

Du müßtest den CTC Modus einstellen, damit der Timer nach erreichen von 
OCR1A wieder bei 0 anfängt und nicht erst bis 65536  läuft bis er wieder 
bei 0 beginnt.

von Bert S. (kautschuck)


Lesenswert?

Super, klappt wunderbar.
Vielen Dank

Gruss Bert

von spess53 (Gast)


Lesenswert?

Hi

>Super, klappt wunderbar.
>Vielen Dank

Na ja, der korrekte Comparewert ist aber $1E83.

MfG spess

von Bert S. (kautschuck)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Super, klappt wunderbar.
>>Vielen Dank
>
> Na ja, der korrekte Comparewert ist aber $1E83.
>
> MfG spess


Nein, 7812.5 ist in Hex eher 0x1E85, da aber der Fehler für 0x1E84 
gleich gross ist, ist es egal, was man nimmt.

von Uwe (de0508)


Lesenswert?

Hallo,

spess53 wollte Dur nur mitteilen, das in deiner Rechnung ein -1 aus den 
ersten Beitrag fehlt!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.