Hur skriver jag till en LCD 16x2 ?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Hur skriver jag till en LCD 16x2 ?

Inlägg 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
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
metric
Inlägg: 766
Blev medlem: 16 maj 2010, 11:04:52

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
metric
Inlägg: 766
Blev medlem: 16 maj 2010, 11:04:52

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg av metric »

Jag får 41 träffar på "busy flag" i pdf:en jag länkade till?
ToPNoTCH
Inlägg: 4882
Blev medlem: 21 december 2009, 17:59:48

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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);
	}

}

Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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.
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg av Klas-Kenny »

Finns en bra sida i forumets wiki:
http://elektronikforumet.com/wiki/index.php/HD44780
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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();
		} 

	}
}
Användarvisningsbild
mankan
EF Sponsor
Inlägg: 908
Blev medlem: 18 juli 2015, 11:23:22
Ort: Linköping

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg av mankan »

Kolla i Ardionolibbet så kanske du kan få några ledtrådar: https://github.com/arduino-libraries/LiquidCrystal
metric
Inlägg: 766
Blev medlem: 16 maj 2010, 11:04:52

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg av metric »

Har du ställt in kontrasten?
Användarvisningsbild
Klas-Kenny
Inlägg: 11328
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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.
Senast redigerad av Klas-Kenny 4 november 2018, 15:12:19, redigerad totalt 1 gång.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Hur skriver jag till en LCD 16x2 ?

Inlägg 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?
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Skriv svar