PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu verwendung von Timern



Henry
15.02.2007, 20:41
Hallo,

ich bekomme es einfach nicht hin mit den Timern und nun suche ich bei euch Hilfe

Ich habe versucht mit Hilfe des AVR-GCC Tut von Mikrocontroller.net einen Timer zum laufen zu bekommen, nur leider mache ich scheinbar irgendetwas falsch.
Mit C kenne ich mich leider nicht so richtig aus, den ich programmiere meine kleinen PC-Progrämmchen mit Delphi (also Pascal). Meine ATMega möchte ich in C programmieren, da es da mir das sehr verbreitet scheint.

Mein Testobjekt ist ein ATMega16 und mein Versuch sieht wie folgt aus:

Timer Aktivieren:


void init_timer()
{
TCCR0 = (1<<CS00) | (0<<CS01) | (1<<CS02);
}


Versuch einen Ausgang zum blinken zu bewegen:


#include <avr/io.h>
#include "inttypes.h"


int main()
{
int32_t Zaehler = 0;


init_digital(); //Ports als Ausgänge schalten
init_timer(); //Timer Aktivieren

while(1)
{

if (TCNT0 == 100)
{
Zaehler++;
PORTB = (0<<PB2);
}

if (Zaehler == 1020)
{
Zaehler = 0;
PORTB = (0<<PB2);
}


if (Zaehler == 250)
{
PORTB = (0<<PB0);
}


if (Zaehler == 1000)
{
PORTB = (1<<PB0);
}

} //while

} //main


Bin wie gesagt noch etwas auf Kriegsfuß mit C, daher bitte nicht über den Code wundern. Der ist mit sicherheit alles andere als Professionell und scheinbar ja auch falsch ;)

Könnt Ihr mir evt. sagen was ich da für einen Denkfehler mache?

Danke schon einmal vorab

uwegw
15.02.2007, 20:57
Du fragst ja mit if (TCNT0 == 100) ständig ab, ob das Zählregister eine gewissen Wert enthält. Das ist probelmatisch, weil dessen Wert sich ja ständig ändert. Nun kann es passieren, dass der AVR gerade irgendwo im Rest des Programms hängt, und währenddessen zählt der Timer ...99, 100, 101,... . Und schon ist dir ein Impuls durch die Lappen gegangen. Zuverlässiger funktionieren tut es, wenn du auf größer oder gleich testest. Eleganter wäre es, den Timer einen Interrupt auslösen zu lassen.

Die Zugriffe auf die LEDs sind auch nicht ganz richtig. Da solltest du http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ausg.C3.A4nge noch mal gründlich lesen.
PORTB |= (1<<PB2); //Pin auf high
PORTB &= ~(1<<PB2); //Pin auf low

Henry
15.02.2007, 21:41
Hallo uwegw,

wie gesagt, ich habe mich noch nicht so richtig mit C angefreundet.
Aber dank deinem Tipp habe ich es nun schon einmal geschafft die LED zum blinken zu überreden.
Werde mich auf jeden Fall mal mit dem Tut befassen.

Kannst Du mir evt. noch (möglichst einfach) erklären wie das mit dem auslösen von so einem Interrpt geht und wie ich da die Zeit vorgebe?

Das wird noch ein weiter Weg, denn ich würde irgendwann mal gern PWM Signale auswerten und ausgeben.

uwegw
16.02.2007, 15:12
Es gibt bei dem Timer0 des M16 zwei verschiedene Timer-Interrupts: den Overflow-Interrupt, und den Compare-match-interrupt.
Der Overflow löst aus, wenn der Zähler bei 255 angekommen ist und wieder auf null springt. Der Compare-match löst aus, wenn der Zähler einen bestimmten Wert erreicht.

Wenn ein Interrupt auslöst, wird das laufende Programm unterbrochen, und eine spezielle Funktion im Programm wird aufgerufen.

Die Zeit wird erst einmal über den Prescaler (Vorteiler) grob vorgewählt. das geht mit den CS... -bits. In deiner Initalisierung stellst du 1024 ein. Damit wird der Zähler alle 1024 Takte um eins weitergezählt. Bei z.B. 1Mhz Taktfrequenz würde der Timer also 976mal in der Sekunde weiterzählen. Ein Zählschritt entspricht also 1/976tel Sekunde.

SprinterSB
16.02.2007, 17:34
Sehr gut ist das immer im Handbuch beschrieben. Als erstes ist empfehlenswert, sich den Überblick über das Kapitel (zB Timer1, Interrupts) anzuschauen und was die Einheit prinzipiell kann. Danach ist ein Blich and Ende des Kapitels auf die Register nicht schlecht. Da wird die Funktion einzelner Register und Bits aufgedröselt und man bekommt eine konkretere Vorstellung von den Zusammenhängen und was die Einheit genau kann. Danch kann man sich aus dem Kapitel rausfischen, was man detailiert beschrieben haben will. Hat aber des Hasenfuß, daß es auf Englisch ist.

Im Wiki gibt's einen Artikel, der sich auch mit Timern beschäftigt. Ist zwar schon recht komplex für den Anfang, aber vielleicht beantwortet er mehr Fragen, als er aufwirft...

https://www.roboternetz.de/wissen/index.php/Hallo_Welt_f%C3%BCr_AVR_%28LED_blinken%29