16x2 LCD with PIC16F887 not working - Page 1
Forum section: electronics / general

author: newtekuser
author_rank: Frequent Contributor
timestamp: December 28, 2021, 12:53:16 am
content: I am trying to adapt the example given in "PIC Projects A Practical Approach" by Hassan Parchizadeh/Branislav Vuksanovic on how to write characters to an LCD, but using a PIC16F887 instead of the PIC16F627A mentioned in the book. Needless to say, nothing gets displayed on the LCD.The connections are wired according to the diagram (attached), but the only thing that shows up are the white blocks when I turn the 10K POT all the way up.From what I have been reading, I do need to set analog ports (AN) to digital I/O, so I am setting ANSEL and ANSELH registers to 0. Anything else needed besides this and config registers in the code below?The code was compiled with XC8 in mplab x environment and flashed to the Mcu using mikroprog (verified flash content after programming and it checked out).Below is the modified code:Code:// CONFIG1#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)#pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)#pragma config BOREN = ON // Brown Out Reset Selection bits (BOR enabled)#pragma config IESO = ON // Internal External Switchover bit (Internal/External Switchover mode is enabled)#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)#pragma config LVP = ON // Low Voltage Programming Enable b Fail-Safe Clock Monitor Enait (RB3/PGM pin has PGM function, low voltage programming enabled)// CONFIG2#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#include <xc.h>#include<pic.h>#include<pic16f887.h>#define _XTAL_FREQ 4000000#define RS RA0#define RW RA1#define E RA2#define NewLine 0xC0#define ClrDisp 0x01#define TwoLine10dots 0x38#define ScrOnCurOffBlinkOn 0x0F#define IncCurDntMovDis 0x06#define CurHome 0x02void sendCmd(unsigned char Cmd){PORTB = Cmd;RS = 0;RW = 0;__delay_ms(5);E = 1;__delay_ms(5);E = 0;return;}void sendData(unsigned char Ch){PORTB = Ch;RS = 1;RW = 0;__delay_ms(5);E = 1;__delay_ms(5);E = 0;return;}void initializeLCD(){__delay_ms(15);sendCmd(TwoLine10dots);__delay_ms(5);sendCmd(ScrOnCurOffBlinkOn);__delay_ms(5);sendCmd(ClrDisp);__delay_ms(5);sendCmd(CurHome);}void main(void) {ANSEL = 0x00;ANSELH = 0x00;TRISA = 0x00;TRISB = 0x00;RW = 0;RS = 0;E = 0;initializeLCD();sendData("H");sendData("e");sendData("l");sendData("l");sendData("o");sendCmd(NewLine);sendData("W");sendData("o");sendData("r");sendData("l");sendData("d");while(1);}Diagram attached.

author: SuzyC
author_rank: Frequent Contributor
timestamp: December 28, 2021, 02:45:16 am
content: The wiring attached will not work on the 16F887, the pinout is completely different and the '887 has 40-pins.

author: DavidAlfa
author_rank: Super Contributor
timestamp: December 28, 2021, 04:19:19 am
content: No problem as long as the pins are correctly set.Writing to PORTB, or setting RA0 high will be the same on all PICs.Test every IO to ensure they're not locked by some peripheral.Increase power-on delay to 100ms.

author: jpanhalt
author_rank: Super Contributor
timestamp: December 28, 2021, 04:38:00 am
content: What type of LCD do you have? Does it have the Hitachi HD44780 controller or clone?Initialization sequence for that controller sends 0x30 in 8-bit mode (attached). Your defines don't include that value the times shown(0x38 is OK, but why?).

author: newtekuser
author_rank: Frequent Contributor
timestamp: December 28, 2021, 08:35:08 pm
content: The LCD unit I'm using has the HD44780 controller, this is the exact model in question:https://www.amazon.com/gp/product/B00HJ6AFW6/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1As for the LCD init I was sending 0x38 as this was the value referenced in the book. Upon further reading online I learned that it means "8 bit mode, 2-line mode, 5x7 dots font".I also changed it to 0x30 instead but it didn't make any difference. Tried the following init routines below:Using 0x38 commandCode:__delay_ms(100);sendCmd(0x38);__delay_ms(5);sendCmd(0x38);__delay_us(100);sendCmd(0x38);__delay_us(100);sendCmd(ScrOnCurOffBlinkOn);__delay_ms(5);sendCmd(IncCurDntMovDis);__delay_ms(5);sendCmd(ClrDisp);__delay_ms(5);sendCmd(CurHome);Using 0x30 commandCode:__delay_ms(100);sendCmd(0x30);__delay_ms(5);sendCmd(0x30);__delay_us(100);sendCmd(0x30);__delay_us(100);sendCmd(ScrOnCurOffBlinkOn);__delay_ms(5);sendCmd(IncCurDntMovDis);__delay_ms(5);sendCmd(ClrDisp);__delay_ms(5);sendCmd(CurHome);LE: I've also changed _XTAL_FREQ value from 4000000 to 8000000

author: DavidAlfa
author_rank: Super Contributor
timestamp: December 29, 2021, 12:31:03 am
content: http://www.ekenrooi.net/lcd/lcd0.shtml#hd44780https://github.com/geekfactory/LCD

author: Lindley
author_rank: Regular Contributor
timestamp: December 29, 2021, 10:09:18 am
content: Probably the two most commom problems with Pic/LCD are the wiring connections between the pic and lcd, bridged pads on the lcd being no.1Also if using a Breadboard and a Crystal with its thin leads, the signal/connection can be lost, better to solder the crystal and its caps onto some board and fit it with thicker wires to plug into the breadboard.Of course with the 16F887, it has a perfectly good internal oscillator for 4 mhz, so better to use that, you should find examples around of how to do that.Have a look at this 887 to lcd project, it comes with the compiled .hex code so ready to program in, so should eliminate any coding errors etc.https://simple-circuit.com/pic16f887-lcd-example-ccs-c/If all that fails, then go back one step and test out the 877 by doing a 1 second flashing led on Port B pins.

author: SuzyC
author_rank: Frequent Contributor
timestamp: December 29, 2021, 12:23:42 pm
content: I would highly recommend you code to first flash LEDS on all PORTB pins.

author: mariush
author_rank: Super Contributor
timestamp: December 29, 2021, 12:38:13 pm
content: Yeah, agree with Suzy... debug with leds.Also, I had problems with the delay functions not working right, so I wrote my own, sort of... they're basically hardcoded for a specific frequency (16 Mhz in my case) ... but on your 8 Mhz, you either adjust the functions or you call them with half the value (ex divide the delay amount by 2)the nop instruction uses 1 cycle, the goto uses 2 cycles, so you can play with combinations of these to make a function use a particular amount of cyclesdelay.hCode:// Delay routines for 16 Mhz clock.//// 16 Mhz = 4 Hz per cycle = 4 operations/cycles per uS//#ifndef __DELAYH_INIT#define __DELAYH_INIT#define delay_1tcy() asm("nop")#define delay_2tcy() asm("goto $+1")#define delay_4tcy() asm("goto $+1");asm("goto $+1");#define delay_10tcy() delay_2tcy();delay_4tcy();delay_4tcy();#define delay_500ns() delay_2tcy()#define delay_1us() delay_4tcy()#define delay_4us() delay_1us();delay_1us();delay_1us();delay_1us();#define delay_5us() delay_4us();delay_1us();#define delay_10us() delay_5us();delay_5us();#define delay_5ms() delay_ms(5);#define delay_10ms() delay_ms(10);#define delay_25ms() delay_ms(25);#define delay_50ms() delay_ms(50);#endifextern void delay_25us();extern void delay_50us();extern void delay_100us();extern void delay_1ms();extern void delay_ms(unsigned char ms);delay.cCode:/*** The routines below are precomputed for 16 Mhz clock.*/#include "delay.h"void delay_25us(){// function call and return is 4 cycles, on 16Mhz that's 1us// so delay for 24us heredelay_10us();delay_10us();delay_4us();}void delay_50us(){delay_10us();delay_10us();delay_10us();delay_10us();delay_5us();delay_4us();}void delay_100us(){delay_50us();delay_10us();delay_10us();delay_10us();delay_10us();delay_5us();delay_4us();}void delay_1ms(){unsigned char n = 248;do {asm("goto $+1"); asm("goto $+1"); asm("goto $+1");asm("goto $+1"); asm("goto $+1"); asm("goto $+1");asm("nop");// decrease if not zero - decfsz (1 cycle if !=0, 2 cycles otherwise)// goto loop start = 2 cycles} while(--n);// = 16 cycles x [n+1] + 1 (from last decfsz) - 2 (last goto is skipped)// 249x16+1-2 = 3983 cycles (1 = decfsz ), -2 for last goto// + 1 = 3984 cycles (assignment of 248 to n)// + 4 = 3988 cycles (function call and return)delay_2tcy(); // = 3990 cyclesdelay_10tcy(); // = 4000 cycles}// Delay up to 255 milliseconds - approximately (ms + 19 cycles).// ms can be in range 1 to 255void delay_ms(unsigned char ms) {unsigned char n;while(ms--) { // time in cycles for the inner loop includingn = 249; // cycles = 19+16*ms*[1+n]// cycles = 4000*ms + 19 for 16MHz clock// cycles = 2000*ms + 19 for 8MHz clockdelay_4tcy();do {asm("goto $+1");asm("goto $+1");asm("goto $+1");asm("goto $+1");asm("goto $+1");asm("goto $+1");asm("nop");// decrease if not zero - decfsz (1 cycle if !=0, 2 cycles otherwise)// goto loop start - 2 cycles} while(--n);// = 16 cycles x [n+1] + 1 (from last decfsz)}}

author: jpanhalt
author_rank: Super Contributor
timestamp: December 29, 2021, 12:50:29 pm
content: Just in case it might help, here is the Assembly code I use for 8-bit parallel. In practice, I rarely use 8-bit parallel. Usually, I use 4-bit parallel. The difference in time is almost trivial.I realize you are using C, not Assembly, but you might try inline Assembly as a check.PORbcf RWDelayCy (80*msecs)movlw 0x30call PutByte ;?PutByte, not PutData -- BF is not valid untilDelayCy (5*msecs) ;LCD is initialized in 8-bit modemovlw 0x30call PutByte ;?PutByteDelayCy (1*msecs)movlw 0x30call PutByte ;8-bit mode is now set and BF is validmovlw 0x38 ;Function set: 8 bit-mode, N and F setcall PutCMD ;N(set=2-line),F(clear=5x8 dot character font);Set display format:movlw 0x08 ;Display on/off control: display offcall PutCMDDelayCy (80*msecs) ;blinks screen (optional)DelayCy (80*msecs) ;blinks screen (optional)movlw 0x01 ;Clear display: clears displaycall PutCMDDelayCy (2*msecs)movlw 0x06 ;Entry mode set: increment address (cursor)call PutCMDmovlw 0x0C ;Display on/off: display on/cursor off/blink offcall PutCMDreturn;WNB (wait not, busy) checks the "busy" bit, which is marginally faster than a fixed delayPutByte ;"PutByte" does not check "busy" bit.movwf PORTCbsf E ;toggle E; nop ;one or two may be needed at 32 MHz, not needed;at 8 or 16 MHzbcf EDelayCy (80*usecs)returnPutCMDbcf RS ;PutData RS=0bra $+2PutDatabsf RSmovwf PORTCbsf E ;toggle E; nop ;one or two "probably" needed at 32 MHz, not needed at 8 MHzbcf Ecall WNBreturn

author: newtekuser
author_rank: Frequent Contributor
timestamp: December 29, 2021, 07:51:30 pm
content: Thank you all for the replies and suggestions!I'm going to give up for now and buy a dev board kit that comes with the LCD unit and sample code (preferably one using a recent PIC family not from 20 years ago). It is possible all the three LCD units I have are messed up although the pads look ok (not shorted), double checked connections go where they should and also checked for continuity.The LCD-master project from github doesn't even build because it's missing a Delay.h header file and flashing the hex file didn't work (verification failed). I did notice the project is configured to work with an external oscillator, unfortunately reverse engineering the rest of the circuit from code and not having a diagram is a bit too much for me at this point

author: Lindley
author_rank: Regular Contributor
timestamp: December 29, 2021, 09:38:46 pm
content: It looked a decent project/site and was worth a try, but afraid old, missing or incorrect code can be a problem with quiet a few web examples, though eventually you will find sites with good code and schematics.Do not have a 887 chip to try your code on, though like others only used to code Pics in Assembly.Do you have any other Pic chips with you ?Have you ever run anything on your 887 to prove it does work ? eg the flashing led.You can buy dev boards but most are just a load of switches and leds that you will not use, much but cost a lot !See no reason why you cannot get something running using just a Pic and LCD, sure folk here will be able to get some proven code to you.

author: newtekuser
author_rank: Frequent Contributor
timestamp: December 30, 2021, 02:48:57 am
content: No wonder the LCD program didn't work, I can't even blink an LED with these 887 chips. They have "Microchip" etched on them, but were bought off Amazon for $10 (3 for $10) and I'm assuming they're counterfeit. The only chip I believe is genuine is the 877A I purchased from Mouser but wanted to avoid the hassle of adding an external crystal.I also have a few 887 in QFP version for which I have an adapter but have yet to test. I don't have high hopes for them either as they were also clones bought off Amazon.I did a quick test and set all ports to either 0 or 1 and hooked up my multi-meter and noticed some small voltage on all (except for VDD pins which are close to 5V) regardless if ports were set to 0. They should have been 0 when set to low, and close to 5V when set to high, correct?Is there another way to test if the chip is functional?

author: tru
author_rank: Regular Contributor
timestamp: December 30, 2021, 05:59:54 am
content: Quote from: newtekuser on December 30, 2021, 02:48:57 amI remember years ago I couldn't even get a genuine PIC16F877A to work, i.e. to blink a LED, after many hours of trying (changing crystal, getting another PIC, etc) it was the LVP. Try setting LVP = OFF at the top of your configs.

author: jpanhalt
author_rank: Super Contributor
timestamp: December 30, 2021, 06:15:16 am
content: Quote from: newtekuser on December 30, 2021, 02:48:57 amI agree with the subsequent post by @tru. Maybe the problem is elsewhere in your code and either the chip isn't programming correctly or your other settings are wrong, like is the oscillator running.Posting your setup code might help.

author: inse
author_rank: Super Contributor
timestamp: December 30, 2021, 08:27:04 am
content: I don't know what type of programmer you have, but usually they check the device ID before trying to access the memory.If you can verify your flash memory, the chance of counterfeit chips should be rather low.

author: Lindley
author_rank: Regular Contributor
timestamp: December 30, 2021, 09:28:48 am
content: If you have a 4 mhz crystal and 2 x 22pf (approx) caps to drive the oscillator of that 877chip then we have well proven LCD code we can send over as a ready to program .hex file which should help prove if some things work ok.

author: DavidAlfa
author_rank: Super Contributor
timestamp: December 30, 2021, 11:05:21 am
content: Post here your real schematic.Althought you disabled MLCRE functionality, enabling LVP forces MCLRE.Put a 10K pullup resistor from MCLRE pin to VDD or disable LVP.https://microchipdeveloper.com/8bit:lvp

author: Ian.M
author_rank: Super Contributor
timestamp: December 30, 2021, 12:27:27 pm
content: There is no need to write your own delay functions for a HD44780 LCD driver, unless you are using an antique version of HiTech PICC (well before the Microchip buy-out) or a third party compier with broken or no delay functions.Microchip XC8 (for PIC)__delay_ms(nn_ms),__delay_us(nn_us)and_delay(nn_Tcy)macros work as expected, provided their parameter is a compile-time constant (e.g. a numeric literal), _XTAL_FREQ is #defined correctly and the delay is less than the maximum limit given in the compiler release notes (currently 50,463,240 instruction cycles, which is over three seconds on the fastest PIC18 available). You can NOT use them for a variable delay, the delay will be extended by any interrupts that are serviced during it, and the delay will be rounded down to the nearest number of whole instruction cycles.N.B. _XTAL_FREQ must be set to the core clock frequency in Hz, after any PLL multipliers etc. For a PIC16 at 20MHz you'd use:Code:#define _XTAL_FREQ 20000000ULwhich needs to be visible to all source files that use the built-in delays so is probably best defined in a header you can use project-wide.However there is a trap for young players in the HD44780 LCD controller datasheet: The execution time for each command is given for a nominal oscillator frequency of 270KHz, however the internal oscillator frequency is dependent on supply voltage and a resistor between HD44780 OSC1 and OSC2 pins, chosen by the LCD module manufacturer, so if you are using delays rather than polling the busy bit, its advisable to multiply the execution times from the command descriptions in the data sheet by a factor of 2.2 (to allow for the oscillator to be at its minimum frequency limit)

author: newtekuser
author_rank: Frequent Contributor
timestamp: December 30, 2021, 06:23:04 pm
content: Setting LVP to OFF fixed this and I can blink the LED, thank you very much for pointing me in the right direction! I think I'm back on track and will give the LCD code another try later today and report back.

author: DavidAlfa
author_rank: Super Contributor
timestamp: December 30, 2021, 11:32:45 pm
content: Attached a MplabX project for a similar pic (18F23K22). Tested working.8-bit interface though, so you'll have to modify it for 4-bit mode.The init sequence is always 8-bit (0x38)! The 4th FUNCTION_SET command is what does the confioguration.Check these datasheets, they're much better than the common ones:https://www.avrfreaks.net/comment/92532#comment-92532

author: newtekuser
author_rank: Frequent Contributor
timestamp: December 31, 2021, 08:39:19 pm
content: DavidAlfa, I wasn't able to build the project attached due to compile errors and the code I had originally didn't work either. The only thing that works for me is the mikroelectronica sample code for LCD for 4-bit interface. At least that proves that my chip and LCD are working fine. The only adjustments I had to make was to disable MCLRE pin and use the internal oscillator (INTOSCIO option)I do not like that I cannot see the inner-workings of the library functions provided by MikroE, must be closed source, or at least I haven't figured out how.Below is the code and circuit diagram that work for me. Of course that is not what I had in mind as mikroE hides a lot of the stuff behind their own macros which I don't like for learning purposes, but at least I can put the money I spent on the mickroC pro license to a good use...Code:// LCD module connectionssbit LCD_RS at RB4_bit;sbit LCD_EN at RB5_bit;sbit LCD_D4 at RB0_bit;sbit LCD_D5 at RB1_bit;sbit LCD_D6 at RB2_bit;sbit LCD_D7 at RB3_bit;sbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;// End LCD module connectionschar txt1[] = "mikroElektronika";char txt2[] = "EasyPIC6";char txt3[] = "Lcd4bit";char txt4[] = "example";char i; // Loop variablevoid Move_Delay() { // Function used for text movingDelay_ms(500); // You can change the moving speed here}void main(){ANSEL = 0; // Configure AN pins as digital I/OANSELH = 0;C1ON_bit = 0; // Disable comparatorsC2ON_bit = 0;Lcd_Init(); // Initialize LCDLcd_Cmd(_LCD_CLEAR); // Clear displayLcd_Cmd(_LCD_CURSOR_OFF); // Cursor offLcd_Out(1,6,txt3); // Write text in first rowLcd_Out(2,6,txt4); // Write text in second rowDelay_ms(2000);Lcd_Cmd(_LCD_CLEAR); // Clear displayLcd_Out(1,1,txt1); // Write text in first rowLcd_Out(2,5,txt2); // Write text in second rowDelay_ms(2000);// Moving textfor(i=0; i<4; i++) { // Move text to the right 4 timesLcd_Cmd(_LCD_SHIFT_RIGHT);Move_Delay();}while(1) { // Endless loopfor(i=0; i<8; i++) { // Move text to the left 7 timesLcd_Cmd(_LCD_SHIFT_LEFT);Move_Delay();}for(i=0; i<8; i++) { // Move text to the right 7 timesLcd_Cmd(_LCD_SHIFT_RIGHT);Move_Delay();}}}

author: Ian.M
author_rank: Super Contributor
timestamp: December 31, 2021, 09:25:23 pm
content: Quote from: DavidAlfa on December 30, 2021, 11:32:45 pmUnfortunately the PIC18F23K22 is not in any way a similar PIC.The O.P's PIC16F887 is a 40 pin 'classic' midrange (14 bit core) device, wheras the PIC18F23K22 is a 28 pin so-called High End (16 bit core) device. The key difference that makes the code very difficult to port to the older device is the 'classic' midrange core's lack of LAT SFRs for its ports, compounded by the use of short form port SFR bit names rather than the more portablePORTXbits.RXn,TRISXbits.TRISXn&LATXbits.LATXnform, which is much easier to convert to software shadowing using the pointer cast method I posted to'RMW and solutions for it'@Microchip Forums.A PIC18F4xK22 (where x is 3 to 6 depending on the memory size) would be a nice PIC18 drop-in replacement for the O.P. allowing him to use your code . . .

author: Lindley
author_rank: Regular Contributor
timestamp: December 31, 2021, 09:32:52 pm
content: Good to hear you got it all working ok.Not into MikroE C, but seems plenty of documentation on all the library routines.https://download.mikroe.com/documents/compilers/mikroc/pic/help/lcd_library.htmHowever the whole lcd routine is a little bit complicated when you are just starting with C, would worry about how it works in detail until later.Expect there is a neat tutorial on how to use the full lcd character set in the HD44780 chip and make you own symbols. eg -https://www.sparkfun.com/datasheets/LCD/HD44780.pdfhttps://electrosome.com/custom-characters-lcd-pic-mikroc/

author: rpiloverbd
author_rank: Regular Contributor
timestamp: January 01, 2022, 11:03:03 am
content: If you are a beginner with PIC MCU and there is no restriction set by your teachers(in case it is an academic project), I suggest you try the free version of MikroC PRO for PIC compiler. I was personally benefitted from it. MikroC pro for PIC has a library for LCD. It makes showing texts etc. very easy.

author: Ian.M
author_rank: Super Contributor
timestamp: January 01, 2022, 11:36:05 am
content: Quote from: rpiloverbd on January 01, 2022, 11:03:03 amI apologies in advance if you have diagnosed short term memory loss, but do you lack reading comprehension or are you too lazy to read through a single page topic before replying?The O.P. posted back in reply #21:Quote from: newtekuser on December 31, 2021, 08:39:19 pmI find MikroElektronika's walled garden software ecosystem reprehensible. There's no reason for their 'dog in manger' lack of MPLAB compatibility for their compilers. Other companies (even smaller ones) with their own IDEs have written MPLAB plugins for their own compilers and generally are willing to at least sell you a license to see their library source code. Don't hold your breath waiting for either from MicroE.OTOH they do make some nice demo boards and hardware accessories which are often better thought out and more versatile than the Microchip offerings.

author: nigelwright7557
author_rank: Frequent Contributor
timestamp: January 01, 2022, 02:39:22 pm
content: Not only does wiring need to be correct but you must follow software setup from datasheet.Some instructions need quite long delays between them.An oddity with the LCD display is 2nd line starts from position 40.

author: DavidAlfa
author_rank: Super Contributor
timestamp: January 01, 2022, 06:25:35 pm
content: The code works, just copy the important lcd stuff and setup your specific Pic settings."Compiler errors" doesn't mean anything if you don't show them.The project is for mplabX and xc8 compiler.Xc8 is free and unrestricted up to O2 optimization.

author: Ground_Loop
author_rank: Frequent Contributor
timestamp: January 08, 2022, 04:02:29 am
content: Have you tried leaving E in a high state then pulsing it low back to high? I believe data latch occurs on high to low transition. I'm not near my development machine at the moment but I have 4-bit, 8-bit, and 16 bit SPI libraries for the two and four line LCDs and I'm sure I leave the E line high. Also, you can wire the R/W line low and save yourself an IO line.

author: DavidAlfa
author_rank: Super Contributor
timestamp: January 09, 2022, 01:42:39 pm
content: Might work, but I'd rather follow the datasheet specs, so I fetch the data, wait 1us, toggle E high, wait 1us, toggle E down and wait the instruction time.I had a 16x4 module from a decade ago lying around, worked perfectly.Could be optimized, but these displays are slow anyways.

author: nigelwright7557
author_rank: Frequent Contributor
timestamp: January 10, 2022, 03:22:25 pm
content: Quote from: Ground_Loop on January 08, 2022, 04:02:29 amYou can and I sometimes do but you then cant read busy flag.You can get around it by using delays taken from datasheet.

author: Ground_Loop
author_rank: Frequent Contributor
timestamp: January 10, 2022, 06:42:28 pm
content: Quote from: DavidAlfa on January 09, 2022, 01:42:39 pmYea, I went back and looked at my libraries, EN high then EN low. I was confusing the direct write to the display with the control of shift registers when using SPI.

author: nigelwright7557
author_rank: Frequent Contributor
timestamp: April 07, 2022, 02:53:51 am
content: I recently did a project using PIC and LCD.No matter what I did the display would just roll short white lines.Turned out to be a bad display !I got 3 for £4 on ebay so just accepted I might get a bad one occasionally.They are about £6 each at RS Components !