Hi, I work on a small project. I am trying to make a module with atmega32 and 20*4 display. Now I am writing a program for atmega to comunicate with display. But I have a problem with initialization-HD44780 has to be first initialized by a special sequence. I found this in my display datasheet:
I tryed this, but nothink happens-the first and third line is full with black squares only. Could anyone help me plz? Thx much
here is my init sequence. Data pins are on port B; Enable, R/W and R/S port C
As i see from your listing, you have to slip in a delay of at least 45us between taking Enable high and then low again otherwise the lcd can't read the data port. It is advisable to wait again 45us after taking E low so the lcd has enough time to process the command. Watch out for commands that take longer to process (marked in red the pause) and also you can write some commands at once as you can see from the listing below!
Have fun!
Caesar.
This is what I use for 8 bit communication:
[E, RW and RS are low]
wait 100ms after power-up
set binary %00111000 on port B
set E high
wait 45us
set E low
wait 45us
set binary %00001100 on port B
set E high
wait 45us
set E low
wait 45us
set binary %00000001 on port B
set E high
wait 45us
set E low
wait 45us
wait 2ms!!!
set binary %00000110 on port B
set E high
wait 45us
set E low
wait 45us
Thx much for help , but the problem still remains
I checked the wiring and it seems ok. So problem could be in Delay(), I will try to rise the delay time, or maybe, if you look the first line, there is:
D7-D0 0011**** . The * meas that it doesn?t matter if I use 0 or 1 on it?s position? So you use 00111000, I use 0x30 (00110000) but is it the same? Also you use it only once, but there is 3xthis sequence, and the rest of your sequence is also little bit different. I tought that every display using HD44780 has the same initialization?
The *'s are dont cares. They can be anything and you need to send the 0011**** sequence 3 times, not once. Is your delay function built into your compiler or did you make the routine? Delay 1000 usually means 1 second, this may be too long for the initialization sequence. From the diagram I posted the first delay is only 4.1 ms and the second is only 100us. I would make sure your delay routine is working and then readjust for the specs. Other than that your code looks good. If your still having problems I can post my code when I get home.
Just a suggestion after you get it initialized and working. After the initialization sequence I would check the busy flag. Its alot easier to tell when the LCD is ready instead of waiting X amount of time. This also allows the LCD to be as fast as possible.
The *'s are dont cares. They can be anything and you need to send the 0011**** sequence 3 times, not once. Is your delay function built into your compiler or did you make the routine? Delay 1000 usually means 1 second, this may be too long for the initialization sequence. From the diagram I posted the first delay is only 4.1 ms and the second is only 100us. I would make sure your delay routine is working and then readjust for the specs. Other than that your code looks good. If your still having problems I can post my code when I get home.
Just a suggestion after you get it initialized and working. After the initialization sequence I would check the busy flag. Its alot easier to tell when the LCD is ready instead of waiting X amount of time. This also allows the LCD to be as fast as possible.
J
thx much. I looked your link and the initialization seems to be same as I posted. My Delay rutine is quite simple:
void Delay (unsigned int interval)
{
unsigned int i;
for (i=0; i < interval; i++);
}
I tought it doesn matter if the delay is longer than for ex. 4,1ms, I put there simply very long interval to be sure it is more than time for init. If you could please post here your rutine, I would check it to see if there is not some different problem.
Here is my procedures. Note that all delays are in milli seconds and all values are in decimal. Disregard the ,1 in the delay statements, they are used for the compiler.
cruzz wrote:Thx much for help , but the problem still remains
I checked the wiring and it seems ok. So problem could be in Delay(), I will try to rise the delay time, or maybe, if you look the first line, there is:
D7-D0 0011**** . The * meas that it doesn?t matter if I use 0 or 1 on it?s position? So you use 00111000, I use 0x30 (00110000) but is it the same? Also you use it only once, but there is 3xthis sequence, and the rest of your sequence is also little bit different. I tought that every display using HD44780 has the same initialization?
I initialise all my displays exactly like this and have no problem. I have only 4 commands bytes sent because the same category of commands are put toghether in 1 byte. So the bytes I send are in fact multiple commands. The timings I use are already very relaxed to fit all kinf of lcd controllers (hd44780 compatible too) so don't go much over them.
The problem will remain if you don't insert a small pause between raising the enable line and lowering it! It has to be high for some microseconds so the lcd knows that there is data on the datalines. If you just quickly toggle the E line than the lcd won't know you sent a command and act dead.
Here is how the communication timings look like for my lcd.
Hi, today I tried it once more. I changed a order of signals like this:
PORTC = (1 << LCD_E);
PORTB = 0x30; //1
PORTC = 0x00;
PORTB = 0x00;
Delay(100);
PORTC = (1 << LCD_E);
PORTB = 0x06; //ID+S
PORTC = 0x00;
PORTB = 0x00;
Delay(100);
and this happened. Display shows on the first and third line black squares. But only for a microsecond, then they disappear. They are not black, just grey and you cant seem them properly, coz they flash only. And then is display clear. I tought I was successfull, but problem is, that I cant display smthink on it. I wrote very simple rutine:
PORTC = (1 << LCD_RS);
PORTC = (1 << LCD_E);
PORTB = 'Hello';
PORTC = ~(1 << LCD_E);
PORTB = 0x00;
PORTC = 0x00;
But nothink happens. Where could be problem now? Initialization still doesn?t work, or did I make some mistake when displaying some word? Thx
edit: sry I was mistaken, display shows only 2 lines of black squares. I only misswired Vcc pin for HD44780 so it didn?t show anythink. Now the situation is like on beggining, two lines of black squares and nothink more
You cannot send 'Hello' out a port. You have to use ASCII values for each letter (look at the character set for the display).
You need some delays between setting the enable high to low and low to high. I would start there. If that doesnt work I would look into your delay routine, maybe its too slow/fast for what you are doing.
I know where the problem is. Today I took my multimeter to check voltages on each pin. I was very surprised when I found R/W high, E high and D0 high (the rest was low). I really can?t understand why...
I post here my wiring and the whole program, I can?t see the problem in it, just I don?t understand it at all... http://www.svki.wz.cz/Download/disp.zip
edit: seems to me as that Atmega32 doesn?t work. When I send PORTB=0xFF and start to measure each pin, it gives 0V Is there somethink in programming I forgot? I write only Flash memmory, do I have to run the program somehow?
edit2: some progress here-I played a little with Fuses and delay rutine and now display is full (all 4 lines) with grey (not black) squares
_X7JAY7X_ wrote:You cannot send 'Hello' out a port. You have to use ASCII values for each letter (look at the character set for the display).
You need some delays between setting the enable high to low and low to high. I would start there. If that doesnt work I would look into your delay routine, maybe its too slow/fast for what you are doing.
J
hello again, I would like to know why I can?t simply send "Hello" to be displayed? I know, that each character should be translated into ASCII, but my friend told me, that ther?s no need to do it. If I program it in language C, the compiler automaticaly translate each character I write, so instead of 'H' he knows its 01001000....
edit: today I put Delay after each step of initialization, and I think I found the problem. Atmega sends the first step and then nothing, it looks like it stops after first step.....
Cruzz, if you cant find anything wrong with the programming check these things. They have all happened to me at one point and it takes you forever to realize it becuase your focused on the programming.
1. Is the watchdog timer off?
2. Is the crystal set at the right frequency?
3. Is the chip good? Do a test if you have to to test the port and timing.
Even if your compiler translates to ASCII you cannot send more than one character at a time the way you have your program. Try just 'H'.
_X7JAY7X_ wrote:Cruzz, if you cant find anything wrong with the programming check these things. They have all happened to me at one point and it takes you forever to realize it becuase your focused on the programming.
1. Is the watchdog timer off?
2. Is the crystal set at the right frequency?
3. Is the chip good? Do a test if you have to to test the port and timing.
Even if your compiler translates to ASCII you cannot send more than one character at a time the way you have your program. Try just 'H'.
J
yeah, of course I would send each char, not the whole word at once
thx much, I?ll check it, I?ve already checked MCUCR register to see if it?s not in Idle mode. As for crystal-I use internal oscilator @1MHz so that shouldn?t be a problem and the chip seems to be good. Problem is,
int main()
Init; //steps to init display
while(1)
PORTB = 0xFF
.
ATmega sends FF to port B, thats good, but the rest of main()-that what is before while, seems to not work, just Atmega skips these steps...