Adressering av CGram?
Adressering av CGram?
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?
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?
-
- Inlägg: 2360
- Blev medlem: 16 september 2003, 17:18:13
- Ort: Dubai, United Arab Emirates
- Kontakt:
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).
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).
Hnn, där hängde jag inte riktigt med.
Så detta fungerar alltså verkligen inte?
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.
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
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.
-
- Inlägg: 2360
- Blev medlem: 16 september 2003, 17:18:13
- Ort: Dubai, United Arab Emirates
- Kontakt:
Mja, om det fungerar så som du skriver så ser jag egentligen inget fel. Allt fungerar som det ska ju. Titta på tabellen nedan.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.
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.
-
- Inlägg: 2360
- Blev medlem: 16 september 2003, 17:18:13
- Ort: Dubai, United Arab Emirates
- Kontakt:
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.
Om det är så, så är det nog dags att se över clock_e och clock_rs_e-rutinerna.
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.
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.
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:
Istället för:
så vad man gör är igentligen att man kör den 2ggr efter varann fast med en liten fördröjning imellan.
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
Kod: Markera allt
e_clock:
ldi temp,0b00000100
out portb,temp
rcall delay
ldi temp,0b00000000
out portb,temp
ret
Senast redigerad av Hedis 16 december 2003, 20:04:20, redigerad totalt 2 gånger.
-
- Inlägg: 2360
- Blev medlem: 16 september 2003, 17:18:13
- Ort: Dubai, United Arab Emirates
- Kontakt:
Du kan utan problem ta bort den sista
å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.
Kod: Markera allt
rcall delay
ldi temp,0b00000000
out portb,temp
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.
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.
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:
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.
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
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
-
- Inlägg: 515
- Blev medlem: 31 maj 2003, 10:42:37
- Ort: Helsingborg
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.
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.
-
- Inlägg: 2360
- Blev medlem: 16 september 2003, 17:18:13
- Ort: Dubai, United Arab Emirates
- Kontakt:
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 :-)
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 :-)