www.mikrocontroller.net

Forum: Projekte & Code Wartezeiten effektiv (Scheduler)


Autor: Peter Dannegger (peda)
Datum:
Angehängte Dateien:

Bewertung
3 lesenswert
nicht lesenswert
Gerade Anfänger haben oft das Problem, das erstmal alles wunderbar
läuft, aber plötzlich muß noch irgendwo gewartet werden.

Und ruchzuck ist die Performance im Eimer, aber der MC soll doch noch
so viele andere Sachen auch erledigen.

Wie macht man das also, Warten ohne Rechenzeitverschwendung ?

Eine mögliche Lösung ist der hier vorgestellte Scheduler.

Das Programm wurde mit WINAVR auf einem ATMega8 compiliert und belegt
etwa 900 Byte.

In dem Zip-File ist die Beschreibung und alle Source-Files.

Viel Spaß damit.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:

So ein Scheduler hat natürlich auch seine Einschränkungen.

Im Beispiel wird er alle 65536 Zyklen ausgeführt, d.h. die Main-Loop
sollte in der Regel in dieser Zeit mindestens einmal durchlaufen worden
sein. Dauert sie manchmal länger ist das meist auch kein Beinbruch.
Exakte Zeiten, wie z.B. Uhrzeit+Datum, Frequenzmessung sollte man
deshalb nicht im Scheduler sondern direkt im Timerinterrupt machen.


Wichtig ist also voher eine grobe Abschätzung der maximalen und
minimalen Zeitintervalle zu machen.
Im Beispiel ist die minimale Zeit: 1 / (11,0592MHz  256  256) =
5,9ms.
Das ist relativ schnell (das Beispiel hat ja fast nichts zu tun),
meistens sollten aber Zeiten von 100ms...500ms ausreichend sein.

Die maximale Zeit ergibt sich daraus, daß der Delayzähler 16-Bittig
ist, zu 65536 * 5,9ms = 6,4min.

Im main.h kann der Delayzähler als 8-, 16- oder 32-Bittig festgelegt
werden. Das hat dann Einfluß auf die Codegröße sowie die Größe der
Liste im RAM.

Für ein ordnungsgemäßes Funktionieren des Schedulers ist zu beachten,
daß man auch versteckte Wartezeiten vermeiden sollte.
Z.B. ist zu empfehlen, für die UART Sende- und Empfangspuffer
anzulegen, die dann im UART-Interrupt gefüllt bzw. geleert werden.

Das hängt aber immer auch von der konkreten Anwendung ab. Z.B. je 10
Bytes bei 115200Baud im Pollingmode zu senden, dürfte kaum einen
kritischen Zeitverbrauch bewirken.


Ein Scheduler ist also auch kein Zaubermittel, aber für komplexe
Zeitsteuerungen (z.B. Lichteffekte) fast unschlagbar einfach.


Peter

Autor: AxelR. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

muss man erst hingelinkt werden...
http://www.mikrocontroller.net/forum/read-1-155162...
Klasse Idee, hatte ich schon mal aufm AVR Seminar was von gehört.
Sehe ich mir gerne mal an.

Danke
(876ter DL)
AxelR.

Autor: Tina Kohler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

da ich auf der Suche nach einer Guten Entprell variante in C Suche bin
ich auf diese Seite gestossen!

Leider bin ich noch anfänger um komme mit dem Code überhaupt nicht
zurecht er ist halt einfach zu komplex!

Im Prinzip möchte ich nur einen Port als Eingschalten bzw. Port B und
dann mit den Einzelnen Pins bei Betätigung einen Funktion aufrufen oder
variablen um 1 erhöhen, leider geliegt es mir nicht den Code so aus
einander zu nehmen das ich ihn benutzen kann! Ich wäre dir echt dankbar
wenn du gerade für anfänger dieses Thema nochmal bearbeiten könntest da
das entprellen ja fast das wichtigste ist was man am anfang benötigt!

Vielen Dank Tina

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Tina

die Schedulerfunktion laß einfach links liegen.


if( get_key_press( 1<<LED0 ) )

testet ein Bit (gedrückte Taste) und löscht es.


Zur Funktion der Tastenerkennung und Entprellung steht hier was:

http://www.mikrocontroller.net/forum/read-4-20549.html#new


Peter

Autor: Hartmut Semken (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen Dank für ds wirklich schöne Codestück - schon die
Entprellroutine ist toll, die Timer sind ebenfalls sehr nützlich.

Dennoch ein Verbesserungsvorschlag: der Code initialisiert den PortC
nicht, schaltet also auch die Pullups nicht ein.
Out-of-the-zip hat das bei mir sehr schöne Random-Muster zur Folge
gehabt - gegen völlig wild schwingende Eingänge hilft eben auch 4-fach
Abtastung noch nicht.

Aber kaum macht man es richtig, da funktioniert es auch.

hase

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin Peter,
nachdem ich den Scheduler (also die Timer) auch schon erfolgreich 
eingesetzt habe, wollte ich auch mal Danke sagen. Die Idee ist nicht 
neu, aber funktionierend und effektiv fertig vorzufinden ist natürlich 
schön :-)

Vielen Dank Peter.

900ss

Autor: Bene Jan (terfagter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

ich versuche gerade deinen Scheduler auf einem Atmega16 zum laufen zu 
kriegen (16Mhz). Aber es tut sich irgendwie nichts. Als Beispiel sollen 
drei LEDs eingeschaltet werden. Wenn ich test() ausführe passiert dies 
auch. Mit timmeradd passiert aber nichts.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "MAIN.h"
  
int main (void) 
{
  //Für Scheduler
  TCCR0 = 1<<CS02;                    //divide by 256 * 256; Timereinstellungen für Scheduler
  TIMSK = 1<<TOIE0;                    //enable timer interrupt

  timerinit();                      //Initialisierung Timertick für Scheduler
  
  sei();                          

  timeradd( test, SECONDS( 1 ) );        
  
  for(;;)                          // main loop
  {                            
    if( f_timer_tick )
    {
      f_timer_tick = 0;
      timertick();
    }
  }
}

void test(void)
{
  DDRC = 0b00000111;
  PORTC = 0b00000000;
}


Die SCHEDULE.c habe ich nicht verändert und die MAIN.c sieht so aus:
#include <avr/io.h>
#include <avr/interrupt.h>
//#include <signal.h>

#define XTAL 16e6

#define TIMERTICK  (XTAL / 256 / 256)  // timer ticks per second

#define SECONDS(x)  ((uint)(TIMERTICK * x + 0.5))

#define uchar unsigned char
#define uint unsigned int
#define bit uchar
#define idata
#define code

typedef void (code *funcp)(void);

//#define t_res    uchar    // define time resolution  8 bit
#define t_res    uint    // define time resolution 16 bit


extern uchar key_state;    // debounced and inverted key state:
        // bit = 1: key pressed
extern uchar key_press;    // key press detect or repeat

extern uchar f_timer_tick;  // timer flag


extern uchar get_key_press( uchar key_mask );

void timertick(void);

bit timeradd( funcp func, t_res delay );

bit timerremove( funcp func );

void timerinit(void);

extern void test(void);

Woran könnte das liegen? Schonmal danke für deine Hilfe!

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm.... mal sehen.... polier die Glaskugel ;-)

Da du den Code nicht vollständig gepostet hast, kann man nur raten.

Die ISR fehlt zum Beispiel.

Aber hier:
extern uchar f_timer_tick;  // timer flag

Hier fehlt das volatile. Die Variable sollte natürlich auch als volatile 
definiert sein. Das könnte der Fehler sein.

Hast du geprüft, ob deine ISR überhaupt anläuft?
Wird der Zweig in

if( f_timer_tick ) {...}

aufgerufen? Kannst du doch einfach prüfen (Leds einschalten).

Autor: Bene Jan (terfagter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch ich habe meinen ganzen Code gepostet. Meine main.c und meine 
main.h. der Rest ist der scheduler von Peter Dannegger. Da habe ich ja 
nichts verändert.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bene Jan schrieb:
> Doch ich habe meinen ganzen Code gepostet.

Stimmt, hab mal nachgesehen in dem Code von Peter. Vorher
fehlte mir dir ISR. Die ist dann im Modul TOV0.C

1) Setze mal volatile für die oben angegebene Variable.
2) Prüfe, ob die ISR anläuft.
3) Prüfe ob if( f_timer_tick ) {...} durchlaufen wird.

Autor: dunno.. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bene Jan schrieb:
> void test(void)
> {
>   DDRC = 0b00000111;
>   PORTC = 0b00000000;
> }

ääähm... wierum genau hast du denn deine leds angeschlossen..?

könnte dein problem vielleicht einfach nur sein, das du portC auf 0x00 
stehen lässt...?

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dunno.. schrieb:
> könnte dein problem vielleicht einfach nur sein

Bene Jan schrieb:
> Als Beispiel sollen
> drei LEDs eingeschaltet werden. Wenn ich test() ausführe passiert dies
> auch

@dunno: alles klar?

@Bene Jan: Wenn es funktioniert dann schreib es.

Autor: Uwe S. (de0508)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich verwende schon lange den Taskscheduler von PEDA und habe hier eine 
Beispiel mit kompletten Code veröffentlicht.

Beitrag "Re: 3fach Timer (einschaltverzögerung)"

Damit solltest Du zum Erfolg kommen !

Es gibt auch von mir einige Anpassungen, aber damit komme ich immer 
sicher ans Ziel bei meiner Projekte.
utimer_t delta;
 kann 16-Bit oder 32-Bit je nach Problem haben und mit der Nutzung i.a. 
von GPIOR0 - GPIOR2; siehe |main.h|:
#ifdef GPIOR0
# define f_timer_tick  SBIT(GPIOR0,0)
#endif
wird der Code kleiner und schneller.

.

Autor: Bene Jan (terfagter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also mit oder ohne volatile ändert sich leider nichts.

Habe mal versucht in der if( f_timer_tick ) die LEDs einzuschalten. 
Funktioniert nicht! Also wird f_timer_tick nicht 1. Was wiederrum heißt, 
dass die ISR in TOV0.c nicht ausgeführt wird. Ich weiß aber noch nicht 
warum?!?

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bene Jan schrieb:
> Also mit oder ohne volatile ändert sich leider nichts.

Du mußt das volatile in zwei Modulen einsetzen, in dem ISR-Modul und in 
main.h, überall wo eine Deklaration oder Definition von f_timer_tick 
steht.

Um zu prüfen, ob die ISR durchlaufen wird, brauchst du doch nur dort 
(also in der ISR die LEDs einschalten.

Ansonsten die Timerinitialisierung prüfen.

SIGNAL(...) für die Interrupttoutine ist alt. Evtl. liegt es daran, was 
ich aber nicht glaube. Siehe avrlibc-Doku.

Autor: Bene Jan (terfagter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab jetzt nochmal volatile benutzt und auf einmal geht es!
Ich bin mir 100%-sicher das ich es eben genauso gemacht habe und da hat 
es nicht funktioniert...

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bene Jan schrieb:
> Ich hab jetzt nochmal volatile benutzt und auf einmal geht es!

Das ist doch schön :-)

> Ich bin mir 100%-sicher das ich es eben genauso gemacht habe und da hat
> es nicht funktioniert...

Daran hab ich meine Zweifel und die darfst du auch haben ;-)

Autor: Bene Jan (terfagter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich benutze den Scheduler in verschiedenen Projekten und dieser 
funktioniert auch super. Jetzt würde ich gerne auch die Entprellfunktion 
nutzen, diese funktioniert aber leider noch nicht bei mir:

Eingelesen werden sollen PE4 und PE5. Dort sind zwei Kurzhubtaster gegen 
GND angeschlossen. Für dieses Beispiel werte ich aber nur PE5 aus!
In meinem Beispiel soll ein kleiner Text über die UART ausgegeben 
werden. Ausgaben über die UART funktionieren einwandfrei, daran kann es 
also nicht liegen.
Wenn ich den Controller starte wird 1x der Text ausgegeben, ohne das ich 
den Taster drücke. Das kann ja auch schon nicht normal sein?!
Wo liegt mein Fehler?
Vielen Dank für eure Hilfe.
Hier mein Code:
getkey.c
#include "../main.h"

uchar get_key_press( uchar key_mask )
{
  cli();
  key_mask &= key_press;      // read key(s)
  key_press ^= key_mask;      // clear key(s)
  sei();
  return key_mask;
}
tov0.c
#include "../main.h"

uchar f_timer_tick;

uchar key_state;      // debounced and inverted key state:
              // bit = 1: key pressed
uchar key_press;      // key press detect or repeat

SIGNAL (SIG_OVERFLOW0)
{
  static char ct0, ct1;
  char i;

  i = KEY_INPUT & (1<<KEY4^1<<KEY5);
  i ^= ~key_state;          // key changed ?

  ct0 = ~( ct0 & i );      // reset or count ct0
  ct1 = ct0 ^ (ct1 & i);      // reset or count ct1
  i &= ct0 & ct1;      // count until roll over ?
  key_state ^= i;      // then toggle debounced state
  key_press |= key_state & i;    // 0->1: key press detect

  f_timer_tick = 1;
}
Veränderungen in der main.h:
#define KEY_INPUT  PINE
#define KEY4  4
#define KEY5  5
main.c
  TCCR0B = 1<<CS02;                    //divide by 256 * 256; Timereinstellungen für Scheduler
  TIMSK0 = 1<<TOIE0;                    //enable timer interrupt
  key_state = 0;
  key_press = 0;

  while(1)
  {
    if( f_timer_tick )
    {
      f_timer_tick = 0;
      timertick();
    }
    if( get_key_press( 1<<KEY5 ) )
    {  
      //0xFF ^= 1<<PG0;                // toggle LED2 on key press
      uputs0("Taste gedrueckt!");
    }
    
  }

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du externe Pullups oder schaltest Du sie ein?


Bene Jan schrieb:
> Hier mein Code:

Das ist kein Code, sondern Bröckchen, wie man sie einem Hund hinwirft.
Was soll damit jemand anfangen?
Er müßte ein neues Projekt machen und die Änderungen mühsam eintragen.
Und dabei können Fehler passieren.

Hänge das komplette compilierfähige Programm (als Zip) an. Es darf keine 
Warnungen und Fehlermeldungen geben.

Willst Du Änderungen markieren, kommentiere die Originalzeile aus und 
schreibe die neue darunter.
Oder nimm #ifdef, #else, #endif zum Unterscheiden.


Peter

Autor: Markus B. (markus_b77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter: dein Text im ersten Post klingt wie ein Werbetext ;)

Hab den Beitrag erst jetzt entdeckt. Werde ich mir mal anschauen.

Autor: Florian G. (stromflo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,

habe den Scheduler auch für den XMEGA umgeschrieben.
Leider habe ich in deinem Code keine Hinweise zu einer bestimmten Lizenz 
gefunden. Unter welcher Lizenz steht der Code? Soll der Autor angegeben 
werden?

Gruß Flo

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Florian G. schrieb:
> Soll der Autor angegeben
> werden?

Das ist o.k.

Autor: GTM (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

hattet ihr das auch mal, dass in timeradd 'funcp func' außer für -O0 
komplett wegoptimiert worden ist, und damit das Ganze bei aktivierten 
Optimierungen kaputt gegangen ist (während es ohne Optimierungen so 
funktioniert hat wie erwartet)?

Nachdem ich alles probiert habe, was ich kannte, um das Problem zu 
beseitigen, und es mir nicht gelang, hab ich mich letztlich von der Idee 
inspirieren lassen und das Ganze komplett neu geschrieben - allerdings 
mit Pointerarithmetik. Jetzt läufts auch optimiert und braucht sogar ein 
bisschen weniger Speicher im Flash.

Danke für die Vorlage! :)

Tom

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@GTM (Gast)

Welchen Compiler und welche Optionen benutzt Du?
Ich benutze WINAVR und -Os.
Hast Du mal ein Beispiel als Anhang.

Autor: Tim H. (rettungstim)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Servus zusammen,

Ich versucht die original Dateien von Peter zum laufen zu bringen.

Ich habe den Code nur an folgenden Punkten angepasst.
In TOV0.c

SIGNAL (SIG_OVERFLOW0)

wurde geändert in:
SIGNAL (TIMER0_OVF_vect)

und signal.h habe ich rausgeschmissen.

Benutze dazu Atmel Studio 6 (Version 6.1.2730- SP2).

Leider bekomme ich nun eine Warnung die ich nicht ganz verstehe.

Warning  1  suggest parentheses around arithmetic in operand of '^' 
[-Wparentheses]

Kann mir einer sagen was da falsch läuft?

Viele Grüße
Tim

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Warnung sagt doch exakt, was dort moniert wird. Der Compiler spricht 
eine Empfehlung aus. Versuche die Warnung zu übersetzen, dann wirst du 
es auch wissen.

Autor: Tim H. (rettungstim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm ja,

auf die Idee es mal zu übersetzen hätte ich auch kommen können. Sorry!

Aber vielen Dank für die schnelle Antwort.

Jetzt hangle ich mich mal an dem Code entlang um diesen genau zu 
verstehen. Ich hoffe das nicht noch mehr so dumme Fragen von mir kommen 
:-(

Viele Grüße
Tim

Autor: Tim H. (rettungstim)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich stelle mich mal wieder zu Blöd an. Ich bekomme den Code nicht ans 
laufen.

Ich habe zwei Taster an PC2 und PC3 und zwei LEDs an PC4 und PC5.

Ich bekomme den Code nicht so abgeändert das dieser läuft.
Ich habe auch noch nicht kapiert welchen Taster er in dem Code benutzt, 
vielleicht kann mir das einer erklären. Ich würde den Code so gerne 
verstehen...

Ich habe mir einen Mega8 mit 16Mhz.

Viele Grüße
Tim

: Bearbeitet durch User
Autor: Tim H. (rettungstim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

mein Code läuft nun. Der Code von Peter (UART mit FIFO) läuft auch.

Peter schreibt aber so Knackig das ich Schwierigkeiten habe alles zu 
versehen.

Hat jemand von euch den Scheduler und UART Code verheiratet und kann mir 
mal ein Codebeispiel schicken bzw. hier ablegen.

Das würde mir vielleicht auch helfen, beide Codes ein wenig mehr zu 
verstehen.

Vielen Dank und Grüße
Tim

Autor: Uwe S. (de0508)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim,

sag mal was soll man da verheiraten ?

Das sind zwei C Module ohne gemeinsame Schnittstellen.

Sind vielleicht die C Grundlagen, bzw. das C Projektmanagement das 
Problem ?

Autor: Tim H. (rettungstim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ich mir C mehr oder weniger selber beigebracht habe, fehlt es hier 
und da auch an den Grundlagen.

Ich möchte gerne mehrere Prozesse gleichzeitig laufen lassen.

Sprich ich möchte ein Rollo von der Taste aus fahren lassen bzw. diese 
Rollo über eine RS232 Schnittstelle Steuern können.

Deshalb muss ich in den Scheduler auch die UART einbinden.
Es ist ja Theoretisch möglich das während eines Schaltbefehl (Empfang am 
Rollo)  einer die Taste für Rollo hoch oder runter drückt.

Ich versuche bestehenden Code zu verstehen um in meinem Code weiter zu 
kommen.

Viele Grüße
Tim

Autor: Tim H. (rettungstim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ich oben schon schrieb habe ich den Code nicht  ganz verstanden.

Kann mir einer sagen wie ich die Zeitschleife abbreche?

Also durch Drücken der zweiten Taste.  LED ausmachen ist kein Problem 
aber wie "lösche" ich die Zeit? Die Zeit läuft im Hintergrund natürlich 
weiter.

Danke uns schönes WE
Tim

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim H. schrieb:
> Kann mir einer sagen wie ich die Zeitschleife abbreche?

bit timerremove( funcp func );

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim H. schrieb:
> Deshalb muss ich in den Scheduler auch die UART einbinden.

In den Scheduler eher nicht, sondern in die Mainloop:
  for(;;){
    if( taste_gedrueckt )
      mache_was();
    if( byte_empfangen )
      mache_auch_was();
  }

Sind mehrere Byte für ein Kommando nötig, ist das kein Beinbruch.
Die Behandlungsroutine sammelt dann eben die Bytes in einen Puffer, bis 
sie das Paketende erkennt und parst es dann.

Autor: Tim H. (rettungstim)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Tim H. schrieb:
>> Kann mir einer sagen wie ich die Zeitschleife abbreche?
>
> bit timerremove( funcp func );

Danke Peter, hätte ich selber sehen können. Das ist ein super Sache, 
vielen dank fürs einstellen des Codes. Hoffentlich verstehe ich ihn auch 
irgendwann zu mehr als 50%...

Peter Dannegger schrieb:
> Tim H. schrieb:
> Sind mehrere Byte für ein Kommando nötig, ist das kein Beinbruch.
> Die Behandlungsroutine sammelt dann eben die Bytes in einen Puffer, bis
> sie das Paketende erkennt und parst es dann.

Das mit empfangen von 1 Byte habe ich hinbekommen. Also mit Auswertung 
in einer IF-Abfrage. Aber wie mache ich das mit mehreren Bytes, ich habe 
das in deinem Beispiel nicht verstanden wie du den Puffer verwendest. Da 
ich ja zum Beispiel den String "Test1" auswerten will. Wenn aber "Test2" 
kommt soll er natürlich nix tun, bis der "Test1" sieht.

Entschuldigt bitte die blöden Fragen, aber ich möchte den Code 
wenigstens ein bisschen verstehen, da ich ihn in meinem Haus noch ein 
paar mal einsetzen will.

Viele Grüße
Tim

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pseudo-Code:
void rec_cmd()
{
  static char buff[20];
  static uint8_t idx = 0;

  if( byte_avail() == 0 )
    return;
  buff[idx] = get_byte();
  if( idx < sizeof(buff)-1 )
    idx++;
  if( cmd_end( buff ) == 0 )
    return;
  parse_cmd( buff ); // Kommando erkennen und was machen
  idx = 0;
}

Das Parsen kann man z.B. mit sscanf machen, ist zwar nicht sonderlich 
effizient.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.