Forum: Compiler & IDEs Timer1 Problem mit ATMEGA1280


von Bene J. (terfagter)


Lesenswert?

Hallo zusammen,

versuche seit Stunden Timer1 im Compare-Betrieb laufen zu lassen, sodass 
ein Interrupt alle 1ms ausgelöst wird.
Mein Programm unterbricht beim Initialisieren des Timers schon alles und 
führt nichts weiter aus!
In die Interrupt-Routine zählt ich bis zu einer Sekunde hoch und gebe 
einen STring aus. Das ist später nicht die Aufgabe der Routine, sondern 
gerade nur zum testen.
Quarz: 8000000

Was mache ich falsch?

Mein Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
#include <stdio.h>
5
#include <avr/pgmspace.h>
6
#include <string.h>
7
#include <stdlib.h>
8
9
#include "main.h"
10
11
uint8_t mssec = 0;
12
  
13
int main (void) 
14
{
15
  
16
  init_uart0( (u16)(XTAL / BAUD0 / 16 - 0.5) );      
17
18
  TIMSK1 |= (1<<OCIE1A);
19
  
20
  OCR1A = 124;
21
  TCNT1 = 0;                        
22
  
23
  TCCR1A |= (1 << WGM12);
24
  TCCR1B |= (1<<CS11) | (1<<CS10);
25
  sei();  
26
  while(1){}
27
}
28
29
30
ISR(TIMER1_COMPA_vect)
31
{
32
  mssec++;
33
  if(mssec == 1000)
34
  {
35
    mssec = 0;
36
    uputs0("1 sec vergangen");
37
  }
38
}

Vielen Dank für eure Hilfe!

von Helfer (Gast)


Lesenswert?

> Mein Programm unterbricht beim Initialisieren des Timers schon alles und
> führt nichts weiter aus!

Bug in (Endlosschleife?) oder beim Rücksprung (Stack falsch 
initialisiert? falscher AVR im Projekt eingestellt?) aus der nicht 
gezeigten Funktion init_uart0()?

Hardwareprobleme beim RS232 Transfer AVR <-> PC? Funktioniert UART im 
Hello World Programm?

> ISR(TIMER1_COMPA_vect)
>     uputs0("1 sec vergangen");

Angenommen die Interrupts kommen alle ms. Wie viele Interrupts verlierst 
du durch uputs0() bei Baudrate BAUD0? Funktioniert das Toggeln einer LED 
alle Sekunde in der ISR?

>  TCCR1A |= (1 << WGM12);
>  TCCR1B |= (1<<CS11) | (1<<CS10);

CTC1 Modus OK. Prescaler 64. 8000000/64/(124+1) = 1ms OK.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR

von Bene J. (terfagter)


Lesenswert?

Also die uart Initialisierung funktioniert mit 9600 baud. Ohne die 
Initialisierung des timers läuft das Programm auch durch, wenn ich z.b. 
über die uart einen String ausgeben...

von Stefan E. (sternst)


Lesenswert?

Welchen UART-Code verwendest du?

von Bene J. (terfagter)


Lesenswert?

Von Peter danegger. interrupt gesteuert.

von Fabian G. (kjion) Benutzerseite


Lesenswert?

Hi,
1
uint8_t mssec = 0;
2
...  
3
if(mssec == 1000)

das kann so nicht funktionieren und dein Compiler sollte dir auch eine 
entsprechende Warnung ausgeben. uint8_t kann maximal bis 255 zählen.

Besser:
1
ISR(TIMER1_COMPA_vect)
2
{
3
  static uint16_t mssec = 0;
4
  
5
  mssec++;
6
  if(mssec == 1000)
7
  {
8
    mssec = 0;
9
    uputs0("1 sec vergangen");
10
  }
11
}

von Stefan E. (sternst)


Lesenswert?

Bene Jan schrieb:
> Von Peter danegger. interrupt gesteuert.

Und du meinst, es wäre dann eine gute Idee, die Funktion uputs0 an einer 
Stelle aufzurufen, wo Interrupts gerade abgeschaltet sind? Wenn der 
Puffer nicht mehr den kompletten String aufnehmen kann, hast du einen 
schönen Dead-Lock.

von Bene J. (terfagter)


Lesenswert?

Vielen Dank.
Es lag an zwei Sachen:
1. habe ich mich im Datenblatt verguckt und WGM12 in TCCR1A benutzt 
anstall in TCCR1B
2. In der Interrupt-Schleife uputs0 verwendet, was bei mir Interrupt 
gesteuert ist. Da gab es dann einen Dead-Lock.
Jetzt funktionierts.

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.