Sida 1 av 2
Hur skriver jag till en LCD 16x2 ?
Postat: 3 november 2018, 21:43:06
av Al_Bundy
Nu ska jag använda mig utav en I/O expanderare vid namn MCP23017 och en LCD 16x2.
Det jag börjar med är att sätta upp min MCP23017 på addressen 0x20 och kollar om jag har anslutning. Det har jag!
Där efter så skriver jag följande kommando:
Kod: Markera allt
this.i2CDevice.write(0x13, (byte) 0x04); // RS = 0, R/W = 0, E = 1 på B-sidan hos MCP23017
this.i2CDevice.write(0x12, (byte) 0x30); // 0 0 1 1 0 0 x x - Function set på A-sidan hos MCP23017
this.i2CDevice.write(0x12, (byte) 0x08); // 0 0 0 0 1 0 0 0 - Turn of display på A-sidan hos MCP23017
this.i2CDevice.write(0x12, (byte) 0xE); // 0 0 0 0 1 1 1 0 - Turn on cursor på A-sidan hos MCP23017
this.i2CDevice.write(0x12, (byte) 0x06); // 0 0 0 0 0 1 1 0 - Entry Mode set på A-sidan hos MCP23017
this.i2CDevice.write(0x13, (byte) 0x06); // RS = 0, R/W = 1, E = 1 på A-sidan hos MCP23017
this.i2CDevice.write(0x12, (byte) 0x06); // 0 1 0 1 0 0 1 1 - Write S på A-sidan hos MCP23017
this.i2CDevice.write(0x13, (byte) 0x00); // RS = 0, R/W = 0, E = 0 på B-sidan hos MCP23017
Som ska symbolisera koden nedan på bilden. Det jag gör är att jag först sätter RS = 0, R/W = 0 och E = 1 och sedan skriver jag mina ettor och nollor. Där efter sätter jag E = 0 som slut. Men allt jag ser är bara 16 stycken fulla 5x10 rutor på LCD:n på översta raden 16x1. Mer än så blir det inte. Jag tänkte skriva ut ett "S", men icke!
Någon som har en förklaring?
http://hades.mech.northwestern.edu/imag ... J1602A.pdf
http://ww1.microchip.com/downloads/en/d ... 01952c.pdf
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 3 november 2018, 21:55:24
av metric
Först och främst måste displayen initieras.
Sen måste du pauser mellan kommandona eller läsa bysy flaggan.
https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 3 november 2018, 21:59:44
av Al_Bundy
Är inte det som är "Function Set"?
Edit:
Här är hur man initialisera LCD:n. Men detta säger mig inget angående "Busy flag". Vad är det?
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 3 november 2018, 22:16:55
av metric
Jag får 41 träffar på "busy flag" i pdf:en jag länkade till?
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 3 november 2018, 22:22:53
av ToPNoTCH
Tycker det saknas en del för att konfigurera MCP23017 med.
Om pinnar skall vara input/output (IODIR) exempelvis.
Default är dom input.
Du får nog läsa lite mer i databladet.
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 3 november 2018, 22:24:34
av Al_Bundy
Så här ser det ut
Kod: Markera allt
this.i2CDevice.write(0x00, (byte) 0x00); // A-side output, a.k.a not HIGH
this.i2CDevice.write(0x01, (byte) 0x00); // B-side output, a.k.a not HIGH
this.i2CDevice.write(0x0C, (byte) 0xFF); // Pull up for A side
this.i2CDevice.write(0x0D, (byte) 0xFF); // Pull up for B side
Jag har använt mig utav MCP23017 förut och detta är en gammal kod som jag återanvänder.
Jag ändrade nu till så att GPIOB3 blev hög hos MCP23017 och nu tändes en LED lampa. Så kommunikationen är god hos min MCP23017.
Kod: Markera allt
package se.danielmartensson.hardware.MCP23017;
import java.io.IOException;
import com.pi4j.io.i2c.I2CDevice;
import se.danielmartensson.hardware.MCP3008.ReadMCP3008;
public class WriteMCP23017 {
private I2CDevice i2CDevice;
private ReadMCP3008 readMCP3008;
private int IODIRA = 0x00;
private int IODIRB = 0x01;
private int GPPUA = 0x0C;
private int GPPUB = 0x0D;
private int GPIOA = 0x12;
private int GPIOB = 0x13;
public WriteMCP23017(I2CDevice i2CDevice, ReadMCP3008 readMCP3008) {
this.i2CDevice = i2CDevice;
this.readMCP3008 = readMCP3008;
// Set B and A side to output
try {
this.i2CDevice.write(IODIRA, (byte) 0x00); // A-side output is low
this.i2CDevice.write(IODIRB, (byte) 0x00); // B-side output is low
this.i2CDevice.write(GPPUA, (byte) 0xFF); // Pull up for A side
this.i2CDevice.write(GPPUB, (byte) 0xFF); // Pull up for B side
// Set S
this.i2CDevice.write(GPIOB, (byte) 0x0C); // RS = 0, R/W = 0, E = 1, LED = 1
this.i2CDevice.write(GPIOA, (byte) 0x30); // 0 0 1 1 0 0 x x - Function set
this.i2CDevice.write(GPIOA, (byte) 0x08); // 0 0 0 0 1 0 0 0 - Turn of display
this.i2CDevice.write(GPIOB, (byte) 0x08); // RS = 0, R/W = 0, E = 0, LED = 1
/*
this.i2CDevice.write(GPIOA, (byte) 0xE); // 0 0 0 0 1 1 1 0 - Turn on cursor
this.i2CDevice.write(GPIOA, (byte) 0x06); // 0 0 0 0 0 1 1 0 - Entry Mode set
this.i2CDevice.write(GPIOB, (byte) 0x06); // RS = 0, R/W = 1, E = 1
this.i2CDevice.write(GPIOA, (byte) 0x06); // 0 1 0 1 0 0 1 1 - Write S
this.i2CDevice.write(GPIOB, (byte) 0x08); // RS = 0, R/W = 0, E = 0, LED = 1
*/
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* Write to LCD
*/
public void write() {
//int x_axis = readMCP3008.getX_axis();
//int y_axis = readMCP3008.getY_axis();
//i2CDevice.write(arg0);
}
}
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 02:44:14
av Al_Bundy
Hur ska man tolka dessa signaler ingångar?
Jag tolkar som att RS ska alltid vara låg, R/W ska alltid vara låg med tanke på att jag ska hela tiden skriva till LCD:n. E ska vara hög när jag vill antingen läsa eller skriva till LCD:n. När jag inte använder LCD:n så skall E vara låg.
När jag vill använda mig utav LCD:s funktioner så som radera, flytta eller nollställa LCD:n så sätter jag RS = 0. När jag vill skriva in till LCD:s minne så skriver jag RS = 1.
Så det jag alltid börjar med innan jag börjar skriva är att sätta RS = 0, R/W = 0 och E = 1. Sedan sätter jag hög/låg på D7->D0 och när jag sätter E = 0 så förstår LCD:n att den ska skriva in det D7->D0 beskriver.
Utan att läsa utav flaggan så väljer jag att sätta RS = 0, R/W = 0 och E = 1 där efter sätter jag D7->D0 till 0 0 1 1 0 0 x x. Där x är antingen 1 eller 0 för det spelar ingen roll. Där efter sätter jag RS = 0, R/W = 0 och E = 0. Jag upprepar detta 5 gånger. Kan man säga att då har man initialiserat LCD:n?
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 09:55:55
av Icecap
Jag brukar hardwire R/W till GND.
Sedan ska man ju köra uppstartssekvensen för att ställa displayen i 8- eller 4-bit läget och de andra saker man ska ställa.
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 09:58:49
av Klas-Kenny
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 14:24:05
av Al_Bundy
Jag har följt denna manual, men inget har fungerat för mig. Jag fort fortfarande den översta raden helt tjockmarkerad.
Jag lägger 3.3 volt på V0 och 5 volt på VDD. På min MCP23017 så ger den ut mellan 0 och 3.3 volt på GPIOA och GPIOB pinnarna. Det kanske måste vara 5 volt där också?
Jag har kollat om jag har kopplat rätt och det har jag. Jag har även jämfört med LED lampa om varje 1:a och 0:a stämmer och det gör det. Så kommunikationen mellan min CPU och MCP23017 är helt OK. Säger jag att t.ex. GPIOA7 ska vara hög så blir den hög.
Där har jag kopplat ihop följande hos MCP23017:
GPIOB0 -> RS
GPIOB1 -> R/W
GPIOB2 -> E
Och för A-sidan hos MPC23017
GPIOA7 -> D7
GPIOA6 -> D6
GPIOA5 -> D5
GPIOA4 -> D4
GPIOA3 -> D3
GPIOA2 -> D2
GPIOA1 -> D1
GPIOA0 -> D0
Jag har skrivit denna kod. Kolla vid for-loopen:
Kod: Markera allt
import java.io.IOException;
import com.pi4j.io.i2c.I2CDevice;
import se.danielmartensson.hardware.MCP3008.ReadMCP3008;
public class WriteMCP23017 {
private I2CDevice i2CDevice;
private ReadMCP3008 readMCP3008;
private int IODIRA = 0x00;
private int IODIRB = 0x01;
private int GPPUA = 0x0C;
private int GPPUB = 0x0D;
private int GPIOA = 0x12;
private int GPIOB = 0x13;
public WriteMCP23017(I2CDevice i2CDevice, ReadMCP3008 readMCP3008) {
this.i2CDevice = i2CDevice;
this.readMCP3008 = readMCP3008;
// Set B and A side to output and activate pull-up resistors
try {
this.i2CDevice.write(IODIRA, (byte) 0x00); // A-side output is low
this.i2CDevice.write(IODIRB, (byte) 0x00); // B-side output is low
this.i2CDevice.write(GPPUA, (byte) 0xFF); // Pull up for A side
this.i2CDevice.write(GPPUB, (byte) 0xFF); // Pull up for B side
/*
* Initi the LCD
*/
initLCD();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void initLCD() {
// Set S
try {
// Set the D7->D0 bits
/*
* 0x30 = Init
* 0x38 = Function set
* 0x08 = Display off
* 0x01 = Clear display
* 0x06 = Entry mode set
*/
long sleepTime = 10;
byte[] D7_to_D0 = {0x30, 0x30, 0x30, 0x38, 0x08, 0x01, 0x06};
for(int i = 0; i < D7_to_D0.length; i++) {
i2CDevice.write(GPIOB, (byte) 0x00); // RS = 0, R/W = 0, E = 0
Thread.sleep(sleepTime);
i2CDevice.write(GPIOA, (byte) D7_to_D0[i]); // 0 0 1 1 * * * *
Thread.sleep(sleepTime);
i2CDevice.write(GPIOB, (byte) 0x0C); // RS = 0, R/W = 0, E = 1
Thread.sleep(sleepTime);
i2CDevice.write(GPIOA, (byte) 0x00); // 0 0 0 0 0 0 0 0 <--- Nollställ
Thread.sleep(sleepTime);
}
// Write out an S
i2CDevice.write(GPIOB, (byte) 0x01); // RS = 1, R/W = 0, E = 0
Thread.sleep(sleepTime);
i2CDevice.write(GPIOA, (byte) 0x53); // 0 1 0 1 0 0 1 1 = S
Thread.sleep(sleepTime);
i2CDevice.write(GPIOB, (byte) 0x05); // RS = 1, R/W = 0, E = 1
Thread.sleep(sleepTime);
i2CDevice.write(GPIOB, (byte) 0x01); // RS = 1, R/W = 0, E = 0
Thread.sleep(sleepTime);
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 14:29:15
av mankan
Kolla i Ardionolibbet så kanske du kan få några ledtrådar:
https://github.com/arduino-libraries/LiquidCrystal
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 14:40:20
av metric
Har du ställt in kontrasten?
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 14:44:59
av Klas-Kenny
Inte kollat vad varje kommando faktiskt gör, men du har ett fel i där du översatt kommandona i bin från wikin till hex. Den du satt till 0x08 ska vara 0x0C.
Edit: hade skrivit fel 0B istället för 0C.
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 14:54:37
av Al_Bundy
metric skrev:Har du ställt in kontrasten?
Ja. Jag gav V0 3.3 volt och VDD 5 volt samt Vss 0 volt.
Re: Hur skriver jag till en LCD 16x2 ?
Postat: 4 november 2018, 14:57:19
av Al_Bundy
Klas-Kenny skrev:Inte kollat vad varje kommando faktiskt gör, men du har ett fel i där du översatt kommandona i bin från wikin till hex. Den du satt till 0x08 ska vara 0x0B.
Jag tycker det står 0x08. Eller det kanske är ändå fel?