Hallo Forum, warum habe ich seit kurzem auf der linken Displayhälfte schwarze Streifen? ;-) Ich benutze ein GLCD mit KS0108-Controller von Pollin (TG12864). Dazu ein Atmega1280 mit AVR-Studio 5/6 und JtagIce 3. Als Software zur Ansteuerung wurde die von Holger Klabunde verwendet (modifiziert ). Mich hat das genervt, dass der Bildaufbau so langsam ist. Also nen Puffer dazwischen programmiert und es läuft. Also Software und Hardware funktionierte. Aus zeitmangel lagen die Platinen ne weile rum und als ich fortsetzen wollte...siehe Bild 1. Die Signalpegel der beiden CS-Leitungen habe ich mir mit dem Oszi angeschaut. Sehen gut aus. Auch alle anderen Leitungen habe ich durchgemessen. Also Display ausgelötet und neues rein...selbiges Problem. Das alte Display hab ich mit fliegender Verdrahtung an nen Atmega32 gehangen und es geht, also nicht defekt...Bild 4. Nach Initialisierung und anschließendem CLR-Screen bleiben immer links Streifen stehen...Bild 2. Mit laufender Software siehe Bild 3. Falls die Frage mit dem JTAG kommt: nein, die Leitungen µC <-> LCD sind nicht mit den PINs des JTAG-Interface verbunden. Ich nutze PORTA und PORTJ. Kann es sein, dass der PORTJ ne Macke hat??? Würde mich freuen, wenn sich meinem Problem jemand annehmen würde!!! DANKE!!!
neuer Stand: CS1-Leitung unterbrochen und an einen anderen PIN des µC gelötet. Macht besonders Spass bei nem 100-Pinner lol Und siehe da, dass LCD funktioniert wieder. Alten Zustand wiederhergestellt und Display zeigt gleichen Fehler. Also betreffende Lötstellen nachgelötet...geht immer noch nicht. Heißt für mich, dass ein einzelner PIN des PORTJ defekt ist, da an diesem PORTJ noch andere PINs erfolgreich genutzt werden. Kann das sein, dass gerade dieser PIN durch elektrostatische Aufladung oder ähnliches zerstört wurde? Weiter versteh ich dann aber nicht, warum ich mit Oszi ein sauberes Signal messen konnte. Vdd -> kurz low -> Vdd (siehe CS1.jpg) Vielleicht kann noch jemand etwas dazu beisteuern...
Zeig mal den Schaltplan. Wenn Du Dich über einen langsamen Bildaufbau ärgerst: Durch eine andere Beschaltung kannst Du ihn um einige 100% steigern: nämlich durch Verwendung des External Memory Interfaces Dann musst Du nicht selber die Steuerleitungen per Software setzen, sondern der AVR macht das ganz automatisch für Dich, wenn Du einen Speicherzugriff machst. fchk
@ Frank Der langsame Bildaufbau kommt dadurch zustande, dass jedes Pixel genau gesetzt werden kann. D.h. 128x8 Byte auslesen und wieder neu schreiben. Deshalb schreibe ich zuerst in ein array[128][8] und lasse dieses zyklisch ausgeben. Das geht wesentlich schneller als das wiederholte auslesen aus dem LCD. Speicher bietet der µController ja genug dafür.
Ok. Durch Verwendung des External Memory Interfaces wirds aber nochmal um Faktor x schneller. Statt
1 | DDRA=0xff; |
2 | PORTA=data; |
3 | PORTJ&=~(BIT(CS1)|BIT(WR)); |
4 | PORTJ|=(BIT(CS1)|BIT(WR)); |
reicht dann ein
1 | *cs1data=data; |
fchk
>Ok. Durch Verwendung des External Memory Interfaces wirds aber nochmal >um Faktor x schneller. Statt Theoretisch schon, aber hast du mal einen Ks0108 wirklich am External Memory Interface angeschlossen? Ich erinnere mich da an grottige Zeiten für den Enable Pin.
> Ich erinnere mich > da an grottige Zeiten für den Enable Pin. Die Erinnerung ist korrekt: da sind einige NOP()´s als Wartezeit einzubauen. Hat jemand noch nen Tip wegen dem defekten PORT-Pin?
>Hat jemand noch nen Tip wegen dem defekten PORT-Pin? Häng doch mal ne LED dran und lass die blinken. Dann weisst du es. PORTJ liegt ja weit ausserhalb des Bereiches der per cbi oder sbi angesprochen werden kann. Vieleicht hast du da ein Problem mit atomarem Zugriff. Sprich: Wenn du an PORTJ irgendeinen Pin per Interrupt bearbeitest kannst du Probleme bekommen.
Hmm, ich wusste nicht, dass die Portadressen (PORTJ) oberhalb der 32 I/O-Registern liegen. Steht bestimmt im Datenblatt. Könnte man aus
1 | #define CS1_BIT 0
|
2 | #define CS1_PORT PORTG
|
3 | #define CS1_ON() sbi(CS1_PORT,CS1_BIT);
|
4 | #define CS1_OFF() cbi(CS1_PORT,CS1_BIT);
|
dann dieses machen
1 | #define CS1_BIT 0
|
2 | #define CS1_PORT PORTG
|
3 | #define CS1_ON() CS1_PORT |= (1<<CS1_BIT);
|
4 | #define CS1_OFF() CS1_PORT &= ~(1<<CS1_BIT);
|
??? So programmier ich´s sonst immer. > PORTJ liegt ja weit ausserhalb des Bereiches > der per cbi oder sbi angesprochen werden kann. Aber warum funktioniert denn das LCD dann trotzdem??? Die LED an PJ7 (altes CS1, jetzt PG0 ) blinkt freudig vor sich hin.
>Könnte man aus > >#define CS1_BIT 0 >#define CS1_PORT PORTG >#define CS1_ON() sbi(CS1_PORT,CS1_BIT); >#define CS1_OFF() cbi(CS1_PORT,CS1_BIT); > >dann dieses machen > >#define CS1_BIT 0 >#define CS1_PORT PORTG >#define CS1_ON() CS1_PORT |= (1<<CS1_BIT); >#define CS1_OFF() CS1_PORT &= ~(1<<CS1_BIT); Bringt nichts. Genau das macht der Compiler aus deinen sbi,cbi. |= und &= sind keine atomaren Zugriffe. >Die LED an PJ7 (altes CS1, jetzt PG0 ) blinkt freudig vor sich hin. Na dann erfreut sich der Portpin doch bester Gesundheit;) Du hast ein Softwareproblem.
Das LCD funktioniert jetzt aber wieder, nachdem ich CS1 von PJ7 nach PG0 gelötet habe. Also werden die Register doch angesprochen?! > Bringt nichts. Genau das macht der Compiler aus deinen sbi,cbi. > |= und &= sind keine atomaren Zugriffe. Kannst du mir das erläutern, wie ich den Zugriff auf diese IO-Register in der Programmiersprache C bewerkstelligen kann? Nutze AVR Studio 5, testweise auch die 6. lg AleX
Hier mal ein kleines Beispiel wo man das Problem quasi sehen kann:
1 | //#######################################################################
|
2 | // Das Programm toggelt eine LED im CTC Interrupt jede Sekunde.
|
3 | // In der mainloop wird eine LED am selben Port sehr schnell getoggelt.
|
4 | // Die LED die im Interrupt getoggelt wird leuchtet oder bleibt manchmal
|
5 | // 2s an oder aus. Warum? Denk mal nach;)
|
6 | //
|
7 | //#######################################################################
|
8 | |
9 | #include <avr/io.h> |
10 | #include <avr/interrupt.h> |
11 | #include <avr/pgmspace.h> |
12 | #include <util/delay.h> |
13 | |
14 | ISR (TIMER1_COMPA_vect) |
15 | {
|
16 | PORTA ^= (1<<PA1); |
17 | }
|
18 | |
19 | int main(void) |
20 | {
|
21 | DDRA |= (1<<PA1); |
22 | DDRA |= (1<<PA3); |
23 | |
24 | TCCR1B |= (1<<WGM12) | (1<<CS10 | 0<<CS11 | 1<<CS12); // CTC, prescaler 1024 |
25 | OCR1A = ((F_CPU / 1024) / 1 ) - 1; // 1s |
26 | TIMSK1 |= (1 << OCIE1A); |
27 | |
28 | sei(); |
29 | |
30 | while(1) |
31 | {
|
32 | PORTA ^= (1<<PA3); |
33 | _delay_us(1); |
34 | }
|
35 | |
36 | return(0); |
37 | }
|
PORTA ^= (1<<PA3); kann nicht mit sbi, cbi gemacht werden. Ist also nicht atomar.
Sry, aber da fehlen mir glaub ich noch zu viele Grundkenntnisse. Was bedeutet atomar? Was das Bsp. macht versteh ich so: - PA3 wird duch die while-Schleife aller 1 µs getoggelt - aller 1Mio µs wird die ISR aufgerufen und toggelt den PIN ebenfalls warum soll nun die LED an PA3 manchmal 2 Sekunden an/aus bleiben??? Danke für deine Bemühung!!!
>warum soll nun die LED an PA3 manchmal 2 Sekunden an/aus bleiben???
Nein, die an PA1 bleibt manchmal 2s an/aus;)
das kann ja nur was mit dem schreiben auf dem Register zu tun haben. Das das in irgend einer Weise kollidiert. Der Compiler macht was daraus? - Register in Akku laden - Bit 3 in "verodern" , "verunden" - hier z.b. Einsprung in ISR - Rücksprung aus ISR - Akku zurück in Register schreiben Wenn dann in dem Ablauf die ISR eingreift, ändert die zwar BIT 1 und schreibt das richtig in das Register, das Register wird aber wieder durch den Akku überschrieben und dadurch bleibt die BIT1-Änderung wirkungslos. Ist das richtig so? Meine Grundkenntnisse ASM bestehen leider nur aus einem Semester Mikroprozessortechnik mit 8051 inkl. 2 Versuchen. Ansonsten habe ich mich davor immer gedrückt und das C musste für meine Projekte herhalten.
@trivial dein posting hab ich erst später gelesen... trotzdem Danke. Da steht genau das drin was ich mir gerade zusammen gereimt habe...
Doch noch was aus der UNI mitgenommen ;-) Würde das dann auch ein Pin beeinflussen, welcher als PWM (Hardware) verwendet wird?
>Würde das dann auch ein Pin beeinflussen, welcher als PWM (Hardware) >verwendet wird? Eigentlich nicht. Pins die auf periphere Hardwarefunktionen umgeschaltet werden darf das nicht beeinflussen. Aber man weiss ja nie;) Errata Sheet lesen.
OK belassen wir´s für heute damit. Ich würde mich gern morgen zum Thema noch mal melden. Ich muss erst mal die umgeschriebene Software (LCD-Lib) noch mal durchgehen und auf BITs die verlustig gegangen sein können, untersuchen. Ist der holger (Gast) zufällig der Holger Klabunde, dessen Lib ich verwende??? Prüfung muss ich morgen auch noch schreiben...so ein mist :-) Und nochmals DANKE!!!
Hi >Würde das dann auch ein Pin beeinflussen, welcher als PWM (Hardware) >verwendet wird? Jain. Ein Zugriff auf PORTx hat keinen Einfluss. Einer auf DDRx schon. Atomare Zugriffe sind nur dann relevant, wenn auf ein Register im normalen Programm und in einem oder mehreren Interrupts zugegriffen werden kann. Übrigens kann man die PORTs, auf die nicht mit sbi oder cbi zugegriffen werden kann, atomar togglen in dem man eine 1 in das zugehörige Bit des PIN-Registers schreibt. MfG Spess
>Übrigens kann man die PORTs, auf die nicht mit sbi oder cbi zugegriffen >werden kann, atomar togglen in dem man eine 1 in das zugehörige Bit des >PIN-Registers schreibt. Warnung: Bei älteren AVR geht das nicht. Um die Gutenachtgeschichte abzuschliessen: CS1_PORT |= (1<<CS1_BIT); CS1_PORT &= ~(1<<CS1_BIT); Werden vom Compiler bei den Registern unter 32 durchaus in sbi und cbi umgewandelt wenn man die Optimierung einschaltet. Das ist dann auch atomar. Also nicht gleich in Panik geraten. Aber Mädels, passt auf wenn ihr Portpins in Interrupts verwendet!
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.