Forum: Mikrocontroller und Digitale Elektronik Ideales Timing - Brainstorming scheduling


von Simon (Gast)


Lesenswert?

Hi liebe Leut,

ich programmiere schon länger uC - aber stelle mit immer wieder die 
Frage, wie man Timing-Probleme möglichst gut lösen könnte...

Bsp: externes Gerät will nacht Daten 5ms in Ruhe gelassen werden,  beim 
HD 44780 liegt das Busybit erst nach ein paar us bereit   und so weiter

Bisher hab ich immer aktiv dann mindestens auf ein Busy-Bit gewartet  - 
oder eine "Liste der Wartenden" geschrieben  -  gibt es da keine 
besseren Ideen ?

Wie macht Ihr das ? jeder von hat schon mal ein LCD angeschlossen  - 
wartet Ihr nach dem clear tatsächlich dann 5ms in einer Schleife ?

schönen Abend

Simon

von Benedikt K. (benedikt)


Lesenswert?

Simon wrote:

> Wie macht Ihr das ? jeder von hat schon mal ein LCD angeschlossen  -
> wartet Ihr nach dem clear tatsächlich dann 5ms in einer Schleife ?

Nein. Ich frage das Busy Bit vor jedem Schreiben ab. So muss die 
Software nur dann warten, wenn sie Daten loswerden will. Meistens wird 
aber noch irgendwas zwischen clear der Ausgabe berechnet, so dass die 
Wartezeit sinnvoll genutzt wird.

von Peter D. (peda)


Lesenswert?

Simon wrote:
> Wie macht Ihr das ? jeder von hat schon mal ein LCD angeschlossen  -
> wartet Ihr nach dem clear tatsächlich dann 5ms in einer Schleife ?

Nein, ich benutze kein Clear.

Das Schreiben danach braucht ja auch erstmal Zeit.
Wenn man Clear benutzt, hat man also ständig ein äußerst störendes 
Flackern des LCD.

Ich überschreibe daher immer den alten Text mit dem neuen.
Außerdem gebe ich den Text erst nach einem Delay von ~200ms aus, damit 
der Mensch ihn auch lesen kann. Dieses Delay mache ich mit einem Timer, 
so daß nicht unnütz CPU-Zeit verwartet wird.

Wem selbst die 40µs Warten zuviel sind, der packt die Ausgabe in nen 
Timerinterrupt >40µs. Die Ausgaberoutinen schreiben dazu direkt in einen 
SRAM-Puffer und der Timerinterrupt gibt ihn zeichenweise aus.


Peter

von Simon (Gast)


Lesenswert?

Hi,

schon klar  -  aber z.B. clear bei HD44780 bedeutet einfach, 
"vorsichtshalber warten" denn das Bussybyte ist ja nicht sofort da.... 
wenn dann doch keine Rechnung da ist, dann geht's ja schief ...

Gruß

Simon

von Benedikt K. (benedikt)


Lesenswert?

Simon wrote:
> schon klar  -  aber z.B. clear bei HD44780 bedeutet einfach,
> "vorsichtshalber warten" denn das Bussybyte ist ja nicht sofort da....

Wie meinst du das mit dem nicht sofort ?

von Peter (Gast)


Lesenswert?

> Bisher hab ich immer aktiv dann mindestens auf ein Busy-Bit gewartet  -
> oder eine "Liste der Wartenden" geschrieben  -  gibt es da keine
> besseren Ideen ?

wenn's geht, dann lass das gerät einen interrupt auslösen, wenn es 
bereit ist, daten zu empfangen. wenn's nicht geht, dann starte vor dem 
schreibvorgang einen timer-interrupt mit der ungefähren geschwindigkeit 
mit der das gerät daten empfangen kann. die daten, die du ausgeben 
willst, schreibst du in einen FIFO-speicher. am anderen ende des FIFOs 
liest die ISR und sendet die daten zum gerät. ist der FIFO leer, dann 
schaltet die ISR (im falle eines timer-interrupts) den timer wieder ab. 
deine anwendung muss vor dem schreiben in den FIFO den timer-interrupt 
wieder aktivieren, wenn der FIFO gerade leer ist.

...oder du nummst ein kleines RTOS, dann kannste wie bisher in der 
schleife rumidlen und auf das busy-bit warten.

von Simon (Gast)


Lesenswert?

@ Benedikt

Simon wrote:
> schon klar  -  aber z.B. clear bei HD44780 bedeutet einfach,
> "vorsichtshalber warten" denn das Bussybyte ist ja nicht sofort da....

Wie meinst du das mit dem nicht sofort ?


Ist schon sehr lange her, dass ich mir die Routinen programiert habe  - 
aber hatte als Kommentar stehen, dass das Busy-Bit erst nach ein paar 
Zyklen gesetzt wird  und nach einem Clear es richtig spät kommt...

War das damals falsch ?  -  weiß noch, dass ich da einen ganzen Tag 
rumprobiert habe ...

von Benedikt K. (benedikt)


Lesenswert?

Das wäre mir neu. Falls dem so ist, dann ist es zumindest nicht im 
Datenblatt vermerkt, und es würde auch den Sinn eines Busy Bits zu 
nichte machen, wenn man erst mal längere Zeit waren müsste, ehe man das 
Busy Bit abfragen kann.
Die einzige Wartezeit ist die Read/Write Cycle Zeit die bei 1µs liegt.

von Simon (Gast)


Lesenswert?

Hey - ähm habs  grad kurz am STK aufgebaut  -  also bei mir geht das nur 
so:
 ( also ich brauche die Delay trotzdem)
1
{
2
  uint8_t result, count=0;
3
  PORT_LCD_RW |=(1<<PNB_LCD_RW);
4
 
5
  count=0;
6
  while(count<20){asm volatile("nop");count++;}   //TIME CRITICAL !!!
7
 
8
  PORT_LCD_RS &=~(1<<PNB_LCD_RS);
9
  PORT_LCD_DB &= 0b11110000;
10
  DDR_LCD_DB &= 0b11110000;
11
  PORT_LCD_E|=(1<<PNB_LCD_E);
12
 
13
  count=0;
14
  while(count<20){asm volatile("nop");count++;}   //TIME CRITICAL !!!
15
16
  result = (PIN_LCD_DB & 0b00001000);
17
  PORT_LCD_E &=~(1<<PNB_LCD_E);
18
  
19
  count=0;
20
  while(count<20){asm volatile("nop");count++;}   //TIME CRITICAL !!!
21
  
22
  return result;
23
 
24
}

von Tom (Gast)


Lesenswert?

1.3.3. Clear display
Purpose:
- Clears display and returns cursor to home position (upper-left 
corner).
Code:
lcdclear:DO;
DECLARE  lcdregs  BYTE EXTERNAL AUXILIARY;
lcdbusy:PROCEDURE BIT EXTERNAL;
END lcdbusy;
lcdclear:PROCEDURE PUBLIC;

DO WHILE lcdbusy;           /* wait till LCD ready                  */
END;
lcdregs = 001H;             /* clear display, return home           */
CALL TIME(30);              /* wait since busy flag isn't supported */
                            /* while clearing the display           */
END lcdclear;
END lcdclear;



...also nach clear gibt es kein Busy flag

von 6641 (Gast)


Lesenswert?

Ich lese gar nicht erst, sondern warte 10ms. Dadurch bin ich auf 100 
Zeichen pro sekunde limitiert, macht aber nichts.

von Simon (Gast)


Lesenswert?

Hey das war ja eigentlich die Ausgangsfrage  -  legst Du dann eine Liste 
der "To Do" Dinger an  -  oder wie koordinierst Du die Prozesse ?

Gruß

von 6641 (Gast)


Lesenswert?

Na, bei einen 2x20 display zB habe ic ein Array [0..39] und einen index 
auf as aktuelle Zeichen. Da werden immer alle zyklisch rausgehaemmert. 
Eine statusmaschine im main macht das. Nach dem letzten Zeichen wird der 
cursor auf null gesetzt, und nach der ersten Zeile der cursor auf die 
zweite zeile.

von Wolfgang Horn (Gast)


Lesenswert?

Hi, Simon,

Du: "Wie macht Ihr das ? jeder von hat schon mal ein LCD angeschlossen 
-
wartet Ihr nach dem clear tatsächlich dann 5ms in einer Schleife ?"

Alle Eingaben: Per Interrupt-Routine und Ringpuffer.
Alle Ausgaben mit kurzen Wartezeiten: Per Warten.
Alle Ausgaben mit vielleicht auch langen Wartezeiten: State-Machine mit 
Ringpuffer für Ausgang.

Ciao
Wolfgang Horn

von Michael U. (amiga)


Lesenswert?

Hallo,

ich halte es da wie Peter Dannegger: garkein clear.

Ram-Buffer über die Anzahl Zeichen für eine oder mehrere Zeilen, wenn es 
dann nötig ist wird eine Subroutine aufgerufen, die diese oder eben 
mehrere Zeilen zum Display schickt. Alternative hatte wohl mal Hannes 
Lux, wenn ich nicht irre: im sowieso vorhandenen xx ms -IRQ für Timing, 
Entprellen usw. jedesmal 1 Zeichen ausgeben, dann gibt es garkeine 
zusätzlichen Wartezeiten und bei z.B. 10ms IRQ und 32 Zeichen ist das 
Display auch komplett nach 320ms neu geschrieben.

Gruß aus Berlin
Michael

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.