' -----[ Title ]----------------------------------------------------------- ' ' File...... LCDTHERM.BS2 ' Purpose... Dallas DS1620 <-> Stamp II -> LCD (4-bit interface) ' Author.... Jon Williams (jonwms@ix.netcom.com) ' Started... 22 July 1995 ' Updated... 28 July 1995 ' -----[ Program Description ]--------------------------------------------- ' ' Displays temperature from Dallas DS1620 chip on a 1x16 LCD. Custom ' characters are used to create a graphical thermometer on the display. ' The program will display the temperature numerically over the entire ' range of the DS1620 (-55C -> +125C). Temperature will be displayed ' graphically for all positive values. ' ' BS2-IC Connections: ' ' Pin 0 LCD.11 | ' Pin 1 LCD.12 |-- OutA ' Pin 2 LCD.13 | ' Pin 3 LCD.14 | ' Pin 4 LCD.4 ' Pin 5 LCD.6 ' Pin 6 NC ' Pin 7 NC ' Pin 8 DS1620.3 ' Pin 9 DS1620.2 ' Pin 10 DS1620.1 ' Pin 11 NC ' Pin 12 NC ' Pin 13 NC ' Pin 14 NC ' Pin 15 NC ' -----[ Revision History ]------------------------------------------------ ' ' 07-26-95 : Version 1.0 complete ' 07-28-95 : Streamlined WrLCD for BS2 (nibble outputs) ' -----[ Constants ]------------------------------------------------------- ' True CON 1 False CON 0 Nlz CON True ' No leading zeros (in T_Out) DegSym CON 223 ' degrees symbol Mode CON "F" ' fahrenheit mode GrMax CON 120 ' max of graphic is 120 degrees GrSeg CON GrMax / 8 ' degrees per segment GrBit CON GrSeg / 5 ' degrees per graphic bit ' LCD control pins ' E CON 5 ' LCD enable pin (1 = enabled) RS CON 4 ' Register Select (1 = char) ' LCD control characters ' ClrLCD CON $01 ' clear the LCD CrsrHm CON $02 ' move cursor to home position CrsrLf CON $10 ' move cursor left CrsrRt CON $14 ' move cursor right DispLf CON $18 ' shift displayed chars left DispRt CON $1C ' shift displayed chars right ' DS1620 pins ' Rst CON 8 ' DS1620.3 Clk CON 9 ' DS1620.2 DQ CON 10 ' DS1620.1 DQIn VAR In10 ' pin 10 input register DQOut VAR Out10 ' pin 10 output register ' DS1620 commands ' RTmp CON $AA ' read temperature WTHi CON $01 ' write TH (high temp register) WTLo CON $02 ' write TL (low temp register) RTHi CON $A1 ' read TH RTLo CON $A2 ' read TL Strt CON $EE ' start conversion StpC CON $22 ' stop conversion WCfg CON $0C ' write configuration register RCfg CON $AC ' read configuration register ' -----[ Variables ]------------------------------------------------------- ' char VAR Byte ' char sent to LCD loop1 VAR Byte ' loop counter cmdByte VAR Byte ' command to send to DS1620 cmdBit VAR cmdByte.Bit0 ' bit to shift out tmpIn VAR Word ' 9-bit temp input from DS1620 inBit VAR tmpIn.Bit8 ' bit to shift in nFlag VAR tmpIn.Bit8 ' negative flag hlfBit VAR tmpIn.Bit0 ' half degree C bit tempC VAR Byte ' converted celcius value tempF VAR Word ' converted fahrenheit value temp VAR Word ' temperature to display sign VAR Byte ' sign of temperature check VAR Word ' scratch value ' -----[ EEPROM Data ]----------------------------------------------------- ' ' custom characters for animated thermometer ' Bulb DATA $0E,$1F,$1F,$1F,$1F,$1F,$0E,$00 Tube1 DATA $00,$1F,$00,$00,$00,$1F,$00,$00 ' tube empty Tube2 DATA $00,$1F,$10,$10,$10,$1F,$00,$00 ' tube 20% Tube3 DATA $00,$1F,$18,$18,$18,$1F,$00,$00 ' tube 40% Tube4 DATA $00,$1F,$1C,$1C,$1C,$1F,$00,$00 ' tube 60% Tube5 DATA $00,$1F,$1E,$1E,$1E,$1F,$00,$00 ' tube 80% Tube6 DATA $00,$1F,$1F,$1F,$1F,$1F,$00,$00 ' tube full Cap DATA $00,$18,$04,$04,$04,$18,$00,$00 ' end of thermometer ' -----[ Initialization ]-------------------------------------------------- ' Init: DirL = %00111111 ' LCD pins DirH = %00000111 ' DS1620 pins Outs = $0000 ' all outputs off to start ' Initialize the DS1620 ' - use with CPU in free run mode ' I_1620: HIGH Rst ' alert the DS1620 cmdByte = WCfg ' prepare to write config GOSUB CmdOut ' send the command cmdByte = %00000010 ' with CPU; free run mode GOSUB CmdOut LOW Rst PAUSE 10 ' pause for EE write cycle HIGH Rst cmdByte = Strt ' start temp conversions GOSUB CmdOut LOW Rst ' Initialize the LCD (Hitatchi HD44780 controller) ' I_LCD: OutA = %0011 ' 8-bit mode PULSOUT E, 1 PAUSE 5 PULSOUT E, 1 PULSOUT E, 1 OutA = %0010 ' 4-bit mode PULSOUT E, 1 char = %00001100 ' disp on, crsr off, blink off GOSUB WrLCD char = %00000110 ' inc crsr, no disp shift GOSUB WrLCD char = %00000001 ' clear LCD GOSUB WrLCD HIGH RS ' LCD to character mode ' download custom characters to LCD ' char = %01000000 ' address 0 of CG RAM GOSUB LCDcmd ' prepare to write CG data FOR loop1 = 0 TO 63 ' build 8 custom chars READ Bulb + loop1, char ' get byte from EEPROM GOSUB WrLCD ' put into LCD CG RAM NEXT ' -----[ Main Code ]------------------------------------------------------- ' Main: char = CrsrHm ' home the LCD cursor GOSUB LCDcmd HIGH Rst ' alert the DS1620 cmdByte = RTmp ' read temperature GOSUB CmdOut GOSUB TempIn ' get the temperature LOW Rst IF Mode = "F" THEN ShowF ShowC: GOSUB GetC ' convert to celcius temp = tempC GOTO ShowT ShowF: GOSUB GetF ' convert to fahrenheit temp = tempF ShowT: char = sign ' show the sign GOSUB WrLCD GOSUB T_Out ' display the temp char = DegSym ' degrees symbol GOSUB WrLCD IF sign = " " THEN ShowG ' show empty thermometer if temp = 0 ' temperature is negative ShowG: GOSUB G_Out GOTO Main ' -----[ Subroutines ]----------------------------------------------------- ' ' send command byte to the DS1620 ' CmdOut: OUTPUT DQ ' make I/O line an output HIGH Clk FOR loop1 = 1 TO 8 ' 8 bits DQOut = cmdBit ' place bit on DQ PULSOUT Clk, 50 ' clock the bit cmdByte = cmdByte >> 1 ' rotate right for next bit NEXT RETURN ' read 9-bit temperature from DS1620 ' TempIn: tmpIn = 0 ' clear input variable INPUT DQ ' make I/O line an imput HIGH Clk FOR loop1 = 1 TO 9 ' 9 bits tmpIn = tmpIn >> 1 ' rotate bits in, lsb first LOW Clk ' clock out the bit inBit = DQIn ' grab it! HIGH Clk NEXT RETURN ' convert reading from 1/2 degrees input (rounds up) ' GetC: IF nFlag = 0 THEN CPos ' check negative bit (8) sign = "-" ' set sign tempC = -tmpIn / 2 + hlfBit ' if neg, take 2's compliment GOTO CDone CPos: sign = " " tempC = tmpIn / 2 + hlfBit CDone: RETURN ' convert (1/2 degrees C) to fahenheit with rounding ' ' general equation (for whole degrees): F = C * 9 / 5 + 32 ' GetF: sign = " " IF nFlag = 0 THEN FPos1 tmpIn = -tmpIn & $FF ' convert from negative IF tmpIn < 36 THEN FPos0 FNeg: sign = "-" tempF = tmpIn * 9 / 10 + hlfBit - 32 GOTO FDone FPos0: tempF = 32 - (tmpIn * 9 / 10 + hlfBit) GOTO FDone FPos1: tempF = tmpIn * 9 / 10 + 32 + hlfBit FDone: RETURN ' display a 3-digit number on the LCD ' ' output is right-justified ' Nlz = No leading zeros (if set to True) ' T_Out: char = temp / 100 + 48 ' convert 100's to ASCII IF char > "0" OR Nlz = False THEN T100 char = " " ' change 0 to space (Nlz = False) T100: GOSUB WrLCD ' show the digit char = temp // 100 / 10 + 48 ' get 10's IF char > "0" THEN T10 IF temp >= 100 OR Nlz = False THEN T10 char = " " T10: GOSUB WrLCD char = temp // 10 + 48 ' get 1's T1: GOSUB WrLCD RETURN ' display temperature as graphic thermometer ' ' This routine uses custom LCD characters to create an animated graphic ' that looks like a (horizontal) glass thermometer. ' ' custom character map downloaded LCD ' ' 0: bulb ' 1: tube 0% ' 2: tube 20% ' 3: tube 40% ' 4: tube 60% ' 5: tube 80% ' 6: tube 100% ' 7: cap ' G_Out: char = $86 ' move to 7th column GOSUB LCDcmd char = 0 ' bulb character GOSUB WrLCD FOR loop1 = 1 TO 8 ' there a 8 segments ("tubes") check = loop1 * GrSeg ' calc step check size char = 6 ' (assume) full tube IF temp >= check THEN GWr ' show full tube char = 1 ' empty tube check = check - temp IF check > GrSeg THEN GWr ' show empty tube char = 1 + (temp // GrSeg / GrBit) ' calc partial tube GWr: GOSUB WrLCD NEXT char = 7 ' cap character GOSUB WrLCD RETURN ' send command byte to LCD ' LCDcmd: LOW RS ' RS low = command GOSUB WrLCD ' send the byte HIGH RS ' return to character mode RETURN ' Write ASCII char to LCD ' WrLCD: OutA = char >> 4 ' output high nibble PULSOUT E, 1 ' strobe the Enable line OutA = char ' output low nibble PULSOUT E, 1 RETURN -- Jon Williams Riverside, CA USA jonwms@ix.netcom.com