8bit-Timer Mega8

OP #471802
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:
1
#include <mega8.h>   // include file w. SFR names
2
#include <LCDlib.h>    // include MegaPAC-LCD functions
3
#include <stdio.h>
4

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

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

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

19
// Timer 0 overflow interrupt service routine
20
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
21
{
22
   zeit++;
23
} 
24

25
void main(void)
26
{
27
// Declare your local variables here
28

29

30
PORTB=0x00; //  0    0    0    0    0    0    0    0
31
DDRB=0x3F;  //  0    0    1    1    1    1    1    1 
32
PORTC=0x0E; //  0    0    0    0    1    1    1    0
33
DDRC=0x30;  //  0    0    1    1    0    0    0    0 
34
PORTD=0x03; //  0    0    0    0    0    0    1    1
35
DDRD=0xFE;  //  1    1    1    1    1    1    1    0 
36
UBRRH=0x00;  // UBRR = 103 Dez = 0x0067 for 9600 Bd.
37
UBRRL=0x67;
38
UCSRA=0x20;  // 
39
UCSRB=0x08;
40
UCSRC=0x86;
41

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

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

51
// Global enable interrupts
52
#asm("sei")
53

54
while (1)
55
{
56
InitLCD(); // initialize LCD; auto increment cursorposition
57

58
while (1)       // do forever
59
{    
60
  if (!Key1)
61
  {
62
  TCCR0=0x03;
63
  }
64
  if (!Key2)           // if T2 is active (low),
65
   {
66
    zeit = zeit/1000;
67
    sprintf(text,"%i s",zeit);
68
    SetCursLCD(1);   // set cursor to 9.th pos. again
69
    for(n=0;n<16;n++)   // write last 8 chars of welcome msg.
70
       {WrCharLCD(text[n]);}
71
   }
72
   if (!Key3)
73
   {
74
   TCCR0=0x00;
75
   }
76
  }
77
}
78
}// End of while

Ich hoffe ihr könnt mir weiterhelfen...


lg Patrick

PS: Compiler ist CVAVR
Gast #471825
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.
OP #471842
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
Gast #471851
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren