mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 8bit-Timer Mega8


Autor: Pat F. (breaker87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Leute!

Ich habe Probleme mit dem 8bit Timer bei meinem ATmega8.
Das Tutorial habe ich mir durchgelesen und ich habe auch andere Quellen 
im Internet durchsucht (inkl. Datenblatt) - trotzdem habe ich es nicht 
geschafft.

Wie starte ich den Timer?
Ich würde das Programm gerne so gestalten, dass alle 0,1ms (oder 0,01 
ms) ein Timeroverflow ausgelöst wird, welches dann eine long Variable 
"zeit" erhöht. Sobald dann ein "Ereignis" an einem definierten Eingang 
auftritt, soll ein "Timestamp" in ein Array gespeichert werden...

Doch zuerst hat die Funktion des Timers vorrang...

Hier mein aktueller Stand:
#include <mega8.h>   // include file w. SFR names
#include <LCDlib.h>    // include MegaPAC-LCD functions
#include <stdio.h>

#define Key1 PINC.1    // T1 at PC1 (active low)
#define Key2 PINC.2    // T2 at PC2 (active low)
#define Key3 PINC.3    // T3 at PC3 (active low)

#define LED1 PORTD.4   // LED 1 at PD4 (active high)
#define LED2 PORTD.5   // LED 2 at PD5 (active high)
#define LED3 PORTD.6   // LED 3 at PD6 (active high)
#define LED4 PORTD.7   // LED 4 at PD7 (active high)

// Declare your global variables here:
unsigned char n;  // global count variable
long zeit=0;
char text[16]; 

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
   zeit++;
} 

void main(void)
{
// Declare your local variables here


PORTB=0x00; //  0    0    0    0    0    0    0    0
DDRB=0x3F;  //  0    0    1    1    1    1    1    1 
PORTC=0x0E; //  0    0    0    0    1    1    1    0
DDRC=0x30;  //  0    0    1    1    0    0    0    0 
PORTD=0x03; //  0    0    0    0    0    0    1    1
DDRD=0xFE;  //  1    1    1    1    1    1    1    0 
UBRRH=0x00;  // UBRR = 103 Dez = 0x0067 for 9600 Bd.
UBRRL=0x67;
UCSRA=0x20;  // 
UCSRB=0x08;
UCSRC=0x86;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
TCCR0=0x01;  //Prescaler 64 --> 0x01 = Standartwert
TCNT0=0x00;  //Vorladen mit 6 

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Global enable interrupts
#asm("sei")

while (1)
{
InitLCD(); // initialize LCD; auto increment cursorposition

while (1)       // do forever
{    
  if (!Key1)
  {
  TCCR0=0x03;
  }
  if (!Key2)           // if T2 is active (low),
   {
    zeit = zeit/1000;
    sprintf(text,"%i s",zeit);
    SetCursLCD(1);   // set cursor to 9.th pos. again
    for(n=0;n<16;n++)   // write last 8 chars of welcome msg.
       {WrCharLCD(text[n]);}
   }
   if (!Key3)
   {
   TCCR0=0x00;
   }
  }
}
}// End of while

Ich hoffe ihr könnt mir weiterhelfen...


lg Patrick

PS: Compiler ist CVAVR

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TCCR1B heißt das Register glaub ich. Such mal danach, da steht drin 
welche Bits zu setzen mußt, kommt auf darauf an, ob Du einen Vorteiler 
willst.

Autor: Pat F. (breaker87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir für ein timer-Frequenz von 1000Hz bei 16MHz Clock folgende 
Werte berechnet:
Prescaler -> 64
Timervorgabewert ->6
d.h. alle 1000µs wird ein Interrupt ausgelöst...

lg

Autor: unbeschreiblicher Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Solche Sachen macht man nicht (mehr) mit einem "manuellen" 
Timer-Nachladen, sondern mit dem CTC-Mode. Der geht bei Mega8 allerdings 
nur bei Timer1 (16Bit) und Timer2 (8Bit).

>zeit = zeit/1000;


wirr...
Long sind doch 32Bit-Integer, oder? (So riesige Zahlen benutze ich 
nie...)
Wenn man eine Zahl z.B. 5 durch 1000 teilt, bekommt man als Ergebnis 0.
Also kann Zeit nie grösser als 1 werden...

16MHz / 64 = 250000 Hz
Das würde also schon dicht an deine 1kHz herankommen.

Zumindest bei AVRgcc sollte zeit als volatile deklariert werden; wie das 
CodeVision ist, kann ich nicht sagen.

>TCNT0=0x00;  //Vorladen mit 6
Da wird nicht das veranlasst, was der Kommentar verspricht...


Nur so am Rande:
das:
PORTB=0x00; //  0    0    0    0    0    0    0    0
DDRB=0x3F;  //  0    0    1    1    1    1    1    1
PORTC=0x0E; //  0    0    0    0    1    1    1    0
DDRC=0x30;  //  0    0    1    1    0    0    0    0
PORTD=0x03; //  0    0    0    0    0    0    1    1
DDRD=0xFE;  //  1    1    1    1    1    1    1    0
UBRRH=0x00;  // UBRR = 103 Dez = 0x0067 for 9600 Bd.
UBRRL=0x67;
Ist einer der sinnfreiesten Kommentare, die ich mir vorstellen kann.

Autor: Pat F. (breaker87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unbeschreiblicher Rahul wrote:
> Solche Sachen macht man nicht (mehr) mit einem "manuellen"
> Timer-Nachladen, sondern mit dem CTC-Mode. Der geht bei Mega8 allerdings
> nur bei Timer1 (16Bit) und Timer2 (8Bit).
>

Ich hab leider keine ahnung wie das sonst funktioniert...

>>zeit = zeit/1000;
>
> wirr...
> Long sind doch 32Bit-Integer, oder? (So riesige Zahlen benutze ich
> nie...)

Ich will über einen Zeitraum von 2 stunden messen und das mit einer 
Genauigkeit von mindestens 1/100s - daher dachte ich an eine long 
variable...

> Wenn man eine Zahl z.B. 5 durch 1000 teilt, bekommt man als Ergebnis 0.
> Also kann Zeit nie grösser als 1 werden...
>
> 16MHz / 64 = 250000 Hz
> Das würde also schon dicht an deine 1kHz herankommen.
>
> Zumindest bei AVRgcc sollte zeit als volatile deklariert werden; wie das
> CodeVision ist, kann ich nicht sagen.
>
>>TCNT0=0x00;  //Vorladen mit 6
> Da wird nicht das veranlasst, was der Kommentar verspricht...
>
>
> Nur so am Rande:
> das:
> PORTB=0x00; //  0    0    0    0    0    0    0    0
> DDRB=0x3F;  //  0    0    1    1    1    1    1    1
> PORTC=0x0E; //  0    0    0    0    1    1    1    0
> DDRC=0x30;  //  0    0    1    1    0    0    0    0
> PORTD=0x03; //  0    0    0    0    0    0    1    1
> DDRD=0xFE;  //  1    1    1    1    1    1    1    0
> UBRRH=0x00;  // UBRR = 103 Dez = 0x0067 for 9600 Bd.
> UBRRL=0x67;
> Ist einer der sinnfreiesten Kommentare, die ich mir vorstellen kann.

Diese Komentare stammen von meinem Lehrer, bei dem wir unseren "MegaPac" 
- also unser Demoboard gebaut haben. Stammt aus einem Beispielsprogramm, 
um nicht andauernd alle In und Outputs einstellen zu müssen...


lg

Autor: unbeschreiblicher Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich will über einen Zeitraum von 2 stunden messen und das mit einer
>Genauigkeit von mindestens 1/100s - daher dachte ich an eine long
>variable...
Kann schon sein, dass in deiner ISR zeit auch hochgezählt wird.
Sobald Key1 betätigt wurde, ist es mit deiner "Uhr" aber hinfällig.

>zeit = zeit/1000;

>while (1)
>{
>InitLCD(); // initialize LCD; auto increment cursorposition

>while (1)

Was soll das erste while bewirken?
Lass es weg!


>zeit = zeit/1000;
>sprintf(text,"%i s",zeit);

solltest du lieber so machen:

sprintf(text,"%i s",zeit/1000);



Wenn dir die Zeit lieb ist.

Autor: Pat F. (breaker87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das while war ein "Versehen" - habs vergessen zu löschen...


wie kann ich denn den Timer dann zb mit Key1 starten?


lg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> wie kann ich denn den Timer dann zb mit Key1 starten?

Ein Timer läuft sobald ein Vorteiler eingestellt ist.
Ist der Vorteiler 0, dann stoppt der Timer.

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.