Hello everybody!
I'm new here and I hope we'll go on well
I've come here because I'm working on a project with a PIC 16F84 which I'd like to use to control a 2x16 chars LCD display (Hitachi HD44780 driver). I'm programming in C as I have already programmed in this language and I know most of it. But this is my first time in PIC programming and I need some help...
What I need to know for now it's how to proceed in initializing the display for 4-bit data transfer and how to write chars on the display.
On the PIC I'd like to use PORT_A pins to drive the LCD. I see that the LCD uses E (enable), RS (register select) and R/W (Read/Write) pins. Is there any way I can pre-set them to not waste pins on the PIC? I've been thinking I could set E=VDD and R/W=GND (always enabled and writing), so I could use RA1-RA4 as LCD data and RA0 as RS. I don't need to read from LCD so it's ok to not be able to read from.
For testing I have MPLAB with Hi-Tech C Compiler and Proteus ISIS for hardware simulation; both have been tested and are working fine.
I hope you can help me, and thanks
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #define lcd_port P3 //LCD Registers addresses #define LCD_EN 0x80 #define LCD_RS 0x20 void lcd_reset() { lcd_port = 0xFF; delayms(20); lcd_port = 0x03+LCD_EN; lcd_port = 0x03; delayms(10); lcd_port = 0x03+LCD_EN; lcd_port = 0x03; delayms(1); lcd_port = 0x03+LCD_EN; lcd_port = 0x03; delayms(1); lcd_port = 0x02+LCD_EN; lcd_port = 0x02; delayms(1); } void lcd_init () { lcd_reset(); // Call LCD reset lcd_cmd(0x28); // 4-bit mode - 2 line - 5x7 font. lcd_cmd(0x0C); // Display no cursor - no blink. lcd_cmd(0x06); // Automatic Increment - No Display shift. lcd_cmd(0x80); // Address DDRAM with 0 offset 80h. } void lcd_cmd (char cmd) { lcd_port = ((cmd >> 4) & 0x0F)|LCD_EN; lcd_port = ((cmd >> 4) & 0x0F); lcd_port = (cmd & 0x0F)|LCD_EN; lcd_port = (cmd & 0x0F); delayus(200); delayus(200); } void lcd_data (unsigned char dat) { lcd_port = (((dat >> 4) & 0x0F)|LCD_EN|LCD_RS); lcd_port = (((dat >> 4) & 0x0F)|LCD_RS); lcd_port = ((dat & 0x0F)|LCD_EN|LCD_RS); lcd_port = ((dat & 0x0F)|LCD_RS); delayus(200); delayus(200); }
Well about R/W you are right, keep it grounded if you need write only. About E you cannot do something similar, you need a dedicated I/O pin. It is not exactly "enable" as you imagine it, please take a look at the LCD data and command timing diagrams in the lcd datasheet and you will understand what I'm talking about.T3STY said:I've been thinking I could set E=VDD and R/W=GND (always enabled and writing)
The below code will help you to get an idea about initialization.T3STY said:What I need to know for now it's how to proceed in initializing the display for 4-bit data transfer and how to write chars on the display.
void lcd_init (void)
{
Delay_ms(50);
LCD_cmd(0x30);
Delay_ms(10);
LCD_cmd(0x30);
Delay_ms(10);
LCD_cmd(0x30);
Delay_ms(10);
LCD_cmd(0x20); //4 bits bus
Delay_ms(10);
LCD_cmd(0x28);
Delay_ms(10);
LCD_cmd(0x08);
Delay_ms(10);
LCD_cmd(0x01);
Delay_ms(10);
LCD_cmd(0x06);
Delay_ms(10);
LCD_cmd(0x0C); //blink off
Delay_ms(50);
}
while(1);
I guess, the real PIC won't keep on looping the main(), right?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?