LCD module - Testing Busy Flag problem

Status
Not open for further replies.

hbrault

New Member
I am using an LCD module with a PIC micro controller. Most everything is working the way I want it except checking the busy flag.
To be more specific, I can check the busy flag right after sending a command (or data) to the LCD module. I found plenty of code example on the web (including Nigel's) that do exactly that:
1- Send command to the LCD module.
2- Wait until Busy flag turns to zero
3- Do whatever else you have to do.

But, I was thinking: Why do I want to test the busy flag right after the command. I only need to know if the LCD module is busy before I send the next command.
In other words:
1- Send command to LCD
2- Do something useful while LCD is processing the command
3- If LCD is done with previous command, send the next command.

Unfortunately, when I check the busy flag BEFORE the next command, it never seems to be 0. I haven't found any example like that on the web - all examples test the flag immediately after sending the command.
Does anybody know why this could be happening? Is that a feature of LCD modules (Busy flag only available for a limited time?)
Any clue?
Thanks.
 

Are you changing the port direction before reading the busy flag? Without a schematic and code, it's hard to tell what could be wrong.

Brad
 

Hi,

it is not necessary to check for the busy flag at all if you want to do some other task after sending a command. Some programs use a delay between successive commands for this. Depending on your LCD module you can tell from the datasheet how much time you would want to wait to send the next command.Also if you still want to send the next command, just check the busy flag before sending, do what ever you want in between.
 
Are you changing the port direction before reading the busy flag? Without a schematic and code, it's hard to tell what could be wrong.

Brad

Brad, thank for the reply. Yes I do, manage port direction. I call the same routine that handles everything:
- Changes the port to Input
- Read the busy flag until it becomes 0
- Reset the port back to output

My problem looks like this:

This works:
========

LcdCmd ; Send Command routine
bcf LCD_RS ; RS = 0 (Command)
bcf LCD_RW ; RW = 0 (Write Mode)
movwf m_lcdDataOrCmd ; Save command
swapf m_lcdDataOrCmd, w ; Send upper nibble
call LcdCmdSend4Bit
movfw m_lcdDataOrCmd ; Send lower nibble
call LcdCmdSend4Bit
call LcdBusy ; Make sure the LCD is ready to accept commands
return

This does not work:
==============

LcdCmd ; Send Command routine
call LcdBusy ; Make sure the LCD is ready to accept commands
bcf LCD_RS ; RS = 0 (Command)
bcf LCD_RW ; RW = 0 (Write Mode)
movwf m_lcdDataOrCmd ; Save command
swapf m_lcdDataOrCmd, w ; Send upper nibble
call LcdCmdSend4Bit
movfw m_lcdDataOrCmd ; Send lower nibble
call LcdCmdSend4Bit
return

The only difference is the call to LcdBusy: before or after
 
Last edited:
Wond3rboy, I agree with what you say. All I should have to do is check the busy flag before sending the next command just to make sure the LCD had enough time to process the previous command while the micro controller was doing something else (which could be quick or slow, it depends on the application - right?). That's exactly where my problem lies:

This works
1- SendCommand
2- Wait for Busy flag to be 0


This Does not
1- Wait for Busy flag to be 0
2- SendCommand
In this case, I get stuck on waiting for the busy flag to become 0. Calling the same subroutines, nothing else changes.
 
Last edited:
Can you post your LcdBusy routine?

Mike.

Sure, here it is, with the definitions

#DEFINE LCD_DATA_PORT PORTB
#DEFINE LCD_DATA_TRIS TRISB
#DEFINE LCD_DATA_MASK_INPUT 0x0F ; 1 to become input (1), 0 for untouched
#DEFINE LCD_DATA_MASK_OUTPUT 0xF0 ; 1 for untouched, 0 to become output (0)
#DEFINE LCD_BUSY_FLAG 3 ; Busy flag is LCD data bit 7, Found on RB3

#DEFINE LCD_CTRL_PORT PORTA
#DEFINE LCD_CTRL_TRIS TRISA
#DEFINE LCD_RS LCD_CTRL_PORT,0
#DEFINE LCD_RW LCD_CTRL_PORT,1
#DEFINE LCD_E LCD_CTRL_PORT,2


LcdBusy
;+
; Step 1 - set data port as input
;-
movlw LCD_DATA_MASK_INPUT ; Set bits used by LCD ...
errorlevel -302 ; Temporarily turn off banking message
BANKSEL LCD_DATA_TRIS ; Select correct Bank
iorwf LCD_DATA_TRIS,f ; ... as input (1)
BANK0
errorlevel +302 ; Turn banking messages back ON

;+
; Step 2 - read lcd data
;-
bcf LCD_RS ; RS = 0 (This is a command)
bsf LCD_RW ; RW = 1 (Read Mode)
LcdBusyCheck ;
bsf LCD_E ; Pulse E...
bcf LCD_E ; ... to latch upper nible data
btfss LCD_DATA_PORT, LCD_BUSY_FLAG ; Check busy flag, high = busy. Busy?
goto LcdBusyNotBusy ; No - Done testing
bsf LCD_E ; Pulse E...
bcf LCD_E ; ... to latch lower nibble data
goto LcdBusyCheck ; and check again
LcdBusyNotBusy
bsf LCD_E ; Pulse E...
bcf LCD_E ; ... to latch lower nibble data

LcdBusyResetPort
;+
; Step 3 - reset data port as output
;-
movlw LCD_DATA_MASK_OUTPUT; Set bits used by LCD ...
errorlevel -302 ; Temporarily turn off banking message
BANKSEL LCD_DATA_TRIS ; Select correct Bank
andwf LCD_DATA_TRIS,f ; ... as output (0)
BANK0
errorlevel +302 ; Turn banking messages back ON

return
 
The data is only valid whilst EN is high. You are reading it after setting it back low.

Mike.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…