I have a DEM 16217 SYH-PY 2×16 character LCD and I have problems initializing it.
I'm using AVR Studio 4. The 8 datalines are connected to port A of the microcontroller while the 3 control lines are connected to port E. Enable is PE2, R/W is PE1 and S is PE0. Port A connections are DBn to PORTAn. As far as I can see from the datasheet, no instructions seem to take more than 2 ms. For some reason, busy flag check isn't working correctly, so I used 2 ms delay instead.
At first, I wanted to have an LED blink after each step, but it turned out to be much better to have output at a serial port.
Here's my code:
#include <avr/io.h>
#include<util/delay.h>
#include "LED.h"
#include "Terminal.h"
void Screen_Execute(void)
{
_delay_us(2);
PORTE=PORTE | 4;
_delay_us(2);
PORTE=PORTE ^4;
_delay_us(2);
//_delay_us(2);
}
void Screen_busy(void)
{
_delay_ms(2);
//is the screen busy?
//PORTE=PORTE | 2;
//DDRA=0x7F;
//Screen_Execute();
//while ((PINA & 128))
//{
//Screen_Execute();
//BLINK_LED(500);
//}// wait until zero
//DDRA=0xFF;
//PORTE=PORTE ^ 2;
//Screen_Execute();
//no longer busy
}
void Screen_init(void)
{
//BLINK_LED(1000);
SEND_STRING("Starting initialization\r\n",0);
DDRE=0xFF;
PORTE=0x00;
DDRA=0xFF;
PORTA=0x30;
_delay_ms(250);
_delay_ms(1000);
SEND_STRING("Step 1 executing.\r\n",0);
Screen_Execute();//voltage stabilized
_delay_ms(5);//first output complete
SEND_STRING("Step 1 complete.\r\n",0);
//PORTA=0x30;
//Screen_Execute();//second time
//_delay_us(110);//end
//PORTA=0x30;//third time
//Screen_Execute();
SEND_STRING("Step 2 start.\r\n",0);
//BLINK_LED(1000);
Screen_busy();
PORTA=0x38;//two lines, 8 bits, 5*7 characters
SEND_STRING("Step 2 execute.\r\n",0);
Screen_Execute();
SEND_STRING("Step 2 complete.\r\n",0);
SEND_STRING("Step 3 start.\r\n",0);
//BLINK_LED(1000);
Screen_busy();
PORTA=0x08;//screen off
SEND_STRING("Step 3 execute.\r\n",0);
Screen_Execute();
SEND_STRING("Step 3 complete.\r\n",0);
SEND_STRING("Step 4 start.\r\n",0);
//BLINK_LED(1000);
Screen_busy();
PORTA=0x14;//cursor goes to home and screen is cleared
SEND_STRING("Step 4 execute.\r\n",0);
Screen_Execute();
SEND_STRING("Step 4 complete.\r\n",0);
//Screen_busy();
//PORTA=0x04;//
//Screen_Execute();//end of init
//Screen_busy();
SEND_STRING("Step 5 start.\r\n",0);
//BLINK_LED(1000);
PORTA=0x0F;
Screen_Execute();//cursor blinks, screen works
SEND_STRING("Step 5 execute.\r\n",0);
Screen_busy();
SEND_STRING("Step 5 complete.\r\n",0);
}
My problem is that after initialization, cursor appears on a random position on the screen.
When I try to do initialization as described in the documentation, by sending the PORTA=0x30;
line 3 times, it doesn't work. Also, if I try to use tighter timing, it again doesn't work.
Best Answer
I like the way you do serial port debugging, and the comments at each stage.
It appears that your display, like every other small character LCD display I've ever held in my hands, uses the Hitachi 44780 interface standard. May I ask why you aren't using some pre-tested off-the-shelf LCD library code?
Would something like the following work for you?
p.s.: Rather than use 11 pins of your MCU to control the display, some people sacrifice a little speed to gain back some of those pins: some control the LCD display with 7 pins of the MCU in 4-bit mode, others control their LCD display with 1 pin of the MCU.