I'm looking for good ways to integrate LCD processing code into software on an old 8051 IC.
Because the human eye can't process stuff as fast as computers can, what I currently have is a timer that fires off once every 3mS to update a character on the LCD from a set of characters from specific ram location.
I have learned one problem. Trying to change contents of the same ram location while the LCD routine is trying to process characters is a disaster because I'm overwriting ram before the LCD has a chance to finish displaying the characters.
The first thing that people may say is for me to invent a circular buffer and use it. But seeing that my memory is so small, I don't know how feasible it is, because it involves adding more instructions just to put the character in queue and to take it out of queue. But imagine if I wanted to display a 64-character string and I wanted to use the small buffer. Then I'll be in a disaster because then I'll have to stall my program for characters 17 to 64.
Yes, I considered the bank switching trick but all my banks are in use.
Another thing people might say is to reduce the timing of LCD character updates to say 70 uS (so timer interrupt executes more often) but doing that will slow other parts of the system.
The LCD in question is 16 characters wide by 4 characters down with an HD44780 compatible chipset.
The data I'm sending to the LCD routine are null terminated strings in which the MSB determines if the character is a command to set location or to display text. At the moment, the data in question is 5 chunks of 5 bytes (1 byte to set location, 3 for data, and 1 for null).
I don't trust the busy flag on the LCD itself because I heard stories that the timing on it may be worse, meaning it will take longer to process a character than generated timing in software.
I know I'm specifically using the 8051 but the answer to this question can benefit people using any microcontroller.
So what would be the best approach here?
HD44780 data sheet say that the write data to DDRAM as 37u sec.
You have a 40 u sec timer interrupt service routine to display the string.
You initialize the row and column address for LCD and the address from which data is to be displayed. Also you should set it to auto increment mode (Entry mode set).
You enable the 40 u sec timer interrupt.
In interrupt service routine put the present character pointed by address to LCD data. Increment the string address and find out is it the last character. If it is the last character disable the Interrupt.
Like this with minimum overhead you can move data to LCD.
Proposal: Setup a periodic timer with about 10ms duration. Inside the ISR check the busy flag. If not busy write the character. If busy terminate the ISR. Once all characters are transferred, disable the timer.
Assumption is that busy flag is working and that the worst case timing of 37ms does not always apply.
Now that I think about it, I should have mentioned that I have hardwired the RW pin to ground, so checking the busy flag wont work. Plus I have no free GPIO pins left
In that case you need to go for a fixed timing approach as proposed by BVRamesh.