PIC control LCD 1602A & programming with HI-tech C  - Page 1
Forum section: electronics / general

author: singlarrysong
author_rank: Contributor
timestamp: January 03, 2017, 10:37:52 am
content: I always try not to disturb you people here with my easy question by try to dig solutions by myself, but today I fed up again with LCD.With almost 3 years of microcontroller experience I suppose to learn how to program LCD in C, unfortunately no as I learn flowcode in my schoolSo I struggle every time exploring new modules, like last time I ever ask how to make alphabet words input into ASCII and sent to a vintage VFD.Yes, this is my second experience on display but it is a LCD with newer tech and instruction compare to my VFD.Skip my story here.....My LCD model is 16 pins I/O(incl a LED anode and cathode) 1602A and I had research that it instructions are same as the commonly used Hitachi HD44780U 16x2 display.I had attach the datasheet I refers to and comparing other 1602 datasheet I get similar display characteristic.below is my codeCode:#include <htc.h>#include <pic.h>#define _XTAL_FREQ 1000000void write(unsigned char RS , unsigned char data){RA7 = 0;//R/WRA0 = RS;//RS__delay_us(0.15);//RS and RW setup timeRA6 = 1;//ENLATB = data;__delay_us(0.3);//Tw, minimum EN rise time__delay_us(0.01);//Th2, minimum wait time for data clear after EN fallLATB = 0x00;__delay_us(0.19);//Tc, sum from Tw for minimum cycle time of EN}void init_LCD(void){TRISA = 0x00;//RA0 is RS, RA7 is R/W, RA6 is ENTRISB = 0x00;//8 bit data portLATA = 0x00;LATB = 0x00;//ASSUME INITIAL FUNCTION MODE IS 4 Bits//write(0 , 0b00111000);//set functions, sent first 4 MSB bits 8bits bus mode, 2 lines display, 5*8 dots format//write(0 , (0b00111000<<4));//set functions, send last 4 LSB bits//ASSUME INITIAL FUNCTION MODE IS 8 Bitswrite(0 , 0b00111000);//set functions, 8bits bus mode, 2 lines display, 5*8 dots formatwrite(0 , 0b00000001);//clear displaywrite(0 , 0b00000010);//return cursor to homewrite(0 , 0b00001110);//display on/off control, display on, cursor on, cursor blink off}void main(void){OSCCON = 0b01011010;//1MHz Fosc, Int Osc module__delay_ms(400);init_LCD();write(0, 0b01000101);//try to print a alphabet first, "E" in ASCIIfor(;;){}}PROBLEM is hereI try a few codes from Hi-Tech C sample code to code that I get from the internet(modify their I/O config to specific pic I use)...The codes had a successful built and programmed into my PIC.but then I still get a blank on my LCD(attached picture)so I wonder anyone had try 1602A LCD and give my code correction or a sample display test code.This is my first LCD and I really afraid that it is broken.Picture LCD : when the power is off the screen appear dark... the bottom part show slightly poor contrast as my V0 are tuned by 10k ohm resistor, both device are power up by USB power.Picture VFD : This VFD is about 27 years old, so the controller is still using NEC 8041 where lots of SIPO to multi task the matrix.LCD command from website :http://mil.ufl.edu/3744/docs/lcdmanual/commands.html

author: newbrain
author_rank: Super Contributor
timestamp: January 03, 2017, 10:54:59 am
content: Quote from: singlarrysong on January 03, 2017, 10:37:52 amThe first thing I notice is that the E line (RA6) is never reset to 0 in your write function, so the write will never be actually performed (the 44780 latches data on falling edge of E).Consider also that E must stay high for at least 450ns: I don't do PICs so I'm not aware of the resolution and precision of the delay functions.

author: void_error
author_rank: Frequent Contributor
timestamp: January 03, 2017, 11:09:22 am
content: This is what I found when I started playing with those character LCDs:https://electrosome.com/lcd-pic-mplab-xc8/It's using the XC8 compiler though. Shouldn't be too different from Hi-Tech C.

author: singlarrysong
author_rank: Contributor
timestamp: January 03, 2017, 01:56:10 pm
content: I try to put RA6 = 0 into the section but it still the sameCode:void write(unsigned char RS , unsigned char data){RA7 = 0;//R/WRA0 = RS;//RS__delay_us(0.15);RA6 = 1;//ENLATB = data;__delay_us(0.3);//Tw, minimum EN rise timeRA6 = 0; //clear EN__delay_us(0.2);//Th2, minimum wait time for data clear after EN fallLATB = 0x00;//9__delay_us(0.19);//Tc, sum from Tw for minimum cycle time of EN}Quote from: void_error on January 03, 2017, 11:09:22 amI had check this page out early, but the problem is the lcd.h. They saidQuoteso the key is the LCD.h

author: newbrain
author_rank: Super Contributor
timestamp: January 03, 2017, 02:57:59 pm
content: Quote from: singlarrysong on January 03, 2017, 01:56:10 pmOk, that was just the first comment...there are other issues with the code though.To make sure the HD44780 is correctly initialized, the initial setup should be done according to the attached picture: the delays and function set  repetitions are missingwrite(0, 0b01000101); //try to print a alphabet first, "E" in ASCIIRS should be set to 1, otherwise you are still writing to the control register, rather than the display RAM.The timings in the write routine are not according the datasheet, assuming you can have such a fine control (I frankly doubt it, if the clock is actually 1MHz). For tests, you can have them as high as you fancy, the HD44780 won't care as long as they are longer than the minimum.Of course, check and re-check the HW connections...Hope this helps.

author: JanJansen
author_rank: Frequent Contributor
timestamp: January 03, 2017, 05:42:40 pm
content: Here is the first datasheet in google :https://www.openhacks.com/uploadsproductos/eone-1602a1.pdfI suggest write all code yourself, dont copy.Use write only no reading, start with 8 bit.From my head :First small delay.Then set mode : 8 bit mode, datasheet command 0b110000.Clear screen, datasheet command 0b1, then wait long.activate display, datasheet command 0b1100.for instruction : set dataport, then set enable, wait for 7us, clear enable, wait 27us.Your screen aint broken, i thought the same, only bad code.

author: singlarrysong
author_rank: Contributor
timestamp: January 06, 2017, 03:02:03 pm
content: Sorry for the late.I had follow the flowchart and try the instruction but still get blank. The contrast of the display flash for less than a second and everything went blank.Quote from: JanJansen on January 03, 2017, 05:42:40 pmHere is the code. As I don't read busy flag, so I put longer on those delay, such as from datasheet min 37us, I give 50 etc etcCode:void write(unsigned char RS , unsigned char data){RA7 = 0;//R/WRA0 = RS;//RS__delay_us(0.15);RA6 = 1;//ENLATB = data;__delay_us(0.3);//Tw, minimum EN rise timeRA6 = 0;__delay_us(1.2);//Th2, minimum wait time for data clear after EN fallLATB = 0x00;__delay_us(50);//Write data delay}void init_LCD(void){__delay_ms(500);//Power up delayTRISA = 0x00;TRISB = 0x00;LATA = 0x00;LATB = 0x00;write(0 , 0b00110000);//8 bits mode__delay_ms(450);write(0 , 0b00110000);//8 bits mode__delay_us(100);write(0 , 0b00110000);//8 bits mode__delay_us(100);write(0 , 0b00110000);//bits 3, 2 lines mode__delay_us(50);write(0 , 0b00001100);//entire dislay on, cursor on, cursor blinking__delay_us(50);write(0 , 0b00000001);//clear display__delay_ms(2);write(0 , 0b00000110);//entry mode__delay_us(50);}void main(void){OSCCON = 0b01111010;//16MHz Fosc, Int Osc moduleinit_LCD();write(1, 0b01000101);//try to print "E" firstfor(;;){}}

author: Buriedcode
author_rank: Super Contributor
timestamp: January 06, 2017, 10:18:23 pm
content: Have you tried using a pot to control the contrast? Some displays I've used are fine with 10K to 0V, but were hard to read, whilst others this was too much, and I had to use a pot, which is set quite close to 0V (hooked up to 5V and 0V).Also, increase your enable line time to say 10us. Thats a lot, but yuo're makign Enable high, writing to your port, then waiting 1.2us, then pulling it low. That sounds long enough to me, but it is something to check.Set RS.Write data to port.Make E high.wait 10us.Make E low.If that works then you know its a timing issue.Also, what chip are you using? Some PIC's have peripherals enabled by default, and may interfere with writing to PORTB. In other words - post your entire code

author: JanJansen
author_rank: Frequent Contributor
timestamp: January 07, 2017, 04:41:24 pm
content: Please define your pins also to make more readable.

author: StillTrying
author_rank: Super Contributor
timestamp: January 07, 2017, 05:43:16 pm
content: RA7 = 0; //R/WRA0 = RS; //RS__delay_us(0.15);RA6 = 1; //ENLATB = data;Although some LCDs say they latch RS and DATA on the different edges of EN, don't toggle EN until the after the DATA is there.