That's Great wildbilly.
And Happy New Year to you too.
I was hoping it would go the 40ft. but wasn't sure.
Don't want to ruin it for you if you're still trying to do 3 LCD's, but I can show you how, if you give up.
regards,
That's Great wildbilly.
And Happy New Year to you too.
I was hoping it would go the 40ft. but wasn't sure.
Don't want to ruin it for you if you're still trying to do 3 LCD's, but I can show you how, if you give up.
regards,
DT
Hi Darrel. I would like to know how to do 3 LCD's. I won't turn down a chance of learning more. Thanks
OK, let's go with the learning ... idea ...
Here's the changes to add 1 more display to what we already have.
Mostly, it's just "more of the same".
These are the same 3 sections that were modified the last time.
New changes are in red ...
Main ProgramLCD_AnyPin.pbpCode:;----[ Change these to match your LCD ]--------------------------------------- LCD_DB4 VAR PORTB.0 LCD_DB5 VAR PORTB.1 LCD_DB6 VAR PORTB.2 LCD_DB7 VAR PORTB.3 LCD_RS VAR PORTB.4 LCD_E1 VAR PORTB.5 LCD_E2 VAR PORTB.6 LCD_E3 VAR PORTD.0 LCDEN VAR BYTE BANK0 ; Enable bits for each LCD LCD1EN VAR LCDEN.0 LCD2EN VAR LCDEN.1 LCD3EN VAR LCDEN.2 LCD_Lines CON 2 ; # of Lines on LCD, 1 or 2 (Note: use 2 for 4 lines) LCD_DATAUS CON 50 ; Data delay time in us LCD_COMMANDUS CON 2000 ; Command delay time in us INCLUDE "LCD_AnyPin.pbp" ; *** Include MUST be AFTER LCD Pin assignments **** LOW LCD_E1 ; Start with Enables OUTPUT LOW LOW LCD_E2 LOW LCD_E3
Code:ASM LCD_Port_HNIB macro ; Port definition for LCD High Nibble Vbit LCDCDFLAG, _LCD_RS ; Select Command/Data register DelayUS 2 NOP Vpin 4, _LCD_DB4 ; Put the High Nibble on the bus Vpin 5, _LCD_DB5 Vpin 6, _LCD_DB6 Vpin 7, _LCD_DB7 DelayUS 2 btfsc _LCD1EN ; Set enable(s) High bsf _LCD_E1 btfsc _LCD2EN bsf _LCD_E2 btfsc _LCD3EN bsf _LCD_E3 DelayUS 5 ; hold for 5us bcf _LCD_E1 ; Enable(s) Low - Clocks data bcf _LCD_E2 bcf _LCD_E3 endm ;----------------------- LCD_Port_LNIB macro ; Port definition for LCD Low Nibble Vpin 0, _LCD_DB4 ; Put the Low Nibble on the bus Vpin 1, _LCD_DB5 Vpin 2, _LCD_DB6 Vpin 3, _LCD_DB7 DelayUS 2 btfsc _LCD1EN ; Set enable(s) High bsf _LCD_E1 btfsc _LCD2EN bsf _LCD_E2 btfsc _LCD3EN bsf _LCD_E3 DelayUS 5 ; hold for 5us bcf _LCD_E1 ; Enable(s) Low - Clocks data bcf _LCD_E2 bcf _LCD_E3 endm ENDASM
LCD_AnyPin.pbp
And then, to use it.Code:;----[Initialize the LCD]-------------------(DO NOT Change)------------------- LCD_Init: @ OutputPort LCD_Port_HNIB ; Set LCD bus to OUTPUT LCDEN = %111 ; Initialize all LCD's at the same time LOW LCD_RS ; Start with RS LOW Char = 3 : gosub LCDsendShortCOM : @ DelayUS 6000 gosub LCDsendShortCOM : @ DelayUS 1000 gosub LCDsendShortCOM : @ DelayUS 1000 Char = 2 : gosub LCDsendShortCOM : @ DelayUS 1000 ; Start 4-bit mode Char = $28 : gosub LCDsendCOM ; Function Set, 4-bit, 2-line, 5x7 Char = $0C : gosub LCDsendCOM ; Display ON Char = $01 : gosub LCDsendCOM ; Clear Screen Char = $06 : gosub LCDsendCOM ; Entry Mode LCD_Initialized = 1 ; LCD has been Initialized goto LCDAfterInit
It still works the same as before.
But now it's easier to treat the Enable bits like a binary number.
With each bit representing a different display ...
And that should be it.<hr>Code:LCDEN = %001 LCDOUT $FE,$80, "Display 1" LCDEN = %010 LCDOUT $FE,$80, "Display 2" LCDEN = %100 LCDOUT $FE,$80, "Display 3" LCDEN = %111 LCDOUT $FE,$C0, "ALL Displays"
Now, Even though this all works fine ...
I don't like it.
After making all the changes to get 3 LCD's to work.
It's still limited to 3 LCD's.
If you want 4, then you have to go modify it again.
Then if you want to use 2 LCD's on another project. It'll throw a bunch of errors, that won't make sense 6 months from now.
Then there's the Timing options.
What if the cable is longer? Or shorter? How do you adjust the delays?
So what I've done, is create a new module that should incorporate everything learned here, and allow everyone to have up to 8 LCD's on long or short cables without to much hassle.
But it takes longer to post the thread, than it does to write the program.
And I Gotta work tomorrow too.
Feel free to use the code I just posted (it should work)
Or you may want to wait for my next post in the PBP Extensions forum. (day or two)<hr>
P.S. It's unfortunate that we still won't know the answer to your first question.
Uhhh, 40 ft, as far as we can say.Originally Posted by wildbilly
But who knows?
<br>
DT
Question from the sidelines...maybe an idea...not sure...haven't looked into it yet...
Couldn't the LCDOUT command itself be 'hi-jacked' inside on of the macros to change the E line assignment dynamically? As far as I know, LCDs won't do squat unless the E line is pulsed.
Maybe something like:
LCDOUT $fe , $fe , 0 , "First LCD"
LCDOUT $fe , $fe , 1 , "Second LCD"
LCDOUT $fe , $fe , 2 , "Third LCD"
....and so on and so on...
As far as I know, there aren't any character LCDs any wider than 40 characters. If the second character in the 'string' was anything above $FC, it could be a 'hijack' command...
or something like that anyways...
As for myself, like I said before, I'm running 3 different types of LCDs on my OBD interface right now (16x2 parallel, 122x32 graphic mode, and a 130x130 Nokia color knockoff).
Guess which one is the easiest to interface with?![]()
Sure,Originally Posted by skimask
With complete control of the LCDOUT command, you can do pretty much whatever you want.
And, It's not a bad idea.
So, with the existing code from this thread.
Changing the LCDsend routine like this ...Then you can embed the LCD selection inside the LCDOUT statements...Code:;----[Send a byte to the Virtual LCD PORT]------------(DO NOT Change)--------- TempChar var byte Char VAR Byte LCD_Initialized VAR FLAGS.1 RSS VAR FLAGS.0 ; LCD RS State HJ_Command VAR BIT ;----[ This routine is called once for every character sent by LCDOUT ]------- LCDsend: @ MOVE?AB _TempChar ; Get char sent by LCDOUT, in WREG if !LCD_Initialized then LCD_Init ; Make sure LCD was Initialized LCDAfterInit: IF HJ_Command then LCDEN = TempChar : HJ_Command = 0 : goto LCDsendDone IF RSS then NO_HJcheck IF TempChar = $FE then RSS = 1 : HJ_Command = 1 : goto LCDsendDone NO_HJcheck: if TempChar = $FE then RSS=0 : goto LCDsendDone ; next char is Command Char = TempChar LCDsendCOM: @ WritePort _Char, LCD_Port_HNIB ; send the High Nibble LCDsendShortCOM: @ WritePort _Char, LCD_Port_LNIB ; send the Low Nibble IF RSS = 0 then ; Is a Command IF Char = 1 then CommandDelay ; Long delay for Clear Screen IF Char = 2 then CommandDelay ; Long delay for Home @ DelayUS _LCD_DATAUS ; Short delay for everything else goto DelayDone else @ DelayUS _LCD_DATAUS ; Short delay for Data goto DelayDone endif CommandDelay: @ DelayUS _LCD_COMMANDUS DelayDone: if LCD_Initialized then RSS = 1 ; Set RS to Data next time LCDsendDone: returnAnd it still works the original way too. (Choices)Code:LCDOUT $FE,$FE,%001, $FE,$80, "Display 1" LCDOUT $FE,$FE,%010, $FE,$80, "Display 2" LCDOUT $FE,$FE,%100, $FE,$80, "Display 3" LCDOUT $FE,$FE,%111, $FE,$C0, "ALL Displays"Now I really gotta go to bed.Code:LCDEN = %001 LCDOUT $FE,$80, "Display 1" LCDEN = %010 LCDOUT $FE,$80, "Display 2" LCDEN = %100 LCDOUT $FE,$80, "Display 3" LCDEN = %111 LCDOUT $FE,$C0, "ALL Displays"
DT
Bookmarks