Hallo allerseits,
Habe jetzt das Display zum laufen bekommen,
nachdem mir zwischendrinn die Festplatte verreckt war und dadurch auch
alle Projektdaten flöten gegangen sind.
Habe mir jetzt alle nötigen funktionen zusammengeklimpert die ich für
zwei Textgrößen incl. invertierung brauche.
Jetzt habe ich momentan die Funktion zum beschreiben des Display in:
1
intmain(void)
2
{
3
4
while(1)
5
{
6
WDH3224_LOAD_STACK();//Von Dis.Stack --> auf Display
7
}
8
}
9
10
ISR(TIMER0_OVF_vect)
11
{
12
WDH3224_CONTROL_PORT^=(1<<WDH3224_M);//M-Pin toggle ca. 400Hz
Sobald ich jetzt WDH3224_LOAD_STACK() in eine ISR verschiebe
funktioniert das ganze nicht mehr obwohl ich die ISR durch cli() und
sei() verriegel,
so das diese nicht unterbrochen wird. Das die Interrupts abgeschaltet
werden kann man an M gut erkennen, da dort immer wieder für 30ms
unterbrechungen drin sind. Woran kann das liegen? Ich möchte ja nicht
die while(1) Schleife komplett durchlaufen und dann erst das Display
refreshen da das evtl schon zu lang sein kann wenn ich z.B. meine
SD-Card auslese.
Vlt. hat ja jemand eine Idee an was es liegen kann.
hier noch mal die wichtigsten Funktionen fürs Display:
1
unsignedcharLCD_STACK[240][40]={};
2
voidWDH3224_INIT()//alle nötigen Register für PORTs und Timer setzen
Ine ganz schlechte Idee, vom Main und von der Interuptroutine auf das
Display zuzugreifen. So wird das nie was. Ich nicht von der
Interruptroutine auf den Display zugreifen. Eher im Timer ein Flag
setzen und im Main darauf reagieren.
Das Problem ist eben, das das Display keinen eigenen Controller hat, und
ich das alles machen muss darum müssen die Daten spätestens alle 30ms
aufs Display geladen werden, sonst fängt das Bild an zu verblassen. Und
wenn ich jetzt meine SD-Card auslese kann das avtl. länger als 30ms
dauern. Darum wollte ich das ganze jetzt in einen TimerInterrupt packen.
LG
Hallo,
wie lange dauert denn die Ausgabe des kompetten Displayinhalts?
Warscheinlich länger als die 32ms des Timers!
Im übrigen ist es an dieser Stelle besser in der ISR nicht den Inhalt
des kompletten Displays auszugeben, sondern immer eine Zeile und die ISR
mit entsprechend höherer Frequenz laufen zu lassen. Bei Dir werden ja
alle Zeilen nur für einen Bruchteil der Gesamtframerate angezeigt, die
letzte Zeile dafür 30ms lang.
Sascha
die dauer hatte ich gestern gemessen und lag so bei ca. 10ms von einem
FLM (First Line Mark)zum nächsten. Demnach müssten zwischen den
Interrupts 20ms Pause sein.
LG
was genau zeigt denn dein Display an wenn es nicht geht?
UND wenn du in Main und in der ISR auf das Array zugreifst solltest du
es volatile machen.
Sascha
nichts, das Display zeigt einfach nichts an.
Habe alle Funktionen von WDH3224_ in einer externen Header untergebracht
(WDH3224.h) die Unteren Funktionen sind aus dieser rauskopiert.
Muss ich dann das Array trotzdem noch volatile machen?
LG
Chris schrieb:> nichts, das Display zeigt einfach nichts an.> Habe alle Funktionen von WDH3224_ in einer externen Header untergebracht> (WDH3224.h) die Unteren Funktionen sind aus dieser rauskopiert.> Muss ich dann das Array trotzdem noch volatile machen?
wo und in welcher Datei dein Quellcode steht hat doch keinen Einfluss
auf die Verarbeitung des Programms als Gesamtes. Deshalb muss das
volatile trotzdem hin.
Werden den die Steuersignale [FLM/CLK] ausgegeben?
Was hast du überhaupt für einen Controller, und mit welchem Takt läuft
der?
Deinw Timerkonfig und die Frequenzen passen irgendwie nicht mit deinen
Kommentaren zusammen.
Den Timer1 konf. du am besten mal im CTC-Mode, dann kannst du dir das
Rückstellen von TCNT1 schon mal sparen! Und was soll das schreiben von
OCR1A in der ISR?
Sascha
Hallo Sascha,
Habe in der ISR Variante FLM und CLK ehrlichgesagt noch gar nicht
nachgemessen, aber das wäre definitiv schon mal ein anhaltspunkt
gewesen.
Habe einen ATMega1284, mit internen 8MHz. Habe ihn am Freitag mit einem
Externen Oszilator beschaltet, der 12MHz liefert, da ich dachte das vlt.
8Mhz schon zu langsam wären, aber daran lag es nicht. Ich Tippe aber mal
auf deine Idee mit dem volatile vorm Array, kanns aber im Moment leider
nicht ausprobieren, wird aber Morgen sofort gemacht.
LG Chris
ok,
was ich aber noch als Problem sehe, ist die lange Pause, in der nur die
letzte Zeile angezeigt wird, die bis zum nächsten Interrupt vergeht.
Wenn die Ausgabe der 240 Zeilen ca. 10ms dauert, dann wird Zeile 1-239
für je
10ms/240=42us angezeigt, während Zeile 240 für die restlichen 20ms zu
sehen ist. Da glaube ich kaum das da noch Kontrast übrigbleibt!
Mit der Ausgabe in Main erfolgt ja sofort nach der Zeile 240 wieder
Zeile 1 und da geht das natürlich.
Du musst den Timer mit der Framerate * 240 laufen lassen
30Hz * 240 = 7.2kHz -> ca. 140us und innerhalb der ISR dann die 40Byte
einer Zeile ausgeben, dann verteilt sich die Leuchtdauer aller Pixel
gleichmäßig über die gesamte Framezeit.
Sascha
Chris schrieb:>>if(n>240)n=0;>if(i>40)i=0;>if(n==0) //da das Array aus [240][40] besteht bis 40 zählen> {> WDH3224_FRAME_SET_HIGH;> WDH3224_CLOCK_SET_HIGH;> WDH3224_DATA_PORT = LCD_STACK[0][i] >> 4; //da 4 Bit Bus, Bit shift um MSB
zu bekommen
> WDH3224_CLOCK_SET_LOW; //Daten laden>> WDH3224_CLOCK_SET_HIGH;> WDH3224_DATA_PORT = LCD_STACK[0][i]; // kein Bit shift für LSB> WDH3224_CLOCK_SET_LOW; //Daten laden> WDH3224_FRAME_SET_LOW;> }>>>> if(n>0) //nun das ganze für die übrigen 239 Zeilen> {> WDH3224_LOAD_SET_HIGH;> WDH3224_LOAD_SET_LOW;>>>> WDH3224_CLOCK_SET_HIGH;> WDH3224_DATA_PORT = LCD_STACK[n][i] >> 4;> WDH3224_CLOCK_SET_LOW;>> WDH3224_CLOCK_SET_HIGH;> WDH3224_DATA_PORT = LCD_STACK[n][i];> WDH3224_CLOCK_SET_LOW;> }> if(i>40)n++;> i++;
OK ich baue also hier die for schleifen raus und lasse i+n durch die ISR
hochzählen und sollte diese dann ihren Maximalwert erreichen, setze ich
sie wieder 0.
Die 7.2kHz sollte ich ja mit Timer1 Locker hinbekommen.
Interruptfrquent müsste ja wie folgt aussehen
(F_CPU(12MHz)/Prescaler(1))/OCR1A(63869)= 7198,56
Bzw. bei F_CPU= 8MHz, Precaler= 1,OCR1A = 64425 ist F= 7200.72Hz
LG Chris
Chris schrieb:> Die 7.2kHz sollte ich ja mit Timer1 Locker hinbekommen.
jo, währe sogar mit einem 8Bit'er möglich
> Interruptfrquent müsste ja wie folgt aussehen> (F_CPU(12MHz)/Prescaler(1))/OCR1A(63869)= 7198,56>> Bzw. bei F_CPU= 8MHz, Precaler= 1,OCR1A = 64425 ist F= 7200.72Hz
ja,
aber nimm ruhig mal den CTC-Mode, dann ist OCR=1667 und der Zähler wird
bei erreichen dieses Wertes automatisch wieder auf Null gestellt.
Sascha
Ok soweit läuft das jetzt auch in der ISR.
Allerdings haut das mit den Zeiten nicht so ganz hin.
Habe jetzt ewig mit den Zeiten gespielt, bekomme aber das Bild nicht
flimmerfrei.
Code habe ich wie folgt abgeändert:
1
if(zeile>239)zeile=0;
2
//WDH3224_M_SET_HIGH;
3
if(zeile==0)//da das Array aus [240][40] besteht bis 40 zählen
4
{
5
WDH3224_FRAME_SET_HIGH;
6
WDH3224_LOAD_SET_HIGH;
7
8
WDH3224_LOAD_SET_LOW;
9
10
11
for(unsignedinti=0;i<40;i++)
12
{
13
WDH3224_CLOCK_SET_HIGH;
14
WDH3224_DATA_PORT=LCD_STACK[0][i]>>4;//da 4 Bit Bus, Bit shift um MSB zu bekommen
15
WDH3224_CLOCK_SET_LOW;//Daten laden
16
17
WDH3224_CLOCK_SET_HIGH;
18
WDH3224_DATA_PORT=LCD_STACK[0][i];// kein Bit shift für LSB
19
WDH3224_CLOCK_SET_LOW;//Daten laden
20
}
21
22
23
WDH3224_FRAME_SET_LOW;
24
}
25
26
27
28
if(zeile>0)//nun das ganze für die übrigen 239 Zeilen
29
{
30
WDH3224_LOAD_SET_HIGH;
31
WDH3224_LOAD_SET_LOW;
32
33
34
for(unsignedinti=0;i<40;i++)
35
{
36
WDH3224_CLOCK_SET_HIGH;
37
WDH3224_DATA_PORT=LCD_STACK[zeile][i]>>4;
38
WDH3224_CLOCK_SET_LOW;
39
40
WDH3224_CLOCK_SET_HIGH;
41
WDH3224_DATA_PORT=LCD_STACK[zeile][i];
42
WDH3224_CLOCK_SET_LOW;
43
}
44
}
45
46
zeile++;
47
//WDH3224_M_SET_LOW;
Und die ISRs sehen jetzt so aus:
1
ISR(TIMER0_OVF_vect)
2
{
3
WDH3224_CONTROL_PORT^=(1<<WDH3224_M);
4
}
5
6
ISR(TIMER1_COMPA_vect)
7
{
8
9
WDH3224_LOAD_STACK();
10
TCNT1=0;
11
}
Register:
1
OCR1A=300;//TimerCounter1 Compare Register laden
2
TCCR1B|=(1<<CS10);//Timer starten, Vorteiler auf 1
Chris schrieb:> Ok soweit läuft das jetzt auch in der ISR.> Allerdings haut das mit den Zeiten nicht so ganz hin.> Habe jetzt ewig mit den Zeiten gespielt, bekomme aber das Bild nicht> flimmerfrei.> Register:
1
OCR1A=300;//TimerCounter1 Compare Register laden
2
TCCR1B|=(1<<CS10);//Timer starten, Vorteiler auf 1
das währen ja 40kHz und nicht 7.2kHz
nimm mal (bei 12MHz):
mit WDH3224_LOAD_SET_** sollten eigentlich am Ende der Ausgabe der
Zeilendaten diese übernommen werden, so wie du das jetzt hast werden die
reingeschobenen Daten erst mit der nächsten Zeile gelatcht - sollte aber
eigentlich auch gehen.
Sascha
Hallo Sascha,
habe mal deine Änderungen 1:1 übernommen und das ganze ist eigentlich
nur noch schlimmer geworden, der Bildaufbau ist super träge und das
flimmern sogar noch stärker.
Sascha Weber schrieb:> mit WDH3224_LOAD_SET_** sollten eigentlich am Ende der Ausgabe der>> Zeilendaten diese übernommen werden
irgendwie müssen doch die anliegenden Daten übernommen werden..?
LG Chris
Chris schrieb:> Hallo Sascha,>> habe mal deine Änderungen 1:1 übernommen und das ganze ist eigentlich> nur noch schlimmer geworden, der Bildaufbau ist super träge und das> flimmern sogar noch stärker.
hmm
hast du evl. noch die CKDIV8 Fuse drin? Kannst du an FLM messen was du
dort für eine Frequenz hast?
Von was sprichst du bei Bildaufbau, wird irgendwas veränderliches in den
Bildpuffer geschrieben?
Mit 30Hz Framerate @12MHz wird auf alle Fälle mehr als 50% der
Rechleistung schon für die Bildausgabe gebraucht. Müsste man mal
anschauen, ob sich die Ausgabeschleifen noch optimieren lassen.
> irgendwie müssen doch die anliegenden Daten übernommen werden..?
ohne mir jetzt das Datenblatt deines Displays angeschaut zu haben,
werden die Daten mit CLK reingeschoben, und am Ende mit einem Impuls an
LP übernommen.
Sascha
Sascha Weber schrieb:> ohne mir jetzt das Datenblatt deines Displays angeschaut zu haben
habe ich auch nicht ;) konnte keins finden welches direkt für mein
Display ist. Habe mir dann hier über die Suche alle möglichen anderen
Datenblätter gesucht, bis ich eines hatte, wo das Timingdiagram
verständlich genug für mich war :) und habe dann nach diesem meinen
Software geschrieben.
Sascha Weber schrieb:> hast du evl. noch die CKDIV8 Fuse drin?
Habe ich nicht drin, passiert mir aber ständig und ich such jedes mal
wieder den Fehler ;)
Sascha Weber schrieb:> Kannst du an FLM messen was du> dort für eine Frequenz hast?
werde ich mal machen!
Sascha Weber schrieb:> Von was sprichst du bei Bildaufbau, wird irgendwas veränderliches in den> Bildpuffer geschrieben?
Ich kann zusehen wie langsam die Buchstaben erscheinen...
Ja, sonst wäre das langweilig wenn an der anzeige nichts passiert ;)
Es werden (sollen, denn hier Kämpfe ich auch noch dran, auf dem
Testboard gehts im Gerät selber nicht) Daten von einer SD-Card in
abhängigkeit einer gemessenen Leitung angezeigtwerden.
LG Chris
Hallo Sascha,
habe das flimmern jetzt weg.
Habe den ganzen tag rumgespielt und hatte zum Schluss das Gefühl, das
der Controller zu langsam ist. Da ich an FLM 17,5Hz gemessen habe habe
ich jetzt mal anstatt 12MHz; 24MHz Takt angelegt und siehe da FLM hat
jetz 35Hz und es gibt kein flimmern mehr. Hatte das zuvor schon über die
Software versucht, aber das hat nicht so recht funktioniert.
Jetzt kämpfe ich nur noch mit der SD-Card und dem FT232 der immer nur
sporadich was sendet aber wenn, dann ist es richtig.
LG Chris
Chris schrieb:> Hallo Sascha,>> habe das flimmern jetzt weg.> Habe den ganzen tag rumgespielt und hatte zum Schluss das Gefühl, das> der Controller zu langsam ist. Da ich an FLM 17,5Hz gemessen habe habe> ich jetzt mal anstatt 12MHz; 24MHz Takt angelegt und siehe da FLM hat> jetz 35Hz und es gibt kein flimmern mehr.
hast du da jetzt den OCR-Wert halbiert?
> Jetzt kämpfe ich nur noch mit der SD-Card und dem FT232 der immer nur> sporadich was sendet aber wenn, dann ist es richtig.
da hat dein Controller ja ordentlich was zu tun.
Sascha
Sascha Weber schrieb:> hast du da jetzt den OCR-Wert halbiert?
jaein... ich habe bestimmt 45-60min damit verbracht den OCR wert in
sämtliche richtungen zu veränder, von sehr langsam OCR = 60000 zu sehr
schnell OCR = 50. Habe auch den CTC mode (1<<WGM12) wieder aktiviert und
hatte mich dann irgendwo bei OCR = 2850 eingependelt. Alles was
langsamer wahr brachte mir dicke horizontale, von oben nach unten
laufende Streifen. Alles was schneller war beschehrte mir Armeisenkrieg
und irgendwann ein schwarzes Bild. Als ich dann einem Kollegen sagte das
ich glaube der Prozessor packt das in der Zeit nicht mehr meinte der nur
F_CPU erhöhen.
Zum Glück habe ich CBUS0 des FT232 an XTAL1 des AVR so das ich ziemlich
einfach von 12 auf 24MHz wechseln konnte. Nach dem einem Reset zum
übernehmen der werte, dachte ich erst oh misst das hat auch wieder nicht
geklappt, da ich nur den vorgeladenen Display-Stack sehen konnte ohne
irgendwelche Änderungen. Irgendwann hat dann das Display kurz gezuckt
und es war ein eins A flimmerfreies Bild zu sehen wie es sein sollte.
Sascha Weber schrieb:> da hat dein Controller ja ordentlich was zu tun.
auf jeden Fall und das ist noch nicht alles.
Dazu wollen noch einige Schieberegister bedient werden und ein ADC
Bis hier her schon mal vielen vieln Damk für die tolle Hilfe
Chris