2 Zeitberechnungen mit ATMEGA8

OP #923626
Lesenswert?

Hallo,

ich will mit einem MEAG8 und GCC ein Programm schreiben, das mir 
folgendes Erledigt:

Eingänge: Lichtschranke 1 (LS1)--> PD2(INT0)
          Lichtschranke 2 (LS2)--> PD3(INT1)
Ausgang über RxD und TxD(UART) zum PC, dort läuft ein Delphiprogramm ab 
das die daten auswerten soll.

Programm:
1. Nach einem Signal vom PC (logische 1 würde reichen) soll die 
Zeitmessung starten
2. Und mit der neg. Flanke(da aktive low eingang) den Timer stoppen und 
die Zeit ausgeben an den PC über UART. (Zeit < 60sec.; allerdings wäre 
die Genauigkeit im 10ms Bereich nötig)
3. Eine weitere Zeitmessung, die die Zeit zwischen der LS1 und LS2 
ausgibt(wieder neg. Flanke; Zeit < 10sec.; Genauigkeit im 1ms Bereich) 
Diese Zeit ebenfalls weder ausgeben
4. Dann wieder alles zum Anfang und auf das Signal vom PC warten.

---
Eins wär noch erwünschensert:
Eine Überwachung, ob der Microcontroller noch aktiv und verbunden ist. 
Ich dachte mir evtl. ein Signal das alle 5-10sec. an den PC gesendet 
wird.


Jetzt meine Fragen:

Ist es möglich gwasi 2 Timer zu betreiben(nach dem ende des ersten den 
zweiten sofort starten, ohne aber auf die auswertung zu warten, weil 
sonst würde ja diese Zeit verloren gehen)?

Wer hat eine Idee für die Überwachung ob alles noch in Ordung ist oder 
eine Vorschlag wie ich die Idee von mir umsetzten könnte?


Vielen Dank
Mit freundlichen Grüßen
Markus
Gast #923637
Lesenswert?

>gwasi 2 Timer zu betreiben

Ich würde einen 16bit Timer durchlaufen lassen. Mit den Ereignissen dann 
den aktuellen Zählerstand auslesen und danach ne Berechnung durchführen.

>berwachung ob alles noch in Ordung
Zum Beispiel alle 1sek. ein Byte zum PC senden. (Die Zeitbasis kann mit 
über denselben Timer gemacht werden => OVerflow)
OP #923784
Lesenswert?

Was meinst du was ich die ganze zeit mache. Ich komme nur sehr mühsam 
voran und darum hätte ich gehofft, dass mit jemand von euch ein wenig 
hilft. Ihr könnt das sicher auswendig, aber ich muss alles nachlesen und 
weiß noch nichteinmal genau wo was steht.

Wieso willst du meine PLZ wissen?
OP #923798
Lesenswert?

Soweit bin ich schon gekommen. Aber wie kann ich den Timer 
programmieren, im Tutorial ist es auch nicht so schön erklärt.
Welche Variable enthält den Gezählten Wert?
Muss ich den Prescaler so dimensonieren, dass mein Zählwert definitiv in 
den 65... Schritten liegt oder kann ich auch die Overflows zählen 
lassen?

1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#include <inttypes.h>  
5

6
#define FOSC 7372800
7
#define BAUD 19200
8
#define MYUBRR (FOSC/16/BAUD-1)
9

10
#define INTO_vect LS1
11
#define INT1_vect LS2
12

13

14
volatile uint16_t LS_1;
15
ISR(INT0_vect)                /* Interrupt INT0 --> LS1 */
16
{
17
    LS_1++;   
18
}
19

20
volatile uint16_t LS_2;
21
ISR(INT1_vect)                /* Interrupt INT1 --> LS2 */
22
{
23
    LS_2++;   
24
}
25

26
int time (void) {
27
   sei();        /* Global Interrupt Enable */
28

29
   TCCR1B = (1<<CS12);            /* Clock Set Bits auf CPU-Takt / 256 */
30
}
31

32
int main (void) {            
33
 
34
// Ein/Ausgänge
35
   DDRD |= (1<<DDD2) | (1<<DDD3);          /* Lichtschrankeneingänge */
36

37
// Bluetooth-Übertragung   
38
   UCSRB |= (1<<TXEN) | (1<<RXEN);  /* UART Tx und Rx einschalten */
39
   UCSRC |= (1<<URSEL) | (3<<UCSZ0);       /* Asynchron */
40

41
   UBRRH = MYUBRR >> 8;            /* Buadatenragister setzen */
42
   UBRRL = MYUBRR & 0xFF;
43

44
// Interrupt
45
   GIMSK |= (1<<INT0) | (1<<INT1);  /* Flankenerkennung am INT Eingang*/
46
   MCUCR |= (1<<ISC11) | (1<<ISC01);  /* fallende Flanke erzeugt Interrupt */
47
   GICR |= (1<<INT0) | (1<<INT1);      
48

49
   sei();        /* Global Interrupt Enable */
50

51
   TCCR1B = (1<<CS12);            /* Clock Set Bits auf CPU-Takt / 256 */
52

53
   while(1) {               
54
  
55
   while (!(UCSRA & (1<<UDRE))) {  /* warten bis Senden möglich ist */
56
                    /* Variablen die Gesendet werden sollen */          
57
   }
58

59
   UDR = 'x';                /* schreibt auf Schnittstelle */
60
   }                        
61
 
62
   /* wird nie erreicht */
63
   return 0;
#923819
Lesenswert?

Am besten, Du nimmst Dir erstmal Papier und Bleistift und machst nen 
Ablaufplan.

Und dann den Plan stur der Reihe nach in Code umsetzen.
Interrupts würde ich dafür keine verwenden, das machts nur unnötig 
kompliziert.
Einfach an der Stelle in ner while-Schleife pollen.

Und pappe nicht alles als Spaghetticode hintereinander, bis niemand mehr 
durchsieht.
Sondern teile es in Unterfunktionen auf, z.B.:

uart_init
send_byte
receive_byte
timer_start
timer_read
poll_ls1
poll_ls2

usw.

Peter

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