Forum: Mikrocontroller und Digitale Elektronik Timer 0 mi ATmega8


von Birgit (Gast)


Lesenswert?

Hallo ihr!
Bin gerade dabei, mir mittels einigen Testprogrammen den µC ein wenig 
kennenzulernen. Gerade eben möchte ich einfach nur eine LED zum blinken 
bringen, um die Timer-Funktion auszuprobieren. Beim 8051er macht man das 
wie folgt:

#include <AT89X52.H>

sbit LED = P1^0;

void InitTimer0 (void)
{
 IE = IE | 0x82;

 TMOD = TMOD | 0x01; //Timer0 einschalten (16Bit)

 TL0 = 0x3C;
 TH0 = 0xB0;
 TR0 = 1;

}

void ISR_Timer0(void) interrupt 1
{
  int ueberlauf;
  ueberlauf++;

  if(ueberlauf == 10)
  {
   LED = ~LED;
  //LED != LED; --> Osterer
  //P1_0 = ~P1_0;
    ueberlauf = 0;
  }

  //Startwert des Timers setzen
  TL0 = 0x3C;
  TH0 = 0xB0;
}



void main (void)
{
 InitTimer0();
 while(1)
  {}
}


Wie werden aber die Register bei einem ATmega8 gesetzt? Folgendes hab 
ich ausprobiert:


#include <avr/io.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>


void InitTimer0 (void)
{

 SREG = SREG |0x80;
 TCCR0 = TCCR0 | 0x01; //
 TIMSK = TIMSK | 0x01;

}


void ISR_Timer0(void) interrupt 10
{
 // noch nix da
}



void main (void)
{
 InitTimer0();
 while(1);
}


Mit der Bitte um Hilfe
LG Birgit

von johnny.m (Gast)


Lesenswert?

> void ISR_Timer0(void) interrupt 10
Wenn Du mit dem WINAVR-Compiler arbeitest (was ich anhand der #includes 
mal vermute), dann geht das so nicht. Eine ISR wird in WINAVR-C mit
1
ISR(VEKTORNAME_vect)
2
{
3
    //Hier Code einfügen
4
}
geschrieben.

BTW:
Für "SREG = SREG |0x80;" gibt es die Pseudo-Funktion "sei()", die man 
der Übersicht halber auch verwenden sollte.

Generell kann man Sachen wie
1
TCCR0 = TCCR0 | 0x01;
kürzer als
1
TCCR0 |= 0x01;
schreiben.

von johnny.m (Gast)


Lesenswert?

Ach ja, und Sachen wie
1
TCCR0 |= 0x01;
sind nicht sehr aussagekräftig. Verwende dabei bitte die Schreibweise 
mit den Bitnamen, also z.B.
1
TCCR0 |= 1 << CS00;
Sonst kann das Programm hinterher kein Schwein lesen.

von Basti (Gast)


Lesenswert?

ISR(TIMER0_OVF_vect)
{

};



int main (void)

//Timer0 Einstellungen
TCCR0 |= (1<<CS00) | (1<<CS01);  //Timer Prescaler auf /64
TIMSK |= (1<<TOIE0);    //Timer0_Overflow Interrupt aktivieren
TCNT0 = 0;                  //Timerstartwert

sei();   //Interrupts global aktivieren


while(1)
{...

von Berge (Gast)


Lesenswert?

Hallo zusammen!

Ich hänge mich mal hier ran, da ich auch ein Problem mit den Atmega8 
Timer0 habe (naja, wahrscheinlich eher der Timer mit mir ;)

Und zwar habe ich ein kleines Programm geschrieben das erstmal nur eine 
LED zum blinken bringen sollte, leider bisher ohne Erfolg. Daher habe 
ich die ISR erstmal dadurch ersetzt, dass die LED überhaupt einmal 
leuchten soll, um zu überprüfen ob die ISR angesprungen wird. Leider 
auch hier tote Hose. Schreibe ich die Anweisung die LED zu aktivieren 
vor oder in die while Schleife, leuchtet die LED, das Programm läuft 
also bis dahin.

Ich denke ich mache irgendwas bei der Timer Initialisierung falsch oder 
bei der Interruptabarbeitung. Jedenfalls brachte es mich auch nicht 
weiter, als ich das Overflowflag des Timers0 manuell mal auf 1 gesetzt 
habe.

Ich hoffe ihr habt eine Idee!

Liebe Grüße,

Jan
1
ISR (TIMER0_OVF_vect){  //timer0 overflow vector
2
  PORTC |= (1<<PC1);
3
}
4
5
int main(void){
6
  DDRC |= (1 << DDC1);  //Set direction register for pc1
7
  PORTC = 0x00;  //set outputs initially to zero
8
9
  //Timer initialization
10
  TIMSK = (1<<TOIE0);  //Timer overflow Interrupt enable
11
  TCCR0 |= (1<<CS00) | (1<<CS02);  //prescaler set to 1024
12
  TCNT0 = 0;  //startvalue for timer
13
14
  sei();  //activate interrupts
15
  
16
  while(1){
17
  }
18
  return 0;
19
}

von Johannes M. (johnny-m)


Lesenswert?

@Berge:
Zeig mal das vollständige Programm. Interrupt-Flags kann man übrigens 
nicht "manuell" setzen. Abgesehen davon: Sicher, dass die LED gegen 
Masse angeschlossen ist? Ansonsten schaltest Du sie mit "PORTC |= 
(1<<PC1);" nämlich aus und nicht ein. Hast Du alle erforderlichen Header 
eingebunden?

Und nächstes Mal machste bitte nen neuen Thread auf, anstatt einen 
Uralt-Thread wieder rauszukramen. Sonst kommen wieder reihenweise Leute 
auf die Idee, ihren Senf zum Ursprungs-Posting dazuzugeben, weil sie 
nicht aufs Datum schauen.

von Berge (Gast)


Lesenswert?

Lieben Dank für die Antwort, ich werde nächstes Mal einen neuen Thread 
öffnen.
Die LED ist definitiv gegen Masse verschaltet, wie gesagt, wenn ich sie 
sonst mit PORTC |= (1<<PC1) befeuere, leuchtet sie. Ich hatte den 
Quellcode ein wenig beschnitten (unnötige Kommentare etc entfernt) aber 
jetzt verwende ich genau den hier:
1
#include <avr/io.h> //used for register/io access
2
#include <avr/interrupt.h>
3
4
ISR (TIMER0_OVF_vect){  //timer0 overflow vector
5
  PORTC |= (1<<PC1);
6
}
7
8
int main(void){
9
  DDRC |= (1 << DDC1);  //Set direction register for pc1
10
  PORTC = 0x00;  //set outputs initially to zero
11
12
  //Timer initialization
13
  TIMSK = (1<<TOIE0);  //Timer overflow Interrupt enable
14
  TCCR0 |= (1<<CS00) | (1<<CS02);  //prescaler set to 1024
15
  TCNT0 = 0;  //startvalue for timer
16
17
  sei();  //activate interrupts
18
  
19
  //PORTC |= (1<<PC1);  LEDtest
20
  while(1){
21
  }
22
  return 0;
23
}

Die Stelle LEDtest habe ich auskommentiert, damit leuchtet die LED 
problemlos, leider nicht in der ISR.

von Werner (Gast)


Lesenswert?

Probier mal den Ausgang toggeln zu lassen.
1
PORTC ^= (1<<PC1);

Zusätzlich kannst du im der main ja mal den nächsten portpin wackeln 
lassen.
dann weist du schonmal dass überhaupt was läuft.

von Johannes M. (johnny-m)


Lesenswert?

Im Makefile/AVRStudio richtigen Controllertyp eingestellt?

von Berge (Gast)


Lesenswert?

Das Toggeln habe ich ausprobiert, funktoniert ausserhalb der ISR, 
innerhalb leider nicht. Einen anderen Pin nutzen kann ich zwar, dafür 
müßte ich meinen doch recht rudimentären Versuchsaufbau aber erweitern.

Ich nutze das AVR Studio und dort habe ich den Atmega8 auch eingestellt, 
ein Blick auf den avr-gcc Aufruf offenbar mir auch, dass er mit der 
Option -mmcu=atmega8 aufgerufen wird. Scheint also ok zu sein.

Gerade ist mir allerdings etwas elektrisch doch recht seltsames 
aufgefallen, ich werde da mal nachforschen müssen. Vielleicht machts 
auch Sinn direkt ein Testboard zu bauen, mal schauen wozu ich heute 
Abend Zeit finde.

Danke schonmal für eure Antworten!

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.