HD44780-kompatibel display: Kommer inte över till CGRAM...
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Kan det vara så enkelt som att displayen inte är redo för kommando när Du skickar CGRAM-adressen?
Det finns några kommandon som är ultralångsamma, bl.a. "clear display'. Det kan ta upp till 64ms vill jag minnas att det står i databladet. Skickas något innan pågående kommando är klart kan allehanda magiska fenomen uppträda...
Efter att Du skrivit till CGRAM måste något kommando ges som återställer till DDRAM för att Du skall kunna skriva tecken
Kan tillägga att jag precis provat att skriva CGRAM i 4-bit mode och det fungerade alldeles utmärkt, men inte förän jag lagt till en stadig fördröjning efter "clear display"... Använde 100ms delay för att vara helt säker på att den räckte.
Det finns några kommandon som är ultralångsamma, bl.a. "clear display'. Det kan ta upp till 64ms vill jag minnas att det står i databladet. Skickas något innan pågående kommando är klart kan allehanda magiska fenomen uppträda...
Efter att Du skrivit till CGRAM måste något kommando ges som återställer till DDRAM för att Du skall kunna skriva tecken
Kan tillägga att jag precis provat att skriva CGRAM i 4-bit mode och det fungerade alldeles utmärkt, men inte förän jag lagt till en stadig fördröjning efter "clear display"... Använde 100ms delay för att vara helt säker på att den räckte.
- JimmyAndersson
- Inlägg: 26470
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Icecap:
"I databladet är det tydligt angivit att man ska vänta ung. 4,1ms från power-on/Reset till man börjar prata med displayen."
Det är ingen som helst risk (eller ens chans) att jag kommer i närheten av det.
Jag måste sträcka mig lite för att slå på labaggregatet, sedan kollar jag så allt reagerar som det ska
innan jag startar programmet. Det lär gå 8-10 sekunder efter power-on tills jag tar en pratstund med den.
Marta:
"Kan det vara så enkelt som att displayen inte är redo för kommando när Du skickar CGRAM-adressen?"
Om man måste vänta längre än de 3 sekunder som jag provat med så lär den aldrig bli redo.
De flesta av testerna är gjorda med en väntetid på 1 sekund innan jag skickar CGRAM-adressen.
Efter varje rad kod så har jag åtminstone 10ms paus, så det tar närmare 100ms
från det att jag t.ex sätter DB-pinnarna tills jag är klar med att ha tänt och släckt E-pinnarna.
Så när jag t.ex skrivit text så har jag sett bokstav för bokstav komma fram,
som om texten kom från ett äldre modem.
Samma sak när jag gjort eget tecken och markören har hoppat fram ett steg för varje byte.
Nu gjorde jag ett litet php-program som knåpar ihop alla initierings-rader.
Jag använder samma initierings-data som innan.
(Det blev 35 rader eftersom jag ville vara lite tydlig med upplägget.) Såhär ser det ut:
När man kör den koden så resulterar det som sagt i en ny och ren initiering:
(Lite lång, men jag ville ta med den för att visa.)
Den initierings-koden lägger jag efter följande:
Det är alltså allt.
Resultatet av detta?
Mjo.. precis som innan.
När jag startat labaggregatet, väntat en stund och kör programmet så går initieringen fel.
När jag då väntar ett par sekunder och kör programmet igen så blir det rätt.
Är det nu man ska sätta sig i ett hörn och prata med tapeterna?
Nä jag sparar det till senare.
Jag funderar istället på att kavla upp ärmarna och göra ett kretskort
så att de enda sladdarna som finns är de för I2C-anslutningen.
(Har tyvärr inte möjlighet att sätta kortet direkt på Raspberryn.)
"I databladet är det tydligt angivit att man ska vänta ung. 4,1ms från power-on/Reset till man börjar prata med displayen."
Det är ingen som helst risk (eller ens chans) att jag kommer i närheten av det.
Jag måste sträcka mig lite för att slå på labaggregatet, sedan kollar jag så allt reagerar som det ska
innan jag startar programmet. Det lär gå 8-10 sekunder efter power-on tills jag tar en pratstund med den.
Marta:
"Kan det vara så enkelt som att displayen inte är redo för kommando när Du skickar CGRAM-adressen?"
Om man måste vänta längre än de 3 sekunder som jag provat med så lär den aldrig bli redo.

De flesta av testerna är gjorda med en väntetid på 1 sekund innan jag skickar CGRAM-adressen.
Efter varje rad kod så har jag åtminstone 10ms paus, så det tar närmare 100ms
från det att jag t.ex sätter DB-pinnarna tills jag är klar med att ha tänt och släckt E-pinnarna.
Så när jag t.ex skrivit text så har jag sett bokstav för bokstav komma fram,
som om texten kom från ett äldre modem.

Samma sak när jag gjort eget tecken och markören har hoppat fram ett steg för varje byte.
Nu gjorde jag ett litet php-program som knåpar ihop alla initierings-rader.
Jag använder samma initierings-data som innan.
(Det blev 35 rader eftersom jag ville vara lite tydlig med upplägget.) Såhär ser det ut:
Kod: Markera allt
<?php
$init_array = array(
"00110000", "00110000", "00110000",
"00100000",
"00100000", "10000000", "00000000", "11110000", "00000000", "00010000", "00000000", "01100000");
$rs = 0;
$e1e2 = "11"; //Binärt i strängform. E1 och E2.
$wait = "0.1"; //antal sekunder. Dvs 100ms.
echo 'bus.write_byte_data(DEVICE, OLATA, 0b0000000', $rs, ') # RS<br>';
echo 'sleep(', $wait, ')<br>';
echo "<br>";
foreach ($init_array as $init_temp)
{
$db = substr($init_temp, 0, 4);
//DB-pinnarna
$byte_db = substr_replace($init_temp, $rs, 7, 1); //Ersätter RS med rätt för stunden.
//E-pinnarna
$byte_eon_temp = substr_replace($init_temp, $e1e2, 5, 2); //Ersätter E1 och E2 med rätt för stunden.
$byte_eon = substr_replace($byte_eon_temp, $rs, 7, 1); //Ersätter RS med rätt för stunden. Till E on.
$byte_eoff = $byte_db;
echo 'bus.write_byte_data(DEVICE, OLATA, 0b', $byte_db, ') # DB<br>';
echo 'sleep(', $wait, ')<br>';
echo 'bus.write_byte_data(DEVICE, OLATA, 0b', $byte_eon, ') # E on<br>';
echo 'sleep(', $wait, ')<br>';
echo 'bus.write_byte_data(DEVICE, OLATA, 0b', $byte_eoff, ') # E off<br>';
echo 'sleep(', $wait, ')<br>';
echo "#<br>";
}
?>
När man kör den koden så resulterar det som sagt i en ny och ren initiering:
(Lite lång, men jag ville ta med den för att visa.)
Kod: Markera allt
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # RS
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00110000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00110110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00110000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00110000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00110110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00110000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00110000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00110110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00110000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00100000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00100110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00100000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00100000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00100110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00100000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b10000000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b10000110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b10000000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b11110000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b11110110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b11110000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00010000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00010110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00010000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b01100000) # DB
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01100110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01100000) # E off
sleep(0.1)
#
Den initierings-koden lägger jag efter följande:
Kod: Markera allt
import smbus
from time import *
import sys
import getopt
#============================================================
#
# 40 x 4 LCD <- MCP23017 <- I2C <- Raspberry Pi model B
#
#
# PORT - LCD
# -----+----
# GPA0 - RS
# GPA1 - E1
# GPA2 - E2
# GPA3 - Reserverad for R/W.
# Tills vidare ar R/W kopplad till GND, dvs Write-lage.
#
# GPA4 - DB4
# GPA5 - DB5
# GPA6 - DB6
# GPA7 - DB7
#
#=============================================================
# - - - - - -
# Definiera adresser
DEVICE = 0x22 # Adressen till min krets
# A
IODIRA = 0x00 # Register for pin direction. In or Out
OLATA = 0x0A # Register for outputs (When IOCON.BANK=1)
GPIOA = 0x09 # Register for inputs (When IOCON.BANK=1)
# B
IODIRB = 0x10
OLATB = 0x1A
GPIOB = 0x19
#
IOCON = 0x04
GPPUA = 0x06
GPPUB = 0x16
# - - - - - -
bus = smbus.SMBus(1) # I2C-bussen och vilken kanal.
#Bank 1. No mirror in INT. Sequential operation enabled.
bus.write_byte_data(DEVICE, IOCON, 0b10000000)
# Pull-up disabled for inputs
bus.write_byte_data(DEVICE, GPPUA, 0b00000000)
bus.write_byte_data(DEVICE, GPPUB, 0b00000000)
# Set all GPA and GPB pins as outputs by setting
# all bits of IODIRA and IODIRB register to 0
bus.write_byte_data(DEVICE,IODIRA, 0x00)
bus.write_byte_data(DEVICE,IODIRB, 0x00)
# Set output all 7 output bits to 0 on GPA and GPB
bus.write_byte_data(DEVICE,OLATA, 0)
bus.write_byte_data(DEVICE,OLATA, 0)
# - - - - - -
Det är alltså allt.
Resultatet av detta?
Mjo.. precis som innan.
När jag startat labaggregatet, väntat en stund och kör programmet så går initieringen fel.
När jag då väntar ett par sekunder och kör programmet igen så blir det rätt.
Är det nu man ska sätta sig i ett hörn och prata med tapeterna?
Nä jag sparar det till senare.
Jag funderar istället på att kavla upp ärmarna och göra ett kretskort
så att de enda sladdarna som finns är de för I2C-anslutningen.
(Har tyvärr inte möjlighet att sätta kortet direkt på Raspberryn.)
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Här är min initiering som är testad och fungerar. Displayen är en 2x20.
Hoppas det är tydligt nog, kan annars skicka programkoden i morgon.
5ms väntan mellan allt som skickas utom enskilda nibblepar för att forma en hel byte. Där är väntan 100µs.
Detta skickas som enkla nibbles. Hexadecimalt och avser bit 4..7
3
3
3
2
Från och med här skickas data som två niblbes. Hexadecimalt och avser byten i dess helhet.
28
14
0E
06
02
01
Lång väntan 100ms.
Nu sätts CGRAM
40
RS sätts till 1
Teckendata skickas
Tillbaka till DDRAM pos 0
RS sätts till 0
80
----klart----
Hoppas det är tydligt nog, kan annars skicka programkoden i morgon.
5ms väntan mellan allt som skickas utom enskilda nibblepar för att forma en hel byte. Där är väntan 100µs.
Detta skickas som enkla nibbles. Hexadecimalt och avser bit 4..7
3
3
3
2
Från och med här skickas data som två niblbes. Hexadecimalt och avser byten i dess helhet.
28
14
0E
06
02
01
Lång väntan 100ms.
Nu sätts CGRAM
40
RS sätts till 1
Teckendata skickas
Tillbaka till DDRAM pos 0
RS sätts till 0
80
----klart----
- JimmyAndersson
- Inlägg: 26470
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Jag jämförde våra initieringar:
(Från och med rad 7 så är datan uppdelad på två nibble.
Det är alltså bara bit 7-4 som tas om hand från dessa bytes.)
Du kör "Shift cursor to the right. AC is increased by 1" två gånger.
Jag sätter istället igång displayen med synlig markör och blink.
Jag kör visst aldrig "Return home"...
När jag testade din initiering så blev det först likadant. Dvs:
Startade labaggregatet. Väntade en stund. Körde initieringen. Det blev fel.
Väntade en stund igen och körde initieringen igen. Då blev det rätt.
Men varje gång jag kör din initiering så händer det en massa under tiden som den tar emot varje byte.
T.ex så kan alla pixlar tändas för ett ögonblick, markören hoppar ner till mitten av rad 2 för en stund. osv.
Men när initieringen är klar så är markören där den ska och allt ser ok ut.
Det blev aningen bättre när jag lade till längre fördröjningar (100ms) mellan varje nibble skickades.
Då hoppar bara markören till kolumn 3 på rad 1 och står där tills initieringens slutfas.
Då hoppar markören till kolumn 1 och allt ser ut som det ska.
Det går förmodligen att ordna genom att låta displayen vara avstängd (0b000010xx) under tiden den initieras.
Men resten, att sätta CGRAM, har jag inte lyckats med.
Jag använde din initiering.
Väntade 3 sekunder.
Satte CGRAM.
Väntade 3 sekunder.
RS sätts till 1.
Väntade 3 sekunder.
Så här långt blir allt ok.
Men när jag sedan skickar teckendatan så blir det exakt samma tecken på displayen som under alla mina försök.
Har du möjlighet att visa exakt vad du skickar när du skickar teckendata?
Som du gjorde med initieringen t.ex.
Om jag t.ex vill ha ett tecken som ser ut såhär:
00000001
00000011
00000111
00001111
00000111
00000011
00000001
00000000
Så delar jag upp varje rad till 2 nibble. T.ex så blir rad 3 ovan såhär:
Skickar 0000 0000 (bit 7-4 är för mitt tecken. bit 3-0 är utfyllnad så det blir en byte.)
Skickar 0111 0000 (samma förklaring som ovan.)
I detta har jag ju även bakat in E och RS. RS är bit 0. E-pinnarna är bit 1 och 2.
Så det som skickas ut blir i själva verket såhär:
Skickar 0000 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0000 0001 (E1 och E2 = 0. RS = 1.)
Det var ena nibblen, den höga. Nu nästa, den låga:
Skickar 0111 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0111 0001 (E1 och E2 = 0. RS = 1.)
När jag skickar 0x40, dvs sätter CGRAM så gör jag på samma sätt som ovan,
men med motsvarande nibbles och med RS = 0.
Jag kan inte hitta något fel där.
Men jag skulle bli glad om någon ser något galet.
edit:
Finns det något jag kan testa, rent hårdvarumässigt mellan portexpandern och displayen?
Pull-down, filter, osv. Blybunker?
(Från och med rad 7 så är datan uppdelad på två nibble.
Det är alltså bara bit 7-4 som tas om hand från dessa bytes.)
Kod: Markera allt
Martas Jimmys Marta Jimmy
00110000 00110000 8 bit. (initiering) Samma
00110000 00110000 8 bit. (initiering) Samma
00110000 00110000 8 bit. (initiering) Samma
00100000 00100000 4 bit. Samma
00100000 00100000 4 bit. 2 line mode. Samma
10000000 10000000 5x8 dot format. Samma
00010000 00000000 Shift cursor to the right Display is turned on.
01000000 11110000 AC is increased by 1 Cursor on. Blink on.
00010000 00000000 Shift cursor to the right Clear display
01000000 00010000 AC is increased by 1
00000000 00000000 Cursor/blin moves to left and Samma
01100000 01100000 DDRAM adress is increased by 1 Samma
00000000 Return home
00100000
00000000 Clear display
00010000
Jag sätter istället igång displayen med synlig markör och blink.
Jag kör visst aldrig "Return home"...
När jag testade din initiering så blev det först likadant. Dvs:
Startade labaggregatet. Väntade en stund. Körde initieringen. Det blev fel.
Väntade en stund igen och körde initieringen igen. Då blev det rätt.
Men varje gång jag kör din initiering så händer det en massa under tiden som den tar emot varje byte.
T.ex så kan alla pixlar tändas för ett ögonblick, markören hoppar ner till mitten av rad 2 för en stund. osv.
Men när initieringen är klar så är markören där den ska och allt ser ok ut.
Det blev aningen bättre när jag lade till längre fördröjningar (100ms) mellan varje nibble skickades.
Då hoppar bara markören till kolumn 3 på rad 1 och står där tills initieringens slutfas.
Då hoppar markören till kolumn 1 och allt ser ut som det ska.
Det går förmodligen att ordna genom att låta displayen vara avstängd (0b000010xx) under tiden den initieras.
Men resten, att sätta CGRAM, har jag inte lyckats med.
Jag använde din initiering.
Väntade 3 sekunder.
Satte CGRAM.
Väntade 3 sekunder.
RS sätts till 1.
Väntade 3 sekunder.
Så här långt blir allt ok.
Men när jag sedan skickar teckendatan så blir det exakt samma tecken på displayen som under alla mina försök.
Har du möjlighet att visa exakt vad du skickar när du skickar teckendata?
Som du gjorde med initieringen t.ex.
Om jag t.ex vill ha ett tecken som ser ut såhär:
00000001
00000011
00000111
00001111
00000111
00000011
00000001
00000000
Så delar jag upp varje rad till 2 nibble. T.ex så blir rad 3 ovan såhär:
Skickar 0000 0000 (bit 7-4 är för mitt tecken. bit 3-0 är utfyllnad så det blir en byte.)
Skickar 0111 0000 (samma förklaring som ovan.)
I detta har jag ju även bakat in E och RS. RS är bit 0. E-pinnarna är bit 1 och 2.
Så det som skickas ut blir i själva verket såhär:
Skickar 0000 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0000 0001 (E1 och E2 = 0. RS = 1.)
Det var ena nibblen, den höga. Nu nästa, den låga:
Skickar 0111 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0111 0001 (E1 och E2 = 0. RS = 1.)
När jag skickar 0x40, dvs sätter CGRAM så gör jag på samma sätt som ovan,
men med motsvarande nibbles och med RS = 0.
Jag kan inte hitta något fel där.
Men jag skulle bli glad om någon ser något galet.
edit:
Finns det något jag kan testa, rent hårdvarumässigt mellan portexpandern och displayen?
Pull-down, filter, osv. Blybunker?
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Kan Du klocka in data i logikanalysatorn från en extern klocka, så den registrerar vad som skickas och visar det i numerisk form istället för kurvor? Det skulle vara bra för att se vad det är som tas emot vid displayen.
Jag skickar inget dubbelt, det är 14 och sedan 0E som skickas. Du har missat 0E.
Gör två rutiner, en för att skicka en nibble och en annan för att skicka en hel byte i form av två nibbles. Verifiera dem så Du vet med absolut säkerhet att de fungerar och använd dem sedan för att hantera displayen. Då blir allt mycket enklare och överskådligare med mindre möjliheter för fel.
Jag skickar inget dubbelt, det är 14 och sedan 0E som skickas. Du har missat 0E.
Gör två rutiner, en för att skicka en nibble och en annan för att skicka en hel byte i form av två nibbles. Verifiera dem så Du vet med absolut säkerhet att de fungerar och använd dem sedan för att hantera displayen. Då blir allt mycket enklare och överskådligare med mindre möjliheter för fel.
- JimmyAndersson
- Inlägg: 26470
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Oj, jag måste ha missat när jag räknade om till binär visning.
Här är den rättade listan:
Därmed är det bara detta som min initiering saknar:
Shift cursor to the right.
AC is increased by 1.
Return home.
Inget speciellt som kan göra att displayen förlorar fattningen.
När jag kör den korrigerade initieringen så blir det exakt samma resultat som innan.
Över till ditt senaste inlägg:
"Kan Du klocka in data i logikanalysatorn från en extern klocka, så den registrerar vad som skickas och visar det i numerisk form"
Det kan jag ordna, men jag förstår inte riktigt.
Jag lär ju bara få en lång rad med just 1 0 1 0 1 0 1 osv.
Möjligen en extra etta eller nolla varje gång klockan och logikanalysatorns klocka hamnar i "rätt" läge,
men det är ju helt normalt när man har två saker som går i olika frekvens.
"Det skulle vara bra för att se vad det är som tas emot vid displayen."
Okej... (tänker jag och ser ut som ett frågetecken).
Hur ska jag koppla det?
Menar du att jag ska ta en tråd som nu går mellan klockan och portexpandern
och istället koppla klockan i ena änden och logikanalysatorn i andra?
Berätta lite mer om vad du söker så kan jag fixa det.
"Gör två rutiner, en för att skicka en nibble och en annan för att skicka en hel byte i form av två nibbles."
Sådana har jag ju redan. De använde jag fram till mitt 3e inlägg i tråden.
Sedan dess har jag pratat direkt med I2C-bussen, utan rutinerna.
Vill du alltså att jag ska göra om rutinerna och börja använda dem igen?
Inga problem i såfall.
(Jag frågar bara för att vara säker, så jag inte sätter mig och gör något som inte alls var det du sökte.)
De rutiner jag har nu fungerar såhär:
Nibble_high = indata AND 0b11110000
Nibble_low = (indata AND 0b00001111) << 4 #dvs shift 4 åt vänster.
Förmodligen det enklaste sättet man kan göra det på.
Jag har testat rutinerna genom att stoppa in alla möjliga tal mellan 0 och 255.
Någonstans i tråden finns utdatan från dessa rutiner.
Jag missade ju förresten att gå tillbaka till en av bilderna jag postade tidigare. Den här:
http://www.varion.se/elektronik/temp3/L ... helhet.gif
Du skrev om en negativ flank:
"På den mellersta bilden från logikanalysatorn har en negativ flank hamnat så den går rakt igenom där pixlarna tar ett språng i sidled. Samma språng syns på databitarna. Det kan ge intrycket att dessa händelser är samtidiga, men jag antar att det inte är så?"
Tänker du på den som kommer strax innan RS blir hög i bilden ovan?
Tyvärr har jag inte kvar resultatet av den loggningen, men jag stoppade in bilden i Photoshop och förstorade:
http://www.varion.se/elektronik/temp3/L ... t_zoom.gif
Där ser man att flanken kommer samtidigt på alla de kanalerna.
(Jag släcker ju E-pinnarna samtidigt som datapinnarna.(I koden är E-pinnarna är höga i 10,01ms.)
När sådana nedförsbackar kommer samtidigt överallt och med jämna mellanrum, så brukar det ju bero på att två klockor
hamnar i just det läge där den ena "slår runt" precis efter den andra.
Dessutom har jag ju zoomat ut för att kunna visa hela initieringen.
Då blir ju sneda streck utan antialiasing lite förändrade.
På första bilden jag postade, dvs:
http://www.varion.se/elektronik/temp3/L ... s_init.gif
så ser man hur flankerna ser ut i riktig inzoomning.
Där ser man även tiderna bättre.
--
Jag håller även på att göra schema till ett kretskort med display och portexpandern.
Så om du eller någon annan tycker att jag ska lägga till filter, pull-down, osv, på datapinnarna
så skulle jag behöva veta det i kväll.
Här är den rättade listan:
Kod: Markera allt
Martas Jimmys Marta Jimmy
00110000 00110000 8 bit. (initiering) Samma
00110000 00110000 8 bit. (initiering) Samma
00110000 00110000 8 bit. (initiering) Samma
00100000 00100000 4 bit. Samma
00100000 00100000 4 bit. 2 line mode. Samma
10000000 10000000 5x8 dot format. Samma
00010000 00000000 Shift cursor to the right Display is turned on.
01000000 11110000 AC is increased by 1 Cursor on. Blink on.
00000000 00000000 Display is turned on. Clear display
11100000 00010000 Cursor on. Blink off.
00000000 00000000 Cursor/blin moves to left and Samma
01100000 01100000 DDRAM adress is increased by 1 Samma
00000000 Return home
00100000
00000000 Clear display
00010000
Shift cursor to the right.
AC is increased by 1.
Return home.
Inget speciellt som kan göra att displayen förlorar fattningen.
När jag kör den korrigerade initieringen så blir det exakt samma resultat som innan.
Över till ditt senaste inlägg:
"Kan Du klocka in data i logikanalysatorn från en extern klocka, så den registrerar vad som skickas och visar det i numerisk form"
Det kan jag ordna, men jag förstår inte riktigt.
Jag lär ju bara få en lång rad med just 1 0 1 0 1 0 1 osv.
Möjligen en extra etta eller nolla varje gång klockan och logikanalysatorns klocka hamnar i "rätt" läge,
men det är ju helt normalt när man har två saker som går i olika frekvens.
"Det skulle vara bra för att se vad det är som tas emot vid displayen."
Okej... (tänker jag och ser ut som ett frågetecken).

Hur ska jag koppla det?
Menar du att jag ska ta en tråd som nu går mellan klockan och portexpandern
och istället koppla klockan i ena änden och logikanalysatorn i andra?
Berätta lite mer om vad du söker så kan jag fixa det.
"Gör två rutiner, en för att skicka en nibble och en annan för att skicka en hel byte i form av två nibbles."
Sådana har jag ju redan. De använde jag fram till mitt 3e inlägg i tråden.
Sedan dess har jag pratat direkt med I2C-bussen, utan rutinerna.
Vill du alltså att jag ska göra om rutinerna och börja använda dem igen?
Inga problem i såfall.

(Jag frågar bara för att vara säker, så jag inte sätter mig och gör något som inte alls var det du sökte.)
De rutiner jag har nu fungerar såhär:
Nibble_high = indata AND 0b11110000
Nibble_low = (indata AND 0b00001111) << 4 #dvs shift 4 åt vänster.
Förmodligen det enklaste sättet man kan göra det på.
Jag har testat rutinerna genom att stoppa in alla möjliga tal mellan 0 och 255.
Någonstans i tråden finns utdatan från dessa rutiner.
Jag missade ju förresten att gå tillbaka till en av bilderna jag postade tidigare. Den här:
http://www.varion.se/elektronik/temp3/L ... helhet.gif
Du skrev om en negativ flank:
"På den mellersta bilden från logikanalysatorn har en negativ flank hamnat så den går rakt igenom där pixlarna tar ett språng i sidled. Samma språng syns på databitarna. Det kan ge intrycket att dessa händelser är samtidiga, men jag antar att det inte är så?"
Tänker du på den som kommer strax innan RS blir hög i bilden ovan?
Tyvärr har jag inte kvar resultatet av den loggningen, men jag stoppade in bilden i Photoshop och förstorade:
http://www.varion.se/elektronik/temp3/L ... t_zoom.gif
Där ser man att flanken kommer samtidigt på alla de kanalerna.
(Jag släcker ju E-pinnarna samtidigt som datapinnarna.(I koden är E-pinnarna är höga i 10,01ms.)
När sådana nedförsbackar kommer samtidigt överallt och med jämna mellanrum, så brukar det ju bero på att två klockor
hamnar i just det läge där den ena "slår runt" precis efter den andra.
Dessutom har jag ju zoomat ut för att kunna visa hela initieringen.
Då blir ju sneda streck utan antialiasing lite förändrade.
På första bilden jag postade, dvs:
http://www.varion.se/elektronik/temp3/L ... s_init.gif
så ser man hur flankerna ser ut i riktig inzoomning.
Där ser man även tiderna bättre.
--
Jag håller även på att göra schema till ett kretskort med display och portexpandern.
Så om du eller någon annan tycker att jag ska lägga till filter, pull-down, osv, på datapinnarna
så skulle jag behöva veta det i kväll.

- JimmyAndersson
- Inlägg: 26470
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Jag skulle vilja få en sak bekräftat:
Om jag t.ex vill ha ett tecken som ser ut såhär:
00000001
00000011
00000111
00001111
00000111
00000011
00000001
00000000
Så delar jag upp varje rad till 2 nibble. T.ex så blir rad 3 ovan såhär:
Skickar 0000 0000 (bit 7-4 är för mitt tecken. bit 3-0 är utfyllnad så det blir en byte.)
Skickar 0111 0000 (samma förklaring som ovan.)
I detta har jag ju även bakat in E och RS. E-pinnarna är bit 1 och 2. RS är bit 0.
Så det som skickas ut blir i själva verket såhär:
Skickar 0000 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0000 0001 (E1 och E2 = 0. RS = 1.)
Det var ena nibblen, den höga. Nu nästa, den låga:
Skickar 0111 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0111 0001 (E1 och E2 = 0. RS = 1.)
När jag skickar 0x40, dvs sätter CGRAM så gör jag på samma sätt som ovan,
men med motsvarande nibbles och med RS = 0.
Jag kan inte hitta något fel där.
Men jag skulle bli glad om någon ser något galet.
Om jag t.ex vill ha ett tecken som ser ut såhär:
00000001
00000011
00000111
00001111
00000111
00000011
00000001
00000000
Så delar jag upp varje rad till 2 nibble. T.ex så blir rad 3 ovan såhär:
Skickar 0000 0000 (bit 7-4 är för mitt tecken. bit 3-0 är utfyllnad så det blir en byte.)
Skickar 0111 0000 (samma förklaring som ovan.)
I detta har jag ju även bakat in E och RS. E-pinnarna är bit 1 och 2. RS är bit 0.
Så det som skickas ut blir i själva verket såhär:
Skickar 0000 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0000 0001 (E1 och E2 = 0. RS = 1.)
Det var ena nibblen, den höga. Nu nästa, den låga:
Skickar 0111 0111 (E1 och E2 = 1. RS = 1.)
Skickar 0111 0001 (E1 och E2 = 0. RS = 1.)
När jag skickar 0x40, dvs sätter CGRAM så gör jag på samma sätt som ovan,
men med motsvarande nibbles och med RS = 0.
Jag kan inte hitta något fel där.
Men jag skulle bli glad om någon ser något galet.
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Det galna är att du skickar data OCH kontrollsignaler samtidig! Det är inte nödvändigtvis själva datan du överför som blir fel men din data kontra handskakningstiming är helt klart fel!
Du måste skriva en byte som följer:
1: Lägg ut MSB.
2: Lyfta Enable.
3: Sänka Enable.
4: Lägg ut LSB.
5: Lyfta Enable.
6: Sänka Enable.
Varje byte ut till displayen blir alltså minst 6 st skrivningar till bus-expandern!
Du måste skriva en byte som följer:
1: Lägg ut MSB.
2: Lyfta Enable.
3: Sänka Enable.
4: Lägg ut LSB.
5: Lyfta Enable.
6: Sänka Enable.
Varje byte ut till displayen blir alltså minst 6 st skrivningar till bus-expandern!
- JimmyAndersson
- Inlägg: 26470
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Jag förenklade visst lite för mycket i min förklaring där. 
Det är svårt att få med lagom mycket.
För mycket och det blir oöverskådligt. (Någon som vill se alla 358 rader kod?)
För lite och det fattas något.
Jag backar bandet lite:
Först och främst använder jag Martas initiering av displayen.
Det gör jag på samma sätt som koden nedan, men förstås annorlunda för de första bitar som inte ska delas upp.
Sedan RS = 0.
Tänder bit 6 för att hamna i CGRAM. Det gör jag på samma sätt som koden nedan.
Därefter sätter jag RS = 1.
Och därefter datan som ska till CGRAM.
För att t.ex skicka 00000111 :
#
bus.write_byte_data(DEVICE, OLATA, 0b00000001) # DB (MSB)
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000111) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000001) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b01110001) # DB (LSB)
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01110111) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01110001) # E off
sleep(0.1)
osv för de övriga byte som bildar ett tecken.
(E1 och E2 är bit 1 och 2. RS är bit 0.)
Är detta rätt? Det är så jag skickar data till CGRAM.
Men även med Martas initiering och adressering av CGRAM
så hamnar teckendatan på displayen istället för i CGRAM.
Vad 17 gör jag för galet. Allt fungerar utom just att "ställa sig" i CGRAM.

Det är svårt att få med lagom mycket.
För mycket och det blir oöverskådligt. (Någon som vill se alla 358 rader kod?)
För lite och det fattas något.
Jag backar bandet lite:
Först och främst använder jag Martas initiering av displayen.
Det gör jag på samma sätt som koden nedan, men förstås annorlunda för de första bitar som inte ska delas upp.
Sedan RS = 0.
Tänder bit 6 för att hamna i CGRAM. Det gör jag på samma sätt som koden nedan.
Därefter sätter jag RS = 1.
Och därefter datan som ska till CGRAM.
För att t.ex skicka 00000111 :
#
bus.write_byte_data(DEVICE, OLATA, 0b00000001) # DB (MSB)
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000111) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000001) # E off
sleep(0.1)
#
bus.write_byte_data(DEVICE, OLATA, 0b01110001) # DB (LSB)
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01110111) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01110001) # E off
sleep(0.1)
osv för de övriga byte som bildar ett tecken.
(E1 och E2 är bit 1 och 2. RS är bit 0.)
Är detta rätt? Det är så jag skickar data till CGRAM.
Men även med Martas initiering och adressering av CGRAM
så hamnar teckendatan på displayen istället för i CGRAM.
Vad 17 gör jag för galet. Allt fungerar utom just att "ställa sig" i CGRAM.

Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Här är programkod befunnits fungera. Rutiner för att initiera LCD inklusive laddning av CGRAM med ÅÄÖ samt för att skicka kommandon och tecken till displayen. Tyvärr är det inte samma tabulering här som i min editor så texten blir tilltufsad.
Kod: Markera allt
SWECHR .EQ @/2
.RL HS 04,0A,0E,11,1F,11,11,80 Å
.RL HS 0A,80,0E,11,1F,11,11,80 Ä
.RL HS 0A,80,0E,11,11,11,0E,80 Ö
.RL HS 00
*** SEND DATA TO DISPLAY
*
LCDOUT SEF REGSEL SELECT DATA REG
.8OUT LOD LCDPAD,A SAVE CHAR
SWN LCDPAD
JSR .4OUT PUT FIRST NIBBLE
SWN LCDPAD SWAP NIBBLES AND PUT SECOND ONE
.4OUT JSR DELAY.100
LOD A,#$F0 CLEAR OUT DATA BITS
AND PORTC,A
LOD A,LCDPAD GET DATA
AND A,#$0F MASK OUT DATA BITS
ORR PORTC,A PUT DATA
NOP
SEF STROBE SHAKE STROBE
NOP
CLF STROBE
RTS DONE
.4BIT CLF REGSEL SELECT COMMAND REG
LOD LCDPAD,A SAVE CHAR
JSR .4OUT
JMP DELAY.5000 LONG WAIT, JUST TO BE SURE
.CMD CLF REGSEL SELECT COMMAND REG
JSR .8OUT
JMP DELAY.5000 LONG WAIT, JUST TO BE SURE
****** INIT LCD DISPLAY
*
LCDINI CLF STROBE INIT LCD STROBE
CLF REGSEL SELECT CONTROL REGISTER
JSR DELAY.5000 WAIT 15000US
JSR DELAY.5000
JSR DELAY.5000
* DISPLAY RESET
LOD A,#$03 PUT FUNCTION SET CMD
JSR LCDOUT.4BIT
LOD A,#$03 PUT FUNCTION SET CMD ONCE MORE
JSR LCDOUT.4BIT
LOD A,#$03 PUT FUNCTION SET CMD A LAST TIME
JSR LCDOUT.4BIT
* DISPLAY CONFIG
LOD A,#$02 SET 4-BIT MODE
JSR LCDOUT.4BIT
LOD A,#$28 SETUP DISPLAY
JSR LCDOUT.CMD
LOD A,#$14
JSR LCDOUT.CMD
LOD A,#$0E TURN ON DISPLAY AND CURSOR
JSR LCDOUT.CMD
LOD A,#$06 SET ENTRY MODE
JSR LCDOUT.CMD
LOD A,#$02
JSR LCDOUT.CMD
LOD A,#$01 CLEAR DISPLAY
JSR LCDOUT.CMD
LOD A,#20 THIS TAKES TIME...
LOD PAD2,A
.CLRWT JSR DELAY.5000
DSZ PAD2
JMP .CLRWT
JSR SETCG LOAD CGRAM
LOD A,#$80 BACK TO DDRAM, POS0
JSR LCDOUT.CMD
RTS
* INIT CGRAM
SETCG LOD A,#$40 ADDRESS CGRAM
JSR LCDOUT.CMD
LOD A,#SWECHR INIT ADR PNT
LOD PAD3,A
.CGINIT LOD A,PAD3 GET PNT
INC PAD3 NXT POS
JSR TBLRD.0 GET DATA
ORR A,#0 ZERO = AT END?
SFC Z
RTS YES-ALL DONE !! EXITPOINT HERE !!
AND A,#$7F MASK OFF HIGH BIT = NONZERO FILLER FOR BLANK
JSR LCDOUT PUT DATA
JMP .CGINIT DO NXT
*** DELAYS
* .5000 = 5000µs
* .100 = 100µs
*
DELAY
.5000 STZ PAD0 SETUP DELAY COUNT FOR 5000 US
LOD A,#12
LOD PAD1,A
.N5000 DSZ PAD0 COUNT DOWN INNER LOOP
JMP .N5000 INNER DELAY LOOP
DSZ PAD1 COUNT DOWN OUTER DELAY LOOP
JMP .N5000 OUTER DELAY LOOP
RTS DELAY DONE
.100 LOD A,#70 COUNT FOR 100 US DELAY
LOD PAD0,A SET IT
.N100 DSZ PAD0 COUNT DOWN
JMP .N100 DELAY LOOP
RTS DELAY DONE
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
När det går troll i ett program brukar jag alltid börja om med att lägga till bit för bit av koden och testa så allt verkligen fungerar som det är tänkt innan nästa bit läggs till. På det sättet brukar felet komma fram så småningom. Det är alltid extra svårt att hitta fel när det finns många bugs som samverkar och påverkar varandra...
Så mitt råd är att göra enkla rutiner från grunden och testa dessa noggrant innan nästa steg tas. Det brukar hjälpa.
Angående logikanalysatorn så var tanken att koppla E som klocka och låta denna klocka in signalerna i analysatorn som om de klockades in i displayen. Är där tidsmarginaler på alla sidor om flankerna så bör den då "se" detsamma som displayen gör och eventuella magiska fenomen på vägen kan upptäckas.
Har Du förresten möjlighet att skicka data som SPI istället för I2C? Förutsatt att det även finns en vanlig portpinne tillgänglig kan Du då använda vanliga skiftregister med latch på utgången och komma ifrån både portexpander och 4-bit mode.
Så mitt råd är att göra enkla rutiner från grunden och testa dessa noggrant innan nästa steg tas. Det brukar hjälpa.
Angående logikanalysatorn så var tanken att koppla E som klocka och låta denna klocka in signalerna i analysatorn som om de klockades in i displayen. Är där tidsmarginaler på alla sidor om flankerna så bör den då "se" detsamma som displayen gör och eventuella magiska fenomen på vägen kan upptäckas.
Har Du förresten möjlighet att skicka data som SPI istället för I2C? Förutsatt att det även finns en vanlig portpinne tillgänglig kan Du då använda vanliga skiftregister med latch på utgången och komma ifrån både portexpander och 4-bit mode.
- JimmyAndersson
- Inlägg: 26470
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Jag börjar med ditt förra inlägg:
Tack för koden!
Vad använder du för assembler/kompilerare? Jag tycker instruktionerna skiljer sig lite från Microchip's vanliga.
Det är två saker i koden som jag inte är helt säker på:
1)
I LCD.8OUT så byter du bara plats på de båda nibbles med SWN,
men i LCD.4OUT så använder du tricket med AND för att göra (till synes) samma sak.
Varför två olika sätt?
2)
I SETCG.CGINIT så maskar du bort högsta biten (AND A,#$7F).
Vad jag kan se så förekommer den biten bara i ÅÄÖ-datans sista byte.
Först tänkte jag att det kanske var någon markör för "slut på data",
men direkt efter så verkar du anropa LCDOUT.
Så det verkar vara något jag missar här.
Över till ditt senaste inlägg:
"När det går troll i ett program brukar jag alltid börja om med att lägga till bit för bit av koden"[klipp]
Samma här. Jag är på version 2.C och den här sista versionen har jag rensat totalt många gånger.
Som jag skrivit så har jag inte ens några rutiner kvar.
Allt görs med anrop direkt till I2C-busssen.
Men inte ens det fungerar för att hamna i CGRAM.
Jag kör med din initiering och det fungerar.
Men så fort jag lägger till adresseringen av CGRAM så hamnar datan i DDRAM istället.
I mitt förra inlägg finns koden för hur jag gör för att hamna i CGRAM.
Nu har varken du eller Icecap (eller någon annan) skrivit att den koden varken är rätt eller fel,
så jag antar att den är rätt. Ni brukar ju ha falkögon när det gäller att hitta fel.
"Så mitt råd är att göra enkla rutiner från grunden och testa dessa noggrant innan nästa steg tas. Det brukar hjälpa."
Rutiner är ju ett bra sätt att få kod mer kompakt och snygg,
men det är ju även en risk eftersom det är svårare att följa hopp mm.
En "rak" lista med alla instruktioner under varandra är svår att gå vilse i,
så länge det finns kommentarer som "milstenar".
Nackdelen är förstås att en "rak" lista med instruktioner blir lång.
Men eftersom principen är likadan genom hela initieringen
(även anropet till CGRAM görs ju på samma sätt)
så behöver man bara läsa ca 6 rader för att få grepp om exakt hur det är gjort.
Därför har jag alltid sett en rak lista med instruktioner som mer grundläggande
och en bra utgångspunkt för att undvika så många fel som möjligt.
För att få det bästa av båda världar så är dessutom min lista med instruktioner
automatiskt genererad av mitt php-script som använder indata från din initiering.
Om något skulle vara fel med det scriptet så skulle man definitivt få konstig utdata redan från början.
Så jag kan inte komma på hur jag skulle kunna göra det hela mer grundläggande.
Plockar jag bort det enda som inte fungerar (anropet till CGRAM) så plockar jag
ju bort just det som jag försöker få att fungera.
Och att försöka göra det anropet mer grundläggande än att skriva direkt till I2C-bussen finns nog inte.
(Ja om man inte ska stoppa dit tre momentana brytare och knacka in ettor och nollor helt manuellt.
)
Jag kommer nog inte på något mer att prova när det gäller mjukvaran.
"Angående logikanalysatorn så var tanken att koppla E som klocka och låta denna klocka in signalerna"[klipp]
Nu förstår jag. Intressant idé.
Jag ska testa det.
"Har Du förresten möjlighet att skicka data som SPI istället för I2C? Förutsatt att det även finns en vanlig portpinne tillgänglig kan Du då använda vanliga skiftregister med latch på utgången och komma ifrån både portexpander och 4-bit mode."
SPI istället för I2C är inga problem. Men jag är osäker på om jag har några shiftregister av rätt sort.
Jag vet att jag har 4-bitars med parallell input och det går ju att ordna det med dem (och lite annat),
men det hade varit smidigt med något mer färdigt. Så det inte riskerar att bli en till felkälla.
Jag ska titta runt lite och se vad jag kan ordna.
Jo det här med att jag valt köra displayen som 4-bit istället för 8-bit:
Portexpandern har två portar med 8 pinnar i varje.
Till den behöver jag ansluta displayen och 5st knappar.
För att göra det enkelt så tar jag 1st pinne per knapp.
Då får jag över 11st för displayen.
Kör jag displayen i 8-bit så går det åt 12 pinnar. Därav mitt val att köra displayen som 4-bit.
Hm, visst ja...
Det blir lite rörigt om jag kör displayen över SPI och knapparna på en hel portexpander med I2C...
Men som test är det inga problem.
Tack för koden!

Vad använder du för assembler/kompilerare? Jag tycker instruktionerna skiljer sig lite från Microchip's vanliga.
Det är två saker i koden som jag inte är helt säker på:
1)
I LCD.8OUT så byter du bara plats på de båda nibbles med SWN,
men i LCD.4OUT så använder du tricket med AND för att göra (till synes) samma sak.
Varför två olika sätt?
2)
I SETCG.CGINIT så maskar du bort högsta biten (AND A,#$7F).
Vad jag kan se så förekommer den biten bara i ÅÄÖ-datans sista byte.
Först tänkte jag att det kanske var någon markör för "slut på data",
men direkt efter så verkar du anropa LCDOUT.
Så det verkar vara något jag missar här.
Över till ditt senaste inlägg:
"När det går troll i ett program brukar jag alltid börja om med att lägga till bit för bit av koden"[klipp]
Samma här. Jag är på version 2.C och den här sista versionen har jag rensat totalt många gånger.
Som jag skrivit så har jag inte ens några rutiner kvar.
Allt görs med anrop direkt till I2C-busssen.
Men inte ens det fungerar för att hamna i CGRAM.
Jag kör med din initiering och det fungerar.
Men så fort jag lägger till adresseringen av CGRAM så hamnar datan i DDRAM istället.
I mitt förra inlägg finns koden för hur jag gör för att hamna i CGRAM.
Nu har varken du eller Icecap (eller någon annan) skrivit att den koden varken är rätt eller fel,
så jag antar att den är rätt. Ni brukar ju ha falkögon när det gäller att hitta fel.

"Så mitt råd är att göra enkla rutiner från grunden och testa dessa noggrant innan nästa steg tas. Det brukar hjälpa."
Rutiner är ju ett bra sätt att få kod mer kompakt och snygg,
men det är ju även en risk eftersom det är svårare att följa hopp mm.
En "rak" lista med alla instruktioner under varandra är svår att gå vilse i,
så länge det finns kommentarer som "milstenar".
Nackdelen är förstås att en "rak" lista med instruktioner blir lång.
Men eftersom principen är likadan genom hela initieringen
(även anropet till CGRAM görs ju på samma sätt)
så behöver man bara läsa ca 6 rader för att få grepp om exakt hur det är gjort.
Därför har jag alltid sett en rak lista med instruktioner som mer grundläggande
och en bra utgångspunkt för att undvika så många fel som möjligt.
För att få det bästa av båda världar så är dessutom min lista med instruktioner
automatiskt genererad av mitt php-script som använder indata från din initiering.
Om något skulle vara fel med det scriptet så skulle man definitivt få konstig utdata redan från början.
Så jag kan inte komma på hur jag skulle kunna göra det hela mer grundläggande.
Plockar jag bort det enda som inte fungerar (anropet till CGRAM) så plockar jag
ju bort just det som jag försöker få att fungera.
Och att försöka göra det anropet mer grundläggande än att skriva direkt till I2C-bussen finns nog inte.
(Ja om man inte ska stoppa dit tre momentana brytare och knacka in ettor och nollor helt manuellt.

Jag kommer nog inte på något mer att prova när det gäller mjukvaran.
"Angående logikanalysatorn så var tanken att koppla E som klocka och låta denna klocka in signalerna"[klipp]
Nu förstår jag. Intressant idé.
Jag ska testa det.
"Har Du förresten möjlighet att skicka data som SPI istället för I2C? Förutsatt att det även finns en vanlig portpinne tillgänglig kan Du då använda vanliga skiftregister med latch på utgången och komma ifrån både portexpander och 4-bit mode."
SPI istället för I2C är inga problem. Men jag är osäker på om jag har några shiftregister av rätt sort.
Jag vet att jag har 4-bitars med parallell input och det går ju att ordna det med dem (och lite annat),
men det hade varit smidigt med något mer färdigt. Så det inte riskerar att bli en till felkälla.
Jag ska titta runt lite och se vad jag kan ordna.

Jo det här med att jag valt köra displayen som 4-bit istället för 8-bit:
Portexpandern har två portar med 8 pinnar i varje.
Till den behöver jag ansluta displayen och 5st knappar.
För att göra det enkelt så tar jag 1st pinne per knapp.
Då får jag över 11st för displayen.
Kör jag displayen i 8-bit så går det åt 12 pinnar. Därav mitt val att köra displayen som 4-bit.
Hm, visst ja...
Det blir lite rörigt om jag kör displayen över SPI och knapparna på en hel portexpander med I2C...
Men som test är det inga problem.
- JimmyAndersson
- Inlägg: 26470
- Blev medlem: 6 augusti 2005, 21:23:33
- Ort: Oskarshamn (En bit utanför)
- Kontakt:
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Jag är eventuellt något på spåren.
Började mäta på displayens bana för bit 6 och där var det inte helt ren 1a när det skulle.
Det fladdrade lite upp och ner. Så är det inte på de andra datapinnarna.
Förtydligande:
Mäter jag direkt på portexpandern utan displayen inkopplad så finns inte detta fladder.
Misstänkte ett tag labplattan så jag lödde sladden direkt mot IC'ns ben och det tog inte bort felet.
Så det är något med kontakten på displayen eller något som fångas upp av displayens kretskortsbana.
Jag ska fortsätta spåra och se vad det beror på.
edit: Usch, det hade jag inte sett... Flera SMD-komponenter på displayens baksida
(3-4st motstånd och lite avkopplingskondingar) är lite dåligt lödda. Ska löda om dem och se.
edit 2: Det blev bättre. Inget fladder på bit 6, men ingen skillnad i resultat på displayen.
Dvs det som skulle hamna i CGRAM hamnar i DDRAM.
Började mäta på displayens bana för bit 6 och där var det inte helt ren 1a när det skulle.
Det fladdrade lite upp och ner. Så är det inte på de andra datapinnarna.
Förtydligande:
Mäter jag direkt på portexpandern utan displayen inkopplad så finns inte detta fladder.
Misstänkte ett tag labplattan så jag lödde sladden direkt mot IC'ns ben och det tog inte bort felet.
Så det är något med kontakten på displayen eller något som fångas upp av displayens kretskortsbana.
Jag ska fortsätta spåra och se vad det beror på.
edit: Usch, det hade jag inte sett... Flera SMD-komponenter på displayens baksida
(3-4st motstånd och lite avkopplingskondingar) är lite dåligt lödda. Ska löda om dem och se.
edit 2: Det blev bättre. Inget fladder på bit 6, men ingen skillnad i resultat på displayen.
Dvs det som skulle hamna i CGRAM hamnar i DDRAM.
Re: HD44780-kompatibel display: Kommer inte över till CGRAM.
Du behöver att systematisera din kontroll! Gör din mjukvara så att den uteslutande skriver ett steg åt gången. Sedan mäter du och noterar alla pinnarna (kan göras med lite LED för enkelhetens skull) och sedan kommer nästa steg. Och jag menar att ett steg UTESLUTANDE är en enda uppdatering av portexpandern! Sedan får du en lång kedja av värden som du sedan kan stycka ihop till ett vettigt flöde.
Jag hoppas även att du vet om att under initieringen tror displayen att det är 8-bit fram till att det får kommandot om att det är 4-bit som gäller, detta betyder att det under initieringen skrivs ett antal "halva" kommandon!
Jag hoppas även att du vet om att under initieringen tror displayen att det är 8-bit fram till att det får kommandot om att det är 4-bit som gäller, detta betyder att det under initieringen skrivs ett antal "halva" kommandon!
Re: Någon som använt MCP23017 med LCD och egna tecken (CGRAM
Datablad
Det viktiga för mig är att du rent faktisk vet exakt vad som händer. Gör en testcase som initierar "som du brukar" men lägg till en knapp och säkra dig att den inte bouncer. Varje skrivning av data till displayen får först ske när du trycker på knappen, det får bara ske en enda skrivning per tryck och du kollar vad som sker.
Skriv för allt i världen ner vad du ser, vilka steg osv. Alltså alla databit, Enable, R/S, R/W osv. Räkna '0' och '1' så länge du inte får tveksamma spänningsvärden.
Så det blir:
- Notera startvärden!
*tryck*
- En nippel data läggs ut på databitten. Notera.
*tryck*
- Enable höjs. Notera - ALLA bit!
*tryck*
- Enable sänks. Notera ALLA bit!
osv osv.
Detta sätt är långsamt, tråkigt - och ger ett stensäkert bild av vad som händer! Den tid det tar att göra såhär är definitivt kortare än det (som jag uppfattar det) hattande och antagande som du har gjort tidigare.
Har du en LSA kan det såklart gå snabbare men den skal klockas av tid eller SCL, inte Enable! Det blir många data att leta igenom men du hittar problemet och när det är känd är resten enkelt.
Det viktiga för mig är att du rent faktisk vet exakt vad som händer. Gör en testcase som initierar "som du brukar" men lägg till en knapp och säkra dig att den inte bouncer. Varje skrivning av data till displayen får först ske när du trycker på knappen, det får bara ske en enda skrivning per tryck och du kollar vad som sker.
Skriv för allt i världen ner vad du ser, vilka steg osv. Alltså alla databit, Enable, R/S, R/W osv. Räkna '0' och '1' så länge du inte får tveksamma spänningsvärden.
Så det blir:
- Notera startvärden!
*tryck*
- En nippel data läggs ut på databitten. Notera.
*tryck*
- Enable höjs. Notera - ALLA bit!
*tryck*
- Enable sänks. Notera ALLA bit!
osv osv.
Detta sätt är långsamt, tråkigt - och ger ett stensäkert bild av vad som händer! Den tid det tar att göra såhär är definitivt kortare än det (som jag uppfattar det) hattande och antagande som du har gjort tidigare.
Har du en LSA kan det såklart gå snabbare men den skal klockas av tid eller SCL, inte Enable! Det blir många data att leta igenom men du hittar problemet och när det är känd är resten enkelt.