www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer 0 mi ATmega8


Autor: Birgit (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
ISR(VEKTORNAME_vect)
{
    //Hier Code einfügen
}
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
TCCR0 = TCCR0 | 0x01;
kürzer als
TCCR0 |= 0x01;
schreiben.

Autor: johnny.m (Gast)
Datum:

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

Autor: Basti (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)
{...

Autor: Berge (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
ISR (TIMER0_OVF_vect){  //timer0 overflow vector
  PORTC |= (1<<PC1);
}

int main(void){
  DDRC |= (1 << DDC1);  //Set direction register for pc1
  PORTC = 0x00;  //set outputs initially to zero

  //Timer initialization
  TIMSK = (1<<TOIE0);  //Timer overflow Interrupt enable
  TCCR0 |= (1<<CS00) | (1<<CS02);  //prescaler set to 1024
  TCNT0 = 0;  //startvalue for timer

  sei();  //activate interrupts
  
  while(1){
  }
  return 0;
}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Berge (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h> //used for register/io access
#include <avr/interrupt.h>

ISR (TIMER0_OVF_vect){  //timer0 overflow vector
  PORTC |= (1<<PC1);
}

int main(void){
  DDRC |= (1 << DDC1);  //Set direction register for pc1
  PORTC = 0x00;  //set outputs initially to zero

  //Timer initialization
  TIMSK = (1<<TOIE0);  //Timer overflow Interrupt enable
  TCCR0 |= (1<<CS00) | (1<<CS02);  //prescaler set to 1024
  TCNT0 = 0;  //startvalue for timer

  sei();  //activate interrupts
  
  //PORTC |= (1<<PC1);  LEDtest
  while(1){
  }
  return 0;
}

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

Autor: Werner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probier mal den Ausgang toggeln zu lassen.
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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Makefile/AVRStudio richtigen Controllertyp eingestellt?

Autor: Berge (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.