Expansion made easy ? LCD help SOLVED
I am pulling my teeth out here.
I am using a serial to parallel chip to run an LCD display. This was brought to my attention in the publication "Nuts and Volts" volume 5 Expansion made easy. Long story short I have it wired up exactly as seen in the publication.
My first problem is that the volume was made for the stamp and I am having trouble converting it into spin. Since I don't know p-basic you can appreciate the difficulties involved.
I often get a letter on the display but things are inconsistent. I looked in the object exchange and downloaded an object. I carefully go through the object and try to emulate when ever possible being careful to deviating when needed, because I am using the serial to parallel chip.
Well I am asking could someone help me out. Below is my code and I believe that I am initializing incorrectly or, perhaps I am enabling the display in the wrong sequence.
Post Edited (Zap-o) : 2/11/2010 5:38:03 PM GMT
I am using a serial to parallel chip to run an LCD display. This was brought to my attention in the publication "Nuts and Volts" volume 5 Expansion made easy. Long story short I have it wired up exactly as seen in the publication.
My first problem is that the volume was made for the stamp and I am having trouble converting it into spin. Since I don't know p-basic you can appreciate the difficulties involved.
I often get a letter on the display but things are inconsistent. I looked in the object exchange and downloaded an object. I carefully go through the object and try to emulate when ever possible being careful to deviating when needed, because I am using the serial to parallel chip.
Well I am asking could someone help me out. Below is my code and I believe that I am initializing incorrectly or, perhaps I am enabling the display in the wrong sequence.
Pub SetUp | Temp
ms(16) ' Wait for more than 15 ms
Temp := WritePort(0,%0011_0000)
Enable ' Toggle Enable line
ms(5) ' Wait for more than 4.1 ms
Temp := WritePort(0,%0011_0000)
Enable ' Toggle Enable line
ms(1) ' Wait for more than 100uS
Temp := WritePort(0,%0011_0000)
Enable ' Toggle Enable line
Temp := WritePort(0,%0011_1100) ' Function Set
Enable ' Toggle Enable line
Temp := WritePort(0,%0000_1000)
Enable ' Toggle Enable line
Temp := WritePort(0,%0000_0001) ' Clear Display
Enable ' Toggle Enable line
Temp := WritePort(0,%0000_0100) ' Entry Mode
Enable
Post Edited (Zap-o) : 2/11/2010 5:38:03 PM GMT

Comments
con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 SDA = 29 SCL = 28 En = 5 Rw = 6 RS = 7 var Byte PortData Obj i2cObject : "basic_i2c_driver" pub init | Temp PortData := %0000_0000 'used for En,RS,R/W i2cObject.Initialize(SCL) ms(15) Temp := SetPorts(0,%0000_0000) ' GP0 Temp := SetPorts(1,%0000_0000) ' GP1 Temp := WritePort(0,%0000_0000) ' Low Temp := WritePort(1,PortData) ' Low SetUp writeOut("A") Pub SetUp | Temp Temp := WritePort(0,%0011_0000) Enable ms(5) Enable Enable Temp := WritePort(0,%0011_1100) ' 2 line 5x8 Enable Temp := WritePort(0,%0000_1000) ' Display off Enable Temp := WritePort(0,%0000_0001) 'Display Clear Enable Temp := WritePort(0,%0000_0111)'Entry mode pub commandOut(char) | Temp PortData := BitTrick (PortData,RS,0) Temp := WritePort(1,PortData) writeOut(char) pub writeOut(character) | Temp PortData := BitTrick (PortData,RS,1) Temp := WritePort(0,character) enable Temp := WritePort(1,PortData) pub ms(Delay) waitcnt((clkfreq / 1_000) * Delay + cnt) Pri BitTrick (In,Bit,OnOff) : Out Out := (In & !(1<<bit)) | (OnOff << Bit) Pri Enable | Temp PortData := BitTrick (PortData,En,1) '1 hi Temp := WritePort(1,PortData) ms(1) PortData := BitTrick (PortData,En,0) ' 0 low Temp := WritePort(1,PortData) ms(1) Pri SetPorts(Port,i2cData) : ackbit IF (Port == 0) ackbit := i2cObject.WriteLocation(SCL,%0100_0000 ,$6,i2cData) IF (Port == 1) ackbit := i2cObject.WriteLocation(SCL,%0100_0000 ,$7,i2cData) Pri WritePort(In,i2cData) : ackbit ackbit := i2cObject.WriteLocation(SCL,%0100_0000 , In, i2cData) Pri ReadPort(In) : i2cData i2cData := i2cObject.readLocation(SCL,%0100_0000 ,In)I borrowed code form the LCD object and fullduplexserial to finish the object. It works great. I still need to include the buttons but that should be simple.
{ } con SDA = 29 SCL = 28 En = 5 Rw = 6 RS = 7 linelength = 20 lcdlines = 2 Line1 = $80 'Address of the First Line Line2 = $C0 'Address of the Second Line var Byte PortData Byte CurrentLine Byte CurrentPos Byte CursorState Byte ddra Obj i2cObject : "basic_i2c_driver" pub init | Temp CurrentLine := 0 CurrentPos := 0 CursorState := 0 PortData := %0000_0000 i2cObject.Initialize(SCL) ms(15) Temp := SetPorts(0,%0000_0000) ' GP0 Temp := SetPorts(1,%0000_0000) ' GP1 Temp := WritePort(0,%0000_0000) ' Low port 0 Temp := WritePort(1,PortData) ' Low port 1 IntLcd ' Init display Pub IntLcd | Temp Temp := WritePort(0,%0011_0000) Enable ms(5) Enable Enable Temp := WritePort(0,%0011_1000) ' Function set 0011NF** Enable Temp := WritePort(0,%0000_0001) ' Display Clear Enable Temp := WritePort(0,%0000_1100) ' Entry mode Enable pub Pos(line,column) CurrentLine := (line - 1) & (lcdlines-1) CurrentPos := column - 1 checkddra ddra += CurrentPos commandOut(ddra) pub cursor_on CursorState := 1 commandOut($0F) pub cursor_off CursorState := 0 commandOut($0C) Pub Home CurrentLine-- newline pub clear CommandOut(1) ms(10) pub clearline | lptr home lptr := 0 repeat while lptr < linelength writeOut(" ") lptr++ pub CommandOut(character) | Temp 'Write out a command to the display controller PortData := BitTrick(PortData,RS,0) ' set RS High Temp := WritePort(1,PortData) ' write to port 1 Temp := WritePort(0,character) ' write to port 0 enable PortData := BitTrick (PortData,RS,1) ' set Rs low Temp := WritePort(1,PortData) ' write to port 0 pub writeOut(character) | Temp PortData := BitTrick(PortData,RS,1) ' set RS High Temp := WritePort(1,PortData) ' write to port 1 Temp := WritePort(0,character) ' write to port 0 enable PortData := BitTrick (PortData,RS,0) ' set Rs low Temp := WritePort(1,PortData) ' write to port 0 pub ms(Delay) waitcnt((clkfreq / 1_000) * Delay + cnt) PUB str(stringptr) repeat strsize(stringptr) writeOut(byte[noparse][[/noparse]stringptr++]) PUB Dec(value) | i, x x := value == NEGX ' Check for max negative if value < 0 value := ||(value+x) ' If negative, make positive; adjust for max negative writeOut("-") ' and output sign i := 1_000_000_000 ' Initialize divisor repeat 10 ' Loop for 10 digits if value => i writeOut(value / i + "0" + x*(i == 1)) ' If non-zero digit, output digit; adjust for max negative value //= i ' and digit from value result~~ ' flag non-zero found elseif result or i == 1 writeOut("0") ' If zero digit (or only digit) output it i /= 10 ' Update divisor PUB hex(value, digits) value <<= (8 - digits) << 2 repeat digits writeOut(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) PUB bin(value, digits) value <<= 32 - digits repeat digits writeOut((value <-= 1) & 1 + "0") Pub led(oneOrTwo, onOff) 'OneOrTwo = 0,1 OneOrTwo := 4 - OneOrTwo PortData := BitTrick (PortData ,OneOrTwo,OnOff) Pri BitTrick (In,Bit,OnOff) : Out Out := (In & !(1<<bit)) | (OnOff << Bit) Pri Enable | Temp PortData := BitTrick (PortData,En,1) '1 hi Temp := WritePort(1,PortData) ms(1) PortData := BitTrick (PortData,En,0) ' 0 low Temp := WritePort(1,PortData) ms(1) Pri SetPorts(Port,i2cData) : ackbit IF (Port == 0) ackbit := i2cObject.WriteLocation(SCL,%0100_0000 ,$6,i2cData) IF (Port == 1) ackbit := i2cObject.WriteLocation(SCL,%0100_0000 ,$7,i2cData) Pri WritePort(In,i2cData) : ackbit ackbit := i2cObject.WriteLocation(SCL,%0100_0000 , In, i2cData) Pri ReadPort(In) : i2cData i2cData := i2cObject.readLocation(SCL,%0100_0000 ,In) pri newline 'Go to the next line CurrentPos := 0 CurrentLine++ CurrentLine &= (lcdlines-1) checkddra commandOut(ddra) pri checkddra 'Generate the LCD line address case CurrentLine 0: ddra := Line1 'Address of First Line 1: ddra := Line2 'Address of Second Line