LCD code use Lower part instead of high of Port B

tcpip

New Member
I want to use the code below but instead of using the high part of port B (B.4-B.7), I want to use the low part (B.0-B.3) and for RS=B.4 and E=B.5.
How should I do this?

Code:
dirsB = $FF

  symbol Counter = b55
  symbol chr     = b54

'LCD
  symbol RSCMDmask = %00000000 	'select Command register
  symbol RSDATmask = %00000100 	'select Data register
  symbol Line1 = $80 		 	'1ST Line address
  symbol Line2 = $C0  			'2bd line address
  symbol En    = B.3
  symbol rsbit = b53

'initialize LCD
  eeprom  0, ($33, $32, $28, $0C, $06)

  pause 500
  for counter = 0 to 5
    read counter, Chr
    gosub SendCmdLCD 
    pause 300
  next counter



Main:
  chr = "T" 
          GOSUB SendDataLCD
  chr = "E" 
          GOSUB SendDataLCD
  chr = "S"
          GOSUB SendDataLCD 
  chr = "T"
          GOSUB SendDataLCD 
goto Main




'LCD Routines
SendCmdLCD:
  RSbit = RSCMDmask

SendDataLCD:
  pinsB = chr & %11110000 | rsbit
  pulsout En, 2

  pinsB = chr * %00010000 | rsbit
  pulsout En, 2

  rsbit = RSDATmask
 return
 

PaulRB

Senior Member
Funny you should ask that... I've just done almost exactly that myself. Here's my code - see if you can figure it out from that.

Code:
 ; Clock 2013
; P. Beard 25/3/2013

#picaxe 20m2
#terminal 4800

; RTC symbols (Jungletronics DS1338 based module)
symbol RTC = $D0 ; I2C slave address
symbol RTC_Tick = pinC.1
 
 ; LCD Symbols (16x2 driven in 4-bit parrallel mode)
symbol	LCD_D4 = pinB.3
symbol	LCD_D5 = pinB.2
symbol	LCD_D6 = pinB.1
symbol	LCD_D7 = pinB.0
symbol	LCD_E = B.4
symbol	LCD_RS = B.6

symbol	RTCsecs = b8
symbol	ScrollPos = b9

symbol	DOW_Text = 0
data		DOW_Text, ("MTWTFSS", "ouehrau", "neduitn")
symbol	MONTH_Text = 21
data		MONTH_Text, ("JFMAMJJASOND", "aeapauuuecoe", "nbrrynlgptvc")

symbol	Screen_Buffer1 = 28
symbol	Screen_Buffer2_Start = 44
symbol	Screen_Buffer2_End = 59

main:

	setfreq m4

	; Set time on RTC 
	HI2CSETUP I2CMASTER, RTC, i2cslow, i2cbyte
	;HI2COUT 0, (<secs>, <mins>, <hours>, <dow>, <day>, <month>, <year>, <control bits>)
	HI2COUT 0, ($00, $00, $23, $02, $26, $03, $13, %00010000)
	
	'Initialise LCD
	dirsB = %11111111
	low LCD_RS
	'Pause 500
	for b1 = 0 to 4
		lookup b1, ($33,$32,$28,$0C,$01), b0   '(4Bit)(Function 4bit/2line/5x8)(Display On)(Clear Display)
		gosub LCD_byte_send
	next
	
	ScrollPos = Screen_Buffer2_Start
	gosub Update_LCD

	setint %0000010, %0000010	

	do
		pause 10
		sertxd (".")
	loop
	
interrupt:

	gosub LCD_line2_send
	
	if RTC_Tick = 0 then

		sertxd ("Tick", cr, lf)
		inc RTCsecs
		if RTCsecs = 60 then
			gosub Update_LCD
		else
			b0 = $86  : gosub LCD_control_byte_send
			bintoascii RTCsecs, b0, b0, b1
			gosub LCD_byte_send
			b0 = b1 : gosub LCD_byte_send
		end if
		setint %0000010, %0000010
	else
		sertxd ("Tock", cr, lf)
		setint %0000000, %0000010
	endif
	return

LCD_byte_send:	'Send B0 to LCD

	LCD_D4 = bit4 : LCD_D5 = bit5 : LCD_D6 = bit6 : LCD_D7 = bit7 : pulsout LCD_E, 1
	LCD_D4 = bit0 : LCD_D5 = bit1 : LCD_D6 = bit2 : LCD_D7 = bit3 : pulsout LCD_E, 1
	return
	
LCD_control_byte_send:

	low LCD_RS : gosub LCD_byte_send : high LCD_RS
	return
	
LCD_line1_send:	'Send screen buffer line 1 to LCD

	b0 = $80  : gosub LCD_control_byte_send
	bptr = Screen_Buffer1
	For b1 = 0 to 15
		b0 = @bptrinc  : gosub LCD_byte_send
	Next
	return
	
LCD_line2_send:	'Send screen buffer line 2 to LCD
	b0 = $C0  : gosub LCD_control_byte_send
	bptr = ScrollPos
	for b1 = 0 to 15
		b0 = @bptrinc  : gosub LCD_byte_send
		if bptr > Screen_Buffer2_End then
			bptr = Screen_Buffer2_Start
		endif
	next
	inc ScrollPos
	if ScrollPos > Screen_Buffer2_End then
		ScrollPos = Screen_Buffer2_Start
	endif
	return
	
Update_LCD:

	; Read current time from RTC
	HI2CSETUP I2CMASTER, RTC, i2cslow, i2cbyte
	HI2CIN 0, (RTCsecs, b1, b2, b3, b4, b5, b6)
	b0 = RTCsecs & 15
	RTCsecs = RTCsecs / 16 * 10 + b0
	
	; Update screen buffer line 1
	bptr = Screen_Buffer1
	bcdtoascii b2, @bptrinc, @bptrinc
	@bptrinc = ":"
	bcdtoascii b1, @bptrinc, @bptrinc
	@bptrinc = ":"
	bintoascii RTCsecs, b0, @bptrinc, @bptrinc
	@bptrinc = " " : @bptrinc = " " : @bptrinc = " " : @bptrinc = " "
	readinternaltemp IT_3V5, 0, b0
	bintoascii b0, b1, @bptrinc, @bptrinc
	@bptrinc = $DF : @bptrinc = "C"
	gosub LCD_line1_send
	
	
	; Update screen buffer line 2
	bptr = Screen_Buffer2_Start
	b3 = b3 + DOW_Text - 1 : read b3, @bptrinc
	b3 = b3 + 7 : read b3, @bptrinc
	b3 = b3 + 7 : read b3, @bptrinc
	@bptrinc = " "
	bcdtoascii b4, @bptrinc, @bptrinc
	@bptrinc = " "
	b5 = b5 + Month_Text - 1 : read b5, @bptrinc
	b5 = b5 + 12 : read b5, @bptrinc
	b5 = b5 + 12 : read b5, @bptrinc
	@bptrinc = " " : @bptrinc = "2" : @bptrinc = "0"
	bcdtoascii b6, @bptrinc, @bptrinc
	@bptrinc = " "
	'gosub LCD_line2_send
	return

end
Hint: its the LCD_byte_send subroutine.

1364588227666.jpg
 
Last edited:

tcpip

New Member
Thanks PaulRB and westaust55! I've stripped PaulRB's code down (see below) and it's working like a charm...

Code:
; Clock 2013
; P. Beard 25/3/2013

#picaxe 20x2
#terminal 4800
 
 ; LCD Symbols (16x2 driven in 4-bit parrallel mode)
symbol	LCD_D4 = pinB.3
symbol	LCD_D5 = pinB.2
symbol	LCD_D6 = pinB.1
symbol	LCD_D7 = pinB.0
symbol	LCD_E  = B.5
symbol	LCD_RS = B.4

	setfreq m4


	
	'Initialise LCD
	dirsB = %11111111
	low LCD_RS
	'Pause 500
	for b1 = 0 to 4
		lookup b1, ($33,$32,$28,$0C,$01), b0   '(4Bit)(Function 4bit/2line/5x8)(Display On)(Clear Display)
		gosub LCD_byte_send
	next
	
	
	
	main:
	b0 = $80  : gosub LCD_control_byte_send
	b0 = "T" : gosub LCD_byte_send
	b0 = "E" : gosub LCD_byte_send
	b0 = "S" : gosub LCD_byte_send
	b0 = "T" : gosub LCD_byte_send
	
	pause 1000
	
	goto main
	

LCD_byte_send:	'Send B0 to LCD

	LCD_D4 = bit4 : LCD_D5 = bit5 : LCD_D6 = bit6 : LCD_D7 = bit7 : pulsout LCD_E, 1
	LCD_D4 = bit0 : LCD_D5 = bit1 : LCD_D6 = bit2 : LCD_D7 = bit3 : pulsout LCD_E, 1
	return
	
LCD_control_byte_send:

	low LCD_RS : gosub LCD_byte_send : high LCD_RS
	return
 

PaulRB

Senior Member
Can anyone see why the readinternaltemp command in my code is giving such crazy results? I know its not very accurate, but you can see from the pics that something is not right. Did I make a coding error?
 

PaulRB

Senior Member
"When the other (than RAW) settings are used the PICAXE attempts to mathematically change the value into an approximate reading in degrees Celsius."
 

PaulRB

Senior Member
Thanks Technical. Did you change your answer there?

The cells are nimh, so probably around 3.6 or 3.8V in total, so thats why I chose IT_3V5.

I'll play with the offset.
 

inglewoodpete

Senior Member
Thanks PaulRB and westaust55! I've stripped PaulRB's code down (see below) and it's working like a charm...
Running the 20X2 at 4MHz is like driving with the parking brake on. The 20X2 can update a 16X2 LCD 16 times faster than that! Unless you have a reason to continue the use 4MHz, speed it up to 64MHz. With some code improvements, you can update the 16X2 LCD in under 20mS with a 4-bit bus.
 
Top