Adressering av CGram?

Lysdioder, Optiska sensorer, Fiberoptik, Displayer, Lasrar, Optiska kopplare
Användarvisningsbild
Hedis
Inlägg: 2488
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Adressering av CGram?

Inlägg av Hedis »

Jag håller på att bli galen på displayen nu. :)
Jag laddar in tecken i cgramet men sedan när jag skall använda dom så ser dom helt missbildade ut.
Man kan ju ladda in 4st (som anropas med tex. $00 - $08 sedan)
Men det måste vara när jag lägger in dom som det blir fel.

Vilken cgram adress skall den ligga i för att hamna i tex $00? $02 osv?

För i en guide jag läste så står det ju att man kan adressera allt mellan 0b0100000 och 0b01111111.

Någon som kan detta bättre än mig?
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Om det är en vanlig LCD som är initierad till att köra 5x7 font så kan du programmera in 8 egna tecken.

Det första tecknet ska defineras in på CG-ram-adresserna 0 till 7. Det andra tecknet ska in i 8 till 15.... det sista tecknet ska in på adresserna 56 till 63.

Men! Eftersom DB7 ska vara 0 och DB6 ska vara 1 när man sätter CG-ramadressen så kan man ju se det som att man ska skicka adresser från 64 till 71 för det första tecknet, adresser mellan 72 och 79 för det andra tecknet osv...

Tänk på att tecknet byggas upp av bara de 5 första bitterna, så värdena som ska in i CG-rammet ska vara vara mellan 0 (pixelraden helt tom) och 31 (pixelraden helt fylld).
Användarvisningsbild
Hedis
Inlägg: 2488
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Inlägg av Hedis »

Hnn, där hängde jag inte riktigt med.
Så detta fungerar alltså verkligen inte?

Kod: Markera allt

cgram3:	
	ldi	temp,0b01000000            ;För adressering?? Då borde det vell hamna i $00?
	out	portc,temp                 ;Data anslutnigen till displayen sitter på portC
	rcall	e_clock                  ;För att klocka E en puls så displayen tar emot funktionen
	rcall	stripe1                  ;Detta är ju då en rutin med dom data som skall laddas in för mitt egna tecken tecknet
	rjmp	startup                   ;För att hoppa till nästa uppgift


stripe1:                            ;Här kommer datan till tecknet som skall laddas in
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ldi	temp,$10
	out	portc,temp
	rcall	e_rs_clock
	ret

e_clock:                            ;Skickar klockpuls för styrkommando
	ldi	temp,0b00000100
	out	portb,temp
	rcall	delay
	ldi	temp,0b00000000
	out	portb,temp
	ret
Jepp det är en Hd44780 display som körs i 5x7 font med 8bits interface.
Det skumma är att så som koden ser ut ovan så får jag in 2 tecken utav 3 korrekt (dock på skumma adresser men jag kan iaf. använda dom) Men det 1:a tecknet fungerar inte alls.
Det tecken som jag lagrar in på 0b01010000 kan jag komma åt på $02, och det som lagras in på 0b01100000 kan kommas åt på $04.
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Det tecken som jag lagrar in på 0b01010000 kan jag komma åt på $02, och det som lagras in på 0b01100000 kan kommas åt på $04.
Mja, om det fungerar så som du skriver så ser jag egentligen inget fel. Allt fungerar som det ska ju. Titta på tabellen nedan.

X=Tecken #
Y=Pixelrad i tecknet

0b01XXXYYY

Tecken $00 = 0b01000000
Tecken $01 = 0b01001000
Tecken $02 = 0b01010000
Tecken $03 = 0b01011000
Tecken $04 = 0b01100000
Tecken $05 = 0b01101000
Tecken $06 = 0b01110000
Tecken $07 = 0b01111000

Dock så skulle jag nog ändra i koden för e_clock. Enligt databladet ska man lägga ut data på bussen först och låta den ligga i minst 60 nS med E-pinnen hög. Sedan sänker man E-pinnen för att klocka in datat till LCD'n. Efter att man sänkt den måste databussen ligga stabil i minst 10 nS. Sedan måste man ju vänta dom uS eller mS som behövs för att instruktionen ska hinna utföras.

Så en korrekt utmatning data eller en instruktion till displayen borde gå till nåt i stil med detta:

Sätt E hög (om den inte redan är det förståss från portinitieringen)
Lägg ut data
Vänta minst 60 nS
Sätt E låg
Vänta minst 10 nS
Sätt E hög igen
Vänta såpass länge att instruktionen hinner utföras.
Användarvisningsbild
Hedis
Inlägg: 2488
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Inlägg av Hedis »

Tack så hemskt mycket för hjälpen.
Det funkar fint med min e_klock rutin så den får finnas kvar :)
Men däremot så kan jag inte skriva någonting i $00 så jag skiter helt enkelt i den ;)

Jag behöver ändå inte alla 8 platser så.....
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Bara för skojs skull. Prova att definiera upp dina egna tecken i bakvänd ordning istället. Börja med att stoppa in definitionen för tecken $07 och arbeta dig bakåt till $00 och se om det är $07 som inte fungerar fungerar då.

Om det är så, så är det nog dags att se över clock_e och clock_rs_e-rutinerna.
Användarvisningsbild
Hedis
Inlägg: 2488
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Inlägg av Hedis »

Jepp provade det nu och det var som du trodde, någon utav e eller e_rs rutinen som är felskriven för att displayen skall hinna med. Men om man låter dens krota första värdet så är det lungt :)

Men jag får nog skriva om det ändå för säkerhets skull så det inte skiter sig när allt är klart.
Jag kör bara processorn på 8Mhz nu (Mega32:an klarar ju 16) så det kanske skiter sig totalt om man dubblar frekvensen.
Användarvisningsbild
Hedis
Inlägg: 2488
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Inlägg av Hedis »

Jahopp, då var det problemet ur världen.

Jag skrev om E_clock rutinen så som du föreslog och alltihop fungerade som en klocka.

Den blev alltså såhär:

Kod: Markera allt

e_clock:				
	ldi	temp,0b00000100
	out	portb,temp
	rcall	delay
	ldi	temp,0b00000000
	out	portb,temp
	rcall	delay
	ldi	temp,0b00000100
	out	portb,temp
	rcall	delay
	ldi	temp,0b00000000
	out	portb,temp
	ret
Istället för:

Kod: Markera allt

e_clock:                          
   ldi   temp,0b00000100 
   out   portb,temp 
   rcall   delay 
   ldi   temp,0b00000000 
   out   portb,temp 
   ret 
så vad man gör är igentligen att man kör den 2ggr efter varann fast med en liten fördröjning imellan.
Senast redigerad av Hedis 16 december 2003, 20:04:20, redigerad totalt 2 gånger.
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Du kan utan problem ta bort den sista

Kod: Markera allt

   rcall   delay 
   ldi   temp,0b00000000 
   out   portb,temp 
åxå skulle jag tro.

Du har väl ändrat både i clock_e och clock_rs_e?

Hur lång är delay()-rutinen?

Har du r/w-signalen kopplad till portb? I sådana fall så borde du polla readyflaggan istället för att delaya. På så sätt så får du alltid optimal fördröjning oavsett vilkken klockfrekvens som AVR'en kör på eller hus snabb just _den_ LCD'n råkar vara.
Användarvisningsbild
Hedis
Inlägg: 2488
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Inlägg av Hedis »

Hehe, när jag återgick till mitt normala program istället för cg-ram testet så visade det sig att det fick lite andra följder.
Ett hopp på 50 steg åt höger blev numera bara 25.

Men om man tog bort det sista där som du sa så blev allt ok igen.

Kod: Markera allt

e_clock:				;Skickar klockpuls för styrkommando
	ldi	temp,0b00000100
	out	portb,temp
	rcall	delay
	ldi	temp,0b00000000
	out	portb,temp
	rcall	delay
	ldi	temp,0b00000100
	out	portb,temp
	ret
EDIT:
Jo E och RS är kopplade till portB. och både e_clock och e_r_clock är ändrade.
Hur menar du med ready-flaggan?
Min delay är iaf. sådanhär:

Kod: Markera allt

delay:					
	ldi	count1,40		
loop1:	ldi	count2,50		
loop2:	dec	count2			
	cpi	count2,1		
	brne	loop2			
	dec	count1			
	cpi	count1,1		
	brne	loop1			
	ret
Jag orkar inte räkna fram hur lång den är men den fungerar iaf. :), och om den skulle börja stula så ökar jag den till det fungerar igen.
henkebenke
Inlägg: 515
Blev medlem: 31 maj 2003, 10:42:37
Ort: Helsingborg

Inlägg av henkebenke »

Det finns en flagga man kan läsa av som indikerar att displayen är redo för nytt kommando, kolla databladet, har för mig att db7 är inblandat.
Användarvisningsbild
Hedis
Inlägg: 2488
Blev medlem: 8 december 2003, 15:10:44
Ort: Vänersborg
Kontakt:

Inlägg av Hedis »

Det blir aldeles för mycket jobb om jag skall börja läsa av ready-flaggan i displayen för varje operation.
Då fungerar delay funktionen fint för mitt användningsområde.


Och nej, R/W pinnen är inte framdragen till portB.
Men visst om man gör extremt tidskrävande program så är det ju en mycket bra utväg.
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Förutom dom 8 datasignalerna så finns det 3 st till. E (enable) RS (Register Select typ Data eller Kommando) och R/W (Read/Write).

När man skickar data till displayen så har man RW-signalen 0'a. För att läsa tillbaka datat i tecken- och displayrammena och även för att kolla om displayen håller på att bearbeta det senaste kommandot fortfarande så sättar man RW-signalen till 1. Ett bra tips innan man gör det är att ställa om som 8 datapinnarna på processorn till ingångar istället, så slipper det bli "kortslutning" mellan processor och LCD när både försöker prata på databussen samtidigt.

För att kolla om LCD är klar med processeringen av föregående kommando och alltså är redo att ta emot ett nytt tecken eller kommando så gör följande.


Sätt alla 8 datapinnarna till input.
Sätt E till 0, RS till 0 och RW till 1
Vänta i minst 220 nS
Sätt E till 1
Vänta i minst 120 nS
Läs av datapinnarna
Sätt RW till 0
Sätt alla 8 datapinnarna till output
Om Databit 7 (högsta bitten) är 0 så är LCD'n redo för nya äventyr :-)
Skriv svar