Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

16X2 Character Display Fills Screen

Status
Not open for further replies.

jpanhalt

Well-Known Member
Most Helpful Member
Chip: 16F1829 Language: MPASM Display: generic HD44780U controller

I've been wrestling with this $2 display for 2 days. It works in 4-bit mode. I wanted to try 8-bit mode. Here is what the screen looks like:
upload_2015-11-18_14-8-8.png

I can add delays and get one line to fill before the other, but it appears as if all 16 characters are written simultaneously or with a very fast scroll.

Here is the code after POR:
Code:
    movlw     0x38                ;step 5 0x38=8-bit, 2 lines, 5X8 font
     call      PutCmd              ;0x30=8-bit, 1 line, 5X8
     DelayCy   (100*usecs)
     movlw     0x08                ;step 6 0x0E turns on display and cursor
     call      PutCmd              ;0x0C turns on display no cursor
     DelayCy   (100*usecs)
     movlw     0x01                ;step 7
     call      PutCmd
     DelayCy   (4*msecs)
     movlw     0x06                ;step 8 entry mode set increment and shift cursor to right 
     call      PutCmd 
     DelayCy   (100*usecs)         ;execution t=37 us
     movlw     0x0C                ;step 10   
     call      PutCmd
     DelayCy   (100*usecs)
     movlw     0x10               ;no effect
     call      PutCmd
     DelayCy   (100*usecs)
Main

Test
    ; movlw     0x20                ;0x84 causes blink, as does 0x20     
    ; call      PutDat
    ; DelayCy   (150*msecs)
    ; DelayCy   (150*msecs)
;    movlw     0x80              ;from working4-bit   
;    call      PutCmd
;    DelayCy   (100*usecs)
     movlw     '0'
     call      PutDat
     DelayCy   (150*msecs)   
     movlw     '1'
     call      PutDat
     DelayCy   (150*msecs)
     movlw     '2'
     call      PutDat
     DelayCy   (150*msecs)
     movlw     '3'
     call      PutDat
     DelayCy   (150*msecs)
     movlw     '4'
     call      PutDat
     DelayCy   (150*msecs)
     DelayCy   (150*msecs)
     DelayCy   (150*msecs)
     DelayCy   (150*msecs)
     bra       Test
  ;   goto      $-1
      
PutCmd
     bcf       RS                  ;RS=0 for Cmd
     bra       $+2
PutDat
     bsf       RS                  ;RS=1 for Dat
     movwf     PORTC     ;LATC
     bsf       E                   ;is a 37 usec delay needed?
    ;DelayCy   (5*usecs)          ;seems to work w/o
     nop
     bcf       E
     return

I have not removed all of the comments in the code. I have tried longer delays on pulsing E without effect. Also the original version wrote to LATx and I changed to PORTx in desperation. All of the command functions are to PORTA/LATA . PORTC/LATC outputs to data bits D0-D7. D/W is grounded. No reads of busy.

The comment "step" refers to initialization steps listed here: **broken link removed**
They are the same as in the Hitachi datasheet, except for a little more explanation.

Any ideas on how to turn off the simultaneous writing to each position?

John
 
Last edited:
I have never had an issue with 8 bit usage..

My init is as follows...

wait 15ms
put 0x38
wait 5ms
put 0x38
wait 1ms
put 0x38
wait busy
put 0x0C
wait busy
put 0x06
wait busy
put 0x01
wait busy

Ready to go...
 
Hi Ian,

I tried that sequence, again. No change. The 0x38 shouldn't be any different than 0x30, but I tired Ox38 anyway. For the 0x06 ("Entry Mode Set" = cursor move and direction), I have also tried 0x04, i.e, no auto increment and that had no effect.

When I use all the tricks I know, including peripheral vision and a photo, the lines seem to fill with the same speed as a single character. That is, with a photo, I can catch a character in transition to another, and all 16 spaces show the same level of transition.

John

UPDATE: I did some experiments and convinced myself that the problem is in the code. I have some ideas where and will get some sleep. As usual, if any of my ideas are right, the solution is silly simple.
 
Last edited:
Try replacing "bra Test" with "bra $" so that it doesn't loop.

The micro does not have to continuously loop writing out the characters as the LCD's controller handles the display refresh on its own. Your micro only needs to send the characters once and the display will continue to display them until you overwrite them.

Also...you only need two different delay times with the HD44780. A 125uS delay for most routines and a 2mS anytime you send a 0x01 clear display/return home instruction. For condensed code, I would add DelayCy (125*usecs) as the last instruction before the return instruction in your LCD write routine.
 
Thank you all for the suggestions. I made some progress this morning. It seems to be all in the delays. I inserted my code's subroutines into a working 4-bit method, and it continues to work. So, now it is back to the 8-bit method.

Mike - K8LH : That was just a command I added in desperation. I posted approximately 11 hours after I started on it yesterday. I had made lots of changes and substitutions in that period. When I start missing the obvious or do crazy stuff, I put everything away until the next day.
Jon Wilder : I had tried "bra $" before but did it again to to confirm. That does not affect what was happening. Appreciate the advice on delays. I have found the display to start somewhat erratically when it is left in during ICSP, so I just unplug it, let it sit, and then when restarted, I get a truer "cold boot."

Regards, John
 
Hi John,

A question that comes up is, why would you want to run in 8 bit mode instead of 4 bit mode, or even without an IC2 piggy back interface? 8 bit takes more uC pins of course.
Do you need to load it really fast or something?
 
Assume you are trying to display 4 bytes in hex. That is 8 characters or about 8.32 ms at 9600 baud while the MCU can do little else. Baud 19200, which is available on my little Parallax 2X16 serial display, will probably be adequate and works well at 19200 baud. Basically, I thought it would be fun to play with the parallel interfaces for these cheap displays.

John
 
Hi,

Oh ok i see, so it is more for finding out how it can be done just to see how well it works.

I did an 8 bit interface for another type of display the WinTek 16x1 character display, but that was ALL it could do. No 4 bit, no IC2, no serial. The manufacturer has it hard wired to do 8 bit only, when the controller was capable of 4 bit, IC2, and serial. That was nasty of them.

I use IC2 for most of my 1602 displays now, and it doesnt seem to bottleneck any code sections or anything. One application is a dual clock, where the user has to be able to set days, hours, minutes, seconds, and there is still a sense of good human responsiveness. I guess the main thing is that the human sense of responsiveness is much much slower than any code section anyway, so writing to the whole display takes less time than the required debounce time of the setting push button switches. I even had to add a little more time.

From what i remember about the controller for your display there was a certain code for setting up the 4 bit display, and i thought it probably started up in 8 bit mode, but i cant remember that well. It may also require a reset first, so the display might need a reset command which could be a separate input pin, then after that it might respond normally. My WinTek display would sometimes require a reset and sometimes not, so i hard wired a hardware reset (resistor + capacitor) to reset on power up. Always worked after that.

Oh yeah, also a delay at the start of the code to allow the display to get up and running normally before sending any code.

I guess there is also the chance that there is something wrong with the display. You should probably try another display from a different supplier and see if you can get that one running first. If you get that running and not the one you have now, you know there is a problem with the one you have now, otherwise it really is the code.
 
Hi,

Yes, and even faster than most other serial interfaces (it becomes a serial interface with the introduction of a 74xx164).
I think most of these chips will do up to 20MHz or better, so the LCD itself will be the only limiting factor.
 
I've recently started using these LCD displays, and I've noticed some very inefficiently written driver routine libraries on PIClist. I used one of the existing assembly language libraries to get my feet wet, but then rewrote a lot of the code. Looking through the HD44780 datasheet, I found that the library delay times for many of the commands were far longer than they needed to be. When I shortened the delays, it freed up a lot of processor time. For example, according to the datasheet, when sending characters to the display, the delay between sending bytes or nibbles (4 bit mode) doesn't need to be any more than 40 microseconds, but a lot of the library code uses delays measured in milliseconds.
 
I agree with your observations based only on a few days' efforts. It's almost as if someone had problems, thought it might be timing, doubled all of their delays, and kept doing that until it worked. Case on point, E does not need to be high very long (450 ns or so), it's the execution that takes time, yet one can find delays of many usec for E high.

Once I am comfortable with my displays -- got another one today --, I will almost certainly do a backpack like Mike McLaren (K8LH) has described in practice. In fact, I just placed an order with DigiKey for some shift registers and other things. In the meantime, I am trying to measure the elapsed time for execution using MPLab and ICD3 hardware simulation (i.e., monitoring the BF). Had some problems with my ICD3 last night, did the diagnostics this morning, and according to those results it is OK. I did a 4-bit version on a 16F628A, only to find that MC only supports one hardware breakpoint for that chip. I plan to re-write for one of the enhanced chips (16F18xx or 16F15xx), which give 3 breakpoints, I think.

John
 
I don't use a delay between the two nibbles in 4-bit interface mode since I assumed the LCD was simply latching the first 4-bit nibble. Am I doing that wrong, guys?
 
Last edited:
So far as I know based on my reading, your analysis is correct. Even more important, your code works. Thanks for sharing it.

John
 
I don't use a delay between the two nibbles in 4-bit interface mode since I assumed the LCD was simply latching the first 4-bit nibble. Am I doing that wrong, guys?
No! You are quite right.. The delay is after the full command.. All 8 bits.... The only reason I used a tiny delay here is for simulation... ISIS expects a cycle or two..
 
Thanks for pointing that out. I'll take the delay out of my code. It wasn't clear to me from my initial reading of the datasheet whether a delay was required between nibbles. The library routine that I had been using put a 2 ms delay after every pulse of the enable line. I shortened them to 40 µs, but otherwise left them where they were in the code.
 
Thanks for pointing that out. I'll take the delay out of my code. It wasn't clear to me from my initial reading of the datasheet whether a delay was required between nibbles. The library routine that I had been using put a 2 ms delay after every pulse of the enable line. I shortened them to 40 µs, but otherwise left them where they were in the code.
It really doesn't matter... The screen updates are usually 2~3 times a second so all these tiny delays matter not a jot!!

I had longer than necessary delays in my routines for years, did no harm!!
 
So far as I know based on my reading, your analysis is correct. Even more important, your code works. Thanks for sharing it.

John

Hi John,

So you got it to work now? What was the error then, an error in the code?
 
I have not actually used the code Mike posted for his backpack. My shift registers won't get here unit Tuesday; however, I have no doubts Mike's code works. As a small update, I have been testing 4-bit mode on a 16F628A at 4 MHz. PortB<3:0> is used for driving pins DB<7:4> of the display.

This code works fine for command and data to print HELLO WORLD:
Code:
PutCmd 
     bcf       RS
     goto      $+2
PutDat 
    bsf       RS
     movwf     PORTB
     swapf     PORTB,f
     bsf       E
     bcf       E
     swapf     PORTB,f    ; w is preserved, so movwf should also work
     bsf       E
     bcf       E
     ;call      WNB         
     DelayCy   (50*usecs)   
     return

Note: Nothing else is happening on PortB during this time.
I have also been looking at the initialization and function setting commands and sequence. If you go to page 46 of the Hitachi datasheet for the HD44780U controller, you will find this sequence:

upload_2015-11-21_11-23-4.png




Some people do POR and the early steps for initialization and function setting by sending only 4 bits to the controller rather than two writes of 4-bits each . The controller defaults in 8-bit mode, so until the controller is in 4-bit mode, two, 4-bit sends might be interpreted as two instructions, not one. To protect against that, it seems that early on, the controller ignores the second write. Thus, you can send either a 4-bit nibble or the two nibbles as is done once in 4-bit mode. The question is, at what point does the 4-bit mode become active, so the user must do two writes of 4 bits each?

I think I found that step, but from reading the Hitachi comments, it was not clear to me until I knew the answer. Then, it was obvious (duh). There are 5 choices. Two are pretty obviously not right. Which one is it? BTW, this is really a question of understanding the DS for me. In reality, it seems you can use the 8-bit codes in 4-bit mode from the very start. You just have to be sure to start 4-bit mode at the right time. :)

BTW: WNB = wait not busy. I do intend to see what that time is, at least in simulation.

John
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top