Forum: Compiler & IDEs 2 Zeitberechnungen mit ATMEGA8


von Markus V. (darkangel)


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

von Matthias L. (Gast)


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)

von Markus V. (darkangel)


Lesenswert?

Könnte mir mal jemand einen kleinen Aneiz geben, wie ich die ganze Sache 
angehen könnte.

Wie starte ich einen interrupt, oder geht das bei dem Eingang 
automatisch?`

WIe mache ich das mit der Bedingung, dass erst ein Signal vom PC kommen 
muss?

Die wird der Timer programmiert?

von Matthias L. (Gast)


Lesenswert?

Oh Mann...

Ich würd sagen, du liest dir mal das Datenblatt und das Tutorial hier 
duch..


PS: Aus welchem PLZ-Bereich bist du?

von Markus V. (darkangel)


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?

von Markus V. (darkangel)


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;

von Peter D. (peda)


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

von Matthias L. (Gast)


Lesenswert?

>Wieso willst du meine PLZ wissen?

Es ist umständlich alles über das Formu zu erklöären..

Hast du ICQ? dann schreib mir mal ne PM

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.