module TW_LCD
' * Project name:' module TW_LCD.pbas' * Copyright:' Public Domain, 2008' * Author :' Csaba Zvekan' * Revision History:' 20080428:' - initial release.' * Description:' This code demonstrates the two wire Serial LCD Interface originaly' designed Myke Predko. The main code here was written in MikroC by Rich Irace.' I took a different approach for the NybbleShift Routine. More like what' myke suggested on http://www.myke.com/lcd.htm. Also changed some LCD' timing values.' Except at the end I keep Data lines high then low. Different from his' website stated where he keeps clock High then low (to enable "E"pin)' * Test configuration:' MCU: dsPIC30F6014A' Dev.Board: EasyPIC4' Oscillator: HS, 10 - 160.000 MHz fully Tested' Ext. Modules: TW_LCD board, Lcd_2x16' SW: mikroBasic for dsPIC v5.0 or higher' * NOTES:' - In order to have valid function, PORTx pin's must be connected to' pull-up/ or down resistors !' - LEDiodes on PORTx should be turned off !symbol Clk = PORTD.6' PORTD6 for the Clock Signalsymbol Data = PORTD.7' PORTD7 for the Data Signal'* This is where you define the two lines for Clock / Data'**********************************************************************symbol row1 = %00000000' Define on LCD Row1 (0)symbol row2 = %01000000' Define on LCD Row2 (64)
const ClockDelay asbyte = 160dim progarray asstring[17]'*****************************************************************'* Shift Out the Nybble'*****************************************************************sub procedureNybbleShift(dim Nybble asbyte, dim RS asbyte)dim i asbyte'** Empty shift register by writing 6 zeroes to it
Data = 0for i= 1 to 6'Clear the Shift Register by writing
Clk = 1'6 times data 0
Clk = 0next i
'** Output E-pin on LCD at the end of the 6th bit
Data = 1
Clk = 1
Clk = 0'** Output RS-Pin on LCD at 5th position
Data = RS
Clk = 1
Clk = 0'** Output the Nybble highest bit firstfor i= 1 to 4if Nybble.3 = 1then' look at bit MSB lower nybble
Data = 1else
Data = 0endif
Clk = 1
Clk = 0
Nybble= Nybble << 1next i
'** Finish Nybble write with E-pin High
Data = 1' E-pin goes high by pulling Data highdelay_us(1)' 450nS for the delay
Data = 0end sub'**********************************************************************'* Write a byte to LCD with option RS(xx,1) HIGH or RS(xx,0) LOW'**********************************************************************sub procedureTW_LCD_Write(dim LCDData asbyte,dim RSValue asbyte)dim j,t asbyte
t = 0
j = 0
j = LCDData 'save LCDData to jNybbleShift((j >> 4)and 0x0F, RSValue )'Shift out High Nybble'delay_us(ClockDelay) ' 450nS for the clock only if necessary
t = (LCDData << 4)
t = (t >> 4)NybbleShift(t and 0x0F, RSValue)'Shift out Low Nybble'delay_us(ClockDelay) ' 450nS for the clockif((LCDData AND 0xFC) + (RSValue)) = 0thendelay_ms(5)' to be adjusted even higher !!!elsedelay_uS(160)' to be adjusted even higher !!!endifend sub'**********************************************************************'* Converts digital value to BCD'**********************************************************************sub function NumToChar(dim valu asbyte)aschardim ch ascharif(valu < 10)then
ch=valu + 48' 48 = '0'else
valu=valu - 10endif' 65 = A
ch=valu + 65result = ch
end sub'***********************************************************************'* LCD to BCD displays byte in decimal as either 1, 2 or 3 digits'***********************************************************************sub procedure LCDtoBCD(dim valu asinteger,dim digits asinteger)dim d asintegerdim ch asintegerif(digits = 3)then' Take 100's Digits
d = valu/100' Divide it by 100
ch = NumtoChar(d)' Take number, convert it to ASCII' lcdchar(ch) ' number (0 - 9)TW_LCD_Write(ch, 1)' Send that value to displayendifif(digits >1)then' Take the two lowest digits
valu = valu mod 100
d = valu/10
ch = NumtoChar(d)' lcdchar(ch)TW_LCD_Write(ch, 1)endifif(digits = 1)then' Take the least significant digit
valu = valu mod 100endif
d = valu mod 10
ch = NumtoChar(d)' lcdchar(ch)TW_LCD_Write(ch, 1)end sub'**********************************************************************'* LCD Configuration TW_LCD but it don't work !!!'**********************************************************************'sub procedure TW_LCD_Config(dim byref data_port as byte,dim Clk1, Data1 as byte)'symbol Clk = data_port.Clk1 ' PORTB6 for the Clock Signal'symbol Data = data_port.Data1 ' PORTB7 for the Data Signal'end sub'**********************************************************************'* Reset TW_LCD'**********************************************************************sub procedureTW_LCD_Reset()TW_LCD_Write(%00101000, 0)' Switch to 4-Bit mode 2 linesTW_LCD_Write(%00010000, 0)' Turn Off the DisplayTW_LCD_Write(%00000001, 0)' Clear LCD and Home CursorTW_LCD_Write(%00000110, 0)' Move Cursor After Each Character'LCDWrite(%00010000, 0) ' Shift Cursor without chasngin DD Reg'LCDWrite(%00001111, 0) ' Turn On LCD and Enable Cursor & BlinkTW_LCD_Write(%00001100, 0)' Turn On LCD and Disable Cursor& Blinkend sub'************************************************************************'* Initializes the Two Wire LCD'************************************************************************sub procedure TW_LCD_Init()delay_ms(20)NybbleShift(3, 0)' Init LCDdelay_ms(5)NybbleShift(3, 0)' Init LCDdelay_us(160)NybbleShift(3, 0)' Init LCDdelay_us(160)NybbleShift(2, 0)' Set LCD 4 Bit Modedelay_us(160)TW_LCD_Reset()' Call Reset LCDend sub'************************************************************************'* Sends LCD Commands to the TW_LCD Interface same as MikroE'************************************************************************Sub procedureTW_LCD_CMD(dim TW_command asbyte)TW_LCD_Write(TW_command, 0)' Send out a TW_ LCD Commandend sub'***********************************************************************'* Displays String to the TW LCD'*'* When row is 1, Characters are displayed on LCD Row 1 v 0'* When row is 2, Characters are displayed on LCD Row 2 v 64'***********************************************************************sub procedureTW_LCD_Out(dim row asbyte,dim character asbyte, dimbyref s asstring[16])dim i asbyteif row =1then row = row1
endifif row =2then row = row2
endifTW_LCD_Write(%10000000 + row + (character-1), 0)'Move Cursor to the corresponding Row
i = 0while(s[i] <> 0)'Display the stringTW_LCD_Write(s[i],1)inc(i)wendend subend.