Brauche wieder einmal eure Hilfe! Bin noch ein Anfänger, möchte aber mehrere Dinge parallel laufen lassen. Was ich bräuchte ist, ein Grundegrüst, damit ich darauf aufbauen kann. Anbei ein Übungsprogramm, von dem ich nicht weiss, ob der Ansatz so stimmt, oder komplett falsch ist. Wo bekommen ich Info's bzw. kann mir jemand den Code anbei aktualisieren. Wäre euch dankbar! Momentan (jetziges Programm ist noch länger wie dies im Anhang) läuft mein Programm nicht gut, d.h: es macht was es will. Glaube die Funkt. im "Compare-Match-Teil sind zu lang!?!?. Vorab schon Mal vielen Dank! Mad //======================== Programmbeschreibung ======================== // 1.) Die Zeitkritischen Funkt. werden über einen Switch/Case-Schleife mittels "i_ext" gesteuert // 2.) 1x pro Millisek. sollten jene Funktionen aufgerufen werden, die sich ausserhalb der Switch-Case-Schleife befinden. // 3.)Im "main-Teil" sind nur zeitunkritische Funktionen! //===================================================================== #include "definition.h" #include "LCD_def.h" #include "lcd_drv.c" uint8_t Funktion_LED_1(uint16_t ms); uint8_t Funktion_LED_2(uint16_t ms); uint8_t Funktion_LED_3(uint16_t ms); uint8_t Tastaturabfr(uint16_t ms); uint8_t In_Out_Abfr(uint16_t ms); extern uint8_t i_ext = 0; // Eventhandler (steuert die zeitkritischen Funktionen) dekl. & init //************** Beginn zeitkritische Funktionen !!!********** ISR (TIMER0_COMP_vect) { switch(i_ext) // Eventhändler zum steuern des Ablaufs!!! { case 10: Funktion_LED_1(100); break; // bestimmen der Blinkfrequenz Led 1 // case 11: Funktion_LED_2(100); break; // bestimmen der Blinkfrequenz Led 2 // case 12: Funktion_LED_3(100); break; // bestimmen der Blinkfrequenz Led 3 } //Tastaturabfr_4x3(100); break; // längere Funktionen mit LCD Ausgabe //In_Out_Abfr(100); break; // längere Funktionen mit LCD Ausgabe } //************** Ende zeitkritische Funktionen !!!********** int main() { //********************************************************************** ** // Timer Konfig. (Compare Match) zählt bis xx-Wert hoch (zB.: 8) --> IR //********************************************************************** ** TIMSK |= (1 << OCIE0); // IRQ bei Compare Match OCR0 = 8; // Vergleichswert 8 einstellen => ca. 1000 Hz (1ms) --> (8000000/1024/8) sei(); // IRQs enable (Interrupt global einschalten) TCCR0 |= (1 << WGM01); // CTC-Modus (Vergleichmodus) TCCR0 |= (1 << CS00) | (1 << CS02); // Prescaler: 1/1024 (zB.: CPU-Takt 8000000/ Teiler 1024) //********************************************************************** ** // I2C & LCD Konfiguration //********************************************************************** ** lcd_init(); // LCD initialisieren // i2c_init(); // initialize I2C library //********************************************************************** ** // Port Konfig. //********************************************************************** ** DDRA = 0x00; // Eing. Def. PORTA= 0xFF; // Alle Pin via Pullup auf High DDRB = 0xFF; // Ausg. Def. PORTB= 0xFF; // Alle Pin via Pullup auf High lcd_pos(2,0); lcd_text("Guten Tag!"); _delay_ms(1000); while(1) //endlos { lcd_clear(); lcd_pos(2,0); lcd_text("Step 1!"); _delay_ms(1000);// was mich stört sind, diese sinnlosen delay's i_ext = 10; //Aufruf Zeitk.-Funktion_LED_1() im Compare-Match-Modus; _delay_ms(1000); lcd_pos(2,0); lcd_text("Step 2!"); _delay_ms(1000); i_ext = 0; // Zeitkritischen-Funktionsaufruf sperren LCD_Ausg(); _delay_ms(1000); //usw: } // ENDE while(1); return 0; } ENDE main(); //********************************************************************** ** // ZEIT-Kritische Funktion 1 wird mit einer Variable (i_ext) gesteuert //********************************************************************** ** uint8_t Funktion_LED_1 (uint16_t ms) // Funktionsaufruf mit Wertübergabe { static uint16_t i_zaehler = 0; // Zähler auf 0 setzen (einmalig) if (i_zaehler >= ms) // Zählerstand > wie Wert der Funktion --> rein in die Schleife { PORTB ^= (1 << PB1); // Toggle Pin 2 von PORT B i_zaehler = 0; // Zähler wieder auf 0 } i_zaehler ++; // sonst erhöhe Zähler um 1 return 0; // zurück ins HP } //********************************************************************** ** // NICHT-Zeitkritische Funktion //********************************************************************** ** void LCD_Ausg(void) { lcd_clear(); // kompl. LCD löschen!!!! _delay_ms(30); lcd_text(" Hallo wie geht "); lcd_pos(2,0); lcd_text(" es dir "); lcd_pos(3,0); lcd_text(" heute? "); lcd_pos(4,0); lcd_text(" gut/schlecht? "); }
Madang Madang schrieb: > Brauche wieder einmal eure Hilfe! > Bin noch ein Anfänger, möchte aber mehrere Dinge parallel laufen lassen. > Was ich bräuchte ist, ein Grundegrüst, damit ich darauf aufbauen kann.
1 | volatile uint8_t DoLCD; |
2 | volatile uint8_t DoLED; |
3 | |
4 | |
5 | ISR( ... ) |
6 | {
|
7 | ...
|
8 | |
9 | if( ... ) |
10 | DoLCD = 1; |
11 | |
12 | if( ... ) |
13 | DoLED = 1; |
14 | |
15 | ...
|
16 | }
|
17 | |
18 | int main() |
19 | {
|
20 | ....
|
21 | |
22 | sei(); |
23 | |
24 | while( 1 ) { |
25 | |
26 | if( DoLCD ) { |
27 | DoLCD = 0; |
28 | |
29 | Bearbeite das LCD |
30 | }
|
31 | |
32 | if( DoLED ) { |
33 | DoLED = 0; |
34 | |
35 | Bearbeite die LED |
36 | }
|
37 | |
38 | if( ... ) |
39 | {
|
40 | ...
|
41 | }
|
42 | }
|
43 | }
|
Die _delay_xx Funktionen solltest du gleich mal vergessen. Die sind Gift wenn es darum geht, mehrere Dinge 'parallel' abzuarbeiten. Statt dessen wird die jeweilige Funktionalität von einem 'Job-Flag' abhängig gemacht. Ist die Funktionalität auszuführen, so setzt irgendein Code (muss nicht die ISR sein), das Job-Flag auf 1. Bei nächsten Durchgang durch die Hauptschleife wird das registriert und die Funktionalität ausgeführt und das Job-Flag zurückgesetzt. Auf die Art werden immer nur die Aktionen gemacht, die auch tatsächlich notwendig sind. Bei lang andauernden Aktionen, kann es auch sein, dass man diese in mehrere Teile unterteil mit jeweils einem eigenen Job-Flag, damit die Hauptschleife gelegenheit bekommt einmal rundum zulaufen und auch andere 'Parallel-Aktionen' eine Chance haben eine kurze Zeitscheibe abzukriegen.
@ Madang Madang (madang) >Brauche wieder einmal eure Hilfe! Ja, vor allem in Netiquette. Lange Quelltexte postet man als Anhang! >Bin noch ein Anfänger, möchte aber mehrere Dinge parallel laufen lassen. Siehe Artikel Multitasking und Interrupt. MfG Falk
Interessant wird es doch jetzt wenn man einen Job genau zweimal ausführen will. Es könnte doch sein das ich das Flag schon wieder setzen muss obwohl es noch garnicht abgearbeitet wurde. Was wären denn nun die Strategien ? - Abfrage auf Flag schon wieder zurückgesetzt wurde im HP - Flag Variable als Zähler benutzen - Eine Que/Pipe Was gäbe es da noch ?
Wie soll man etwas geanu zweimal ausfuehren, ohne zu zaehlen ? Was spricht gegen eine Zaehlvariable ?
> Interessant wird es doch jetzt wenn man einen Job genau zweimal > ausführen will. > Es könnte doch sein das ich das Flag schon wieder setzen muss obwohl es > noch garnicht abgearbeitet wurde. Da hast Du im wesentlichen genau zwei Möglichkeiten: 1. Die Jobs sind echt zeitkritisch. Falls die zweite 'Aufforderung' kommt und die erste noch gar nicht abgearbeitet wurde, dann hast Du Pech gehabt. 2. Die Jobs sind nicht (oder wenig) zeitkritisch, d.h. es können auch (kurzzeitig) schneller Auslöser kommen als abgearbeitet wird, es darf aber (zahlmäßig) keiner verloren gehen. Für sowas nimmt man eine hübsche Zählvariable, und zwar (z.B.) derart dass der 'Auslöser' die Variable hochzählt und der 'Ausführende' (sofern die Variable > 0 die Aktion ausführt und) die Variable wieder runterzählt. Also Semaphor-artig. HTH
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.