Vorrang hat er schon, aber dann müssen die Werte, die er verändert hat, auch ausgewertet werden, bevor er ein zweites Mal auftritt, sonst werden die Werte wieder überschrieben.
Fleurys Funktionen (zB i2c_readXXX) enthalten Warteschleifen wie
die eine Verzögerung verursachen, für die du keine Obergrenze angeben kannst (ein I2C-Sklave kann die Übertragung beliebig verzögern).Code:while(!(TWCR & (1<<TWINT)));
Eine nicht-blockierende I2C-Implementierung wäre daher IRQ-getrieben oder man müsste sich eine State-Machine bauen (wäre ne IRQ-getriebene im Endeffekt auch).
Ein sehr einfaches Beispiel einer nicht-blockierenden Hauptschleife ist auf meiner HP zkizziert. Dort werden 2 LED geblinkt. Eine im Takt von 1s und eine im Takt von 1.1s, was mit Warteschleifen eh net zu machen wäre.
http://www.gjlay.de/pub/c-code/countdown.html
In deinem Fall käme man ohne extra Timer aus. Die Hauptschleife läuft nichtblockierend über alle Aufgaben und falls an der Aufgabe erledigt werden muss, wird es erledigt. Beispiel: Daten über TWI senden.
Irgendwo in Programm (also innderhalb der Hauptschleife) schreibt was Daten in den Ausgabepuffer. Im TWI-Teil wird geschaut, ob Daten da sind. Wenn ja, wird das Datum gesendet, falls nicht schon eine Übertragung im Gange ist. Dazu wird ein Start geschickt, falls es nicht schon geschickt wurde, etc.
Man muss sich also Zusatände merken (daher der Name /State-Machine/). Wenn man nicht weiterkommt, weil eine Bedingung nicht erfüllt ist (zB weil Daten auf die man wartet noch nicht eingetroffen sind), macht man mit der nächsten Aufgabe (z.B Frequezauswertung) weiter und schaut beim nächsten Durchlauf der Hauptschleife, was geht.
Das ist natürlich aufwändiger zu programmieren als ein blockierender Ansatz, aber eben auch leistungsfähiger und Module bremsen sich net gegenseitig aus.
Lesezeichen