Hallo Zusammen, Ich steh gerade irgendwie auf dem Schlauch. Ich möchte mittels Funkmodul und Atmega8 diverse Funksteckdosen ansteuern was auch soweit mit Delays schon funktioniert wobei das mit den Delays nicht sehr genau ist. Nun habe ich es schon geschafft mit dem 8bit Timer0 alle 500us einen Pin zu togglen ich steh nun aber gerade voll auf dem schlauch. Vllt. kann mir jemand auf die Sprünge helfen wie kann ich nun z.B. einen High Puls mit 500us einfach mehrmals hintereinander senden? Gruß Chris
HaraldB schrieb: > Vllt. kann mir jemand auf die Sprünge helfen wie kann ich nun z.B. einen > High Puls mit 500us einfach mehrmals hintereinander senden? Ich versteh, wo dein Problem liegt. Wenn du es doch schon geschafft hast, eine ISR alle 500µs aurufen zu lassen, dann hast du doch deinen gewünschten Puls. Wenn du x Pulse brauchst, dann zählst du halt einfach in einer Variablen mit und wenn die ISR dann eben 2*x mal aufgerufen wurde, dann machst du einfach nichts mehr am Pin.
Das dacht ich eben auch hat aber nicht funktioniert deshalb dacht ich mir evtl. geht es doch nicht so einfach. Hatte die ganze Zeit schon viele mögliche Varianten Ausprobiert und ein "volatile int count" hat mein Problem nun gelöst denn es funktioniert nun :) Alle 8 Bit werden nun korrekt Übertragen. Auszug Main:
1 | volatile int count = 0; |
2 | volatile int send; |
3 | volatile int data[10]; |
4 | |
5 | int main(void) |
6 | {
|
7 | |
8 | // PortB1 Output
|
9 | PORTB &= ~(1<<PB1); // Low |
10 | DDRB = (1 << PB1); |
11 | |
12 | // Prescaler 64
|
13 | TCCR0 |= (1<<CS01) | (1<<CS00); |
14 | |
15 | // Enable Timer0 Overflow Interrupt
|
16 | TIMSK |= (1<<TOIE0); |
17 | |
18 | // Allow Interrupts
|
19 | sei(); |
20 | |
21 | // set prescaler to 64 and start timer
|
22 | TCCR2 |= (1<<CS21); |
23 | |
24 | data[0] = 1; |
25 | data[1] = 0; |
26 | data[2] = 1; |
27 | data[3] = 0; |
28 | data[4] = 0; |
29 | data[5] = 1; |
30 | data[6] = 0; |
31 | data[7] = 1; |
32 | |
33 | while(1) |
34 | {
|
35 | if(data[count] == 1) |
36 | {
|
37 | send = 1; |
38 | } else if(data[count] == 0) |
39 | {
|
40 | send = 0; |
41 | }
|
42 | |
43 | if(count == 9) |
44 | {
|
45 | count = 0; |
46 | }
|
47 | }
|
ISR:
1 | ISR(TIMER0_OVF_vect) |
2 | {
|
3 | TCNT0 = 131; // 500us |
4 | |
5 | if(send == 1) |
6 | {
|
7 | PORTB |= (1<<PB1); // High |
8 | } else if(send == 0) |
9 | {
|
10 | PORTB &= ~(1<<PB1); // Low |
11 | }
|
12 | |
13 | count++; |
14 | |
15 | //PORTB ^= (1<<PB1);
|
16 | }
|
Ich halte das für unsauber, count an zwei Stellen zu verändern. Nimm den modulo 10 besser noch in den Interrupt. Im übrigen spräche aus meiner Sicht nichts dagegen die Ausgabe und den Zugriff auf data auch im Interrupt zu machen.
Ich hab nun alles in die ISR gepackt jetzt ist die Pulselänge immer 1-2 us zu lang/kurz. Evtl. doch nicht ganz so Optimal.
HaraldB schrieb: > Auszug Main: Tu dir selbst ein paar Gefallen > volatile int count = 0; > volatile int send; > volatile int data[10]; wenn Variablen per Design keine größeren Werte als 255 haben können und auch nie haben werden, dann bürde dem µC keine 16-Bit Airthmetik auf. Mal abgesehen davon, löst sich dann auch das Problem des atomaren Zugriffs in Luft auf, sobald ISR mit dieser Variable im Spiel sind. 8 Bit pro Variable tuns auch: volatile uint8_t count = 0; volatile uint8_t send; volatile uint8_t data[10]; > if(data[count] == 1) > { > send = 1; > } else if(data[count] == 0) > { > send = 0; > } tus nicht. data KANN bei dir per Design nur 0 oder 1 sein. Andere Werte gibt es nicht. Wenn data[count] nicht 1 ist, dann KANN es daher nur 0 sein. Das muss man nicht testen. Jedes Wort, dass du unnötig schreibst, ist eine potentielle Fehlerquelle. > if(send == 1) > { > PORTB |= (1<<PB1); // High > } else if(send == 0) > { > PORTB &= ~(1<<PB1); // Low > } selbiges. Wenn send nicht 1 ist, dann kann es per Definition nur 0 sein. Wozu eigentlich der ganze komplizierte Umweg über send? Wickle doch gleich alles komplett in der ISR ab, anstatt die Logik quer über das ganze Programm zu verstreuen.
Oops. Sorry. Aber gleich 2us? Hmm. Naja. Dann lass es lieber. Vielleicht nur den Modulus im Int.
HaraldB schrieb: > Ich hab nun alles in die ISR gepackt jetzt ist die Pulselänge immer 1-2 > us zu lang/kurz. > > Evtl. doch nicht ganz so Optimal. Kann nicht sein.
1 | ISR( ... ) |
2 | {
|
3 | TCNT0 = 131; // 500us |
4 | |
5 | if( data[count] ) |
6 | PORTB |= (1<<PB1); // High |
7 | else
|
8 | PORTB &= ~(1<<PB1); // Low |
9 | |
10 | count++; |
11 | if( count == sizeof( data ) ) |
12 | count = 0; |
13 | }
|
und mach deine Variablen uint8_t
Wenn Du da noch 1-2us Verzögerung hast, dann ist was anderes faul.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.