![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | Thread Tools | Display Modes |
| | (permalink) |
| Experienced Member | The following code is adapted from Nigels LCD tutorials. Im trying to modify it so that instead of using a0-a3 for data lines, it uses b0-b3 for the data. I thought that this would be extremely simple to implement (i.e change wires, change applicable LCD_PORT code From A to PORTB.) For some reason though, it doesnt work! can anyone see the problem? I have left the code so that it writes data to both port a and portb, just so i can quickly change the wires round to see it working. Many thanks Code:
LIST p=16F628a ;tell assembler what chip we are using
include "P16F628a.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__cONFIG _CP_OFF &_PWRTE_OFF & _WDT_OFF &_DATA_CP_OFF & _MCLRE_OFF & _INTOSC_OSC_NOCLKOUT &_LVP_OFF
;Set led on
Led_On Macro Led
banksel LED_PORT
bsf LED_PORT, Led
endm
;Set led off
Led_Off Macro Led
banksel LED_PORT
bcf LED_PORT, Led
endm
cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
temp
delayCountA
delayCountB
delayCountC
messageCounter
tmp1 ;temporary storage
tmp2
templcd ;temp store for 4 bit mode
templcd2
NumL ;Binary inputs for decimal convert routine
NumH
TenK ;Decimal outputs from convert routine
Thou
Hund
Tens
Ones
endc
LED_PORT Equ PORTB
LCD_DATA_PORT Equ PORTB
LED_TRIS Equ TRISB
LED_GREEN Equ 0x00
LED_YELLOW Equ 0x01
LCD_PORT Equ PORTA
LCD_TRIS Equ TRISA
LCD_RS Equ 0x04 ;LCD handshake lines
LCD_RW Equ 0x06
LCD_E Equ 0x07
org 0x0000
call Delay100
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
goto Initialise
Text addwf PCL, f
retlw ' '
retlw ' '
retlw 'H'
retlw 'e'
retlw 'r'
retlw 'b'
retlw 'e'
retlw 'r'
retlw 't'
retlw 'M'
retlw 'u'
retlw 'n'
retlw 'c'
retlw 'h'
retlw ' '
retlw ' '
retlw 0x00
LCD_Init
call Delay100
movlw 0x28 ;4bit 2 lines 5x7
call LCD_Cmd
movlw 0x0c ;Display On
call LCD_Cmd
movlw 0x06 ;charactor increment on
call LCD_Cmd
call LCD_Clear
call LCD_Line2
retlw 0x00
Initialise clrf count
clrf PORTA
clrf PORTB
clrf messageCounter
SetPorts
BANKSEL LCD_TRIS
CLRF LCD_TRIS ;MAKE ALL PORTS OUTPUTS
CLRF LED_TRIS
Led_On LED_GREEN
call Delay100
call LCD_Init
call Message
movlw 0x02
call LCD_Cmd
goto $
Message
clrf messageCounter
messagego
movf messageCounter, w ;Set charactor index
call Text ;retrieve charactor
xorlw 0x00
btfsc STATUS, Z ;Check if its 0
retlw 0x00
call LCD_Char
incf messageCounter , f
goto messagego
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LCD HD44780 Instructions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Clears the screen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_Clear
movlw 0x01
call LCD_Cmd
retlw 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Goes to Line2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_Line2
movlw 0xC0
call LCD_Cmd
retlw 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Set the LCD CGRam address [W]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_CGRAM_Address
movwf temp
bcf temp, 7 ;Clear bit 7
bsf temp, 6 ;Set bit 6
movf temp, W ;move into w
call LCD_Cmd ;send command
retlw 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Shift the LCD display Left
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_ShiftDisplay_Left
movlw 0x18
call LCD_Cmd ;send command
retlw 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Shift the LCD display Left
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_ShiftDisplay_Right
movlw 0x1C
call LCD_Cmd ;send command
retlw 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Set the LCD Display address [W]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_Display_Address
movwf temp
bsf temp, 7 ;ensure bit 7 is set
movf temp, W ;move into w
call LCD_Cmd ;send command
retlw 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LCD CORE ROUTINES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_Cmd
Led_On LED_YELLOW
movwf templcd
swapf templcd, w ;swap nibbles around, so we send the high nibble first on a0-a3
andlw 0x0f ;clear LCD handshaking lines
movwf LCD_PORT ;set data
movwf LCD_DATA_PORT
bcf LCD_PORT,LCD_RS ;set up instruction
call Pulse_E ;Inform lcd data ready. Send high nibble
movf templcd, w ;Select lower nibble
andlw 0x0f ;clear LCD handshaking lines
movwf LCD_PORT
movwf LCD_DATA_PORT
bcf LCD_PORT,LCD_RS ;Instruction
call Pulse_E ;inform lcd data ready. Send low nibble
call Delay100 ;Wait until lcd ready.
Led_Off LED_YELLOW
retlw 0x00
LCD_CharA movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_E ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_E ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_Char
Led_On LED_YELLOW
movwf templcd ;store charactor
swapf templcd, W ;swap nibbles around, so that we send high nibble first on a0-a3
andlw 0x0f ;clear LCD handshaking lines
movwf LCD_PORT ;set data on pins a0-a3
movwf LCD_DATA_PORT
bsf LCD_PORT, LCD_RS ;setup to write charactor
call Pulse_E ;Inform lcd data ready, send high nibble
movf templcd, W ;Select stored charactor
andlw 0x0F ;Clear lcd handshaking lines, leaving data on a0-a3
movwf LCD_PORT ;set data on pins a0-a3
movwf LCD_DATA_PORT
bsf LCD_PORT, LCD_RS ;setup to write character
call Pulse_E ;send data.
call LCD_Busy
Led_Off LED_YELLOW
retlw 0x00
Pulse_E
bsf LCD_PORT, LCD_E ;make e high
nop
bcf LCD_PORT,LCD_E ;e low, signals data ready
retlw 0x00
LCD_BusyA
MakePortInputs
banksel LCD_TRIS
MakePortOutputs
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7 ;delay 1mS
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
;This routine downloaded from http://www.piclist.com
Convert: ; Takes number in NumH:NumL
; Returns decimal in
; TenK:Thou:Hund:Tens:Ones
swapf NumH, w
iorlw B'11110000'
movwf Thou
addwf Thou,f
addlw 0XE2
movwf Hund
addlw 0X32
movwf Ones
movf NumH,w
andlw 0X0F
addwf Hund,f
addwf Hund,f
addwf Ones,f
addlw 0XE9
movwf Tens
addwf Tens,f
addwf Tens,f
swapf NumL,w
andlw 0X0F
addwf Tens,f
addwf Ones,f
rlf Tens,f
rlf Ones,f
comf Ones,f
rlf Ones,f
movf NumL,w
andlw 0X0F
addwf Ones,f
rlf Thou,f
movlw 0X07
movwf TenK
; At this point, the original number is
; equal to
; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
; if those entities are regarded as two's
; complement binary. To be precise, all of
; them are negative except TenK. Now the number
; needs to be normalized, but this can all be
; done with simple byte arithmetic.
movlw 0X0A ; Ten
Lb1:
addwf Ones,f
decf Tens,f
btfss 3,0
goto Lb1
Lb2:
addwf Tens,f
decf Hund,f
btfss 3,0
goto Lb2
Lb3:
addwf Hund,f
decf Thou,f
btfss 3,0
goto Lb3
Lb4:
addwf Thou,f
decf TenK,f
btfss 3,0
goto Lb4
retlw 0x00
LCD_Busy
bsf STATUS, RP0 ;set bank 1
movlw 0x0f ;set Port for input
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
bcf LCD_PORT, LCD_RS ;set LCD for command mode
bsf LCD_PORT, LCD_RW ;setup to read busy flag
bsf LCD_PORT, LCD_E
swapf LCD_PORT, w ;read upper nibble (busy flag)
bcf LCD_PORT, LCD_E
movwf templcd2
bsf LCD_PORT, LCD_E ;dummy read of lower nibble
bcf LCD_PORT, LCD_E
btfsc templcd2, 7 ;check busy flag, high = busy
goto LCD_Busy ;if busy check again
bcf LCD_PORT, LCD_RW
bsf STATUS, RP0 ;set bank 1
movlw 0x00 ;set Port for output
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
return
end Last edited by HerbertMunch; 1st October 2007 at 10:28 AM. |
| | |
| | (permalink) |
| Super Moderator | Check my analogue tutorials (Tutorial 11), these use the LCD on PortB of a 16F876/877 - basically you just need to alter the equ at the start. |
| | |
| | (permalink) |
| Experienced Member | Thats what I have done. The code above works fine if its on a0 -a3. For a reason that I cant determin, it refuses to work on b0-b3! I just dont understand it. Ive only changed a few lines, but it doesnt work. |
| | |
| | (permalink) |
| Super Moderator | Well the code above still has the LCD_PORT and LCD_TRIS set to PortA. |
| | |
| | (permalink) |
| Experienced Member | Yes it does. As i stated before, I set the data on both port a and portB. i,e Code: LCD_DATA_PORT Equ PORTB LCD_PORT Equ PORTA LCD_Cmd Led_On LED_YELLOW movwf templcd swapf templcd, w ;swap nibbles around, so we send the high nibble first on a0-a3 andlw 0x0f ;clear LCD handshaking lines movwf LCD_PORT ;set data movwf LCD_DATA_PORT bcf LCD_PORT,LCD_RS ;set up instruction call Pulse_E ;Inform lcd data ready. Send high nibble movf templcd, w ;Select lower nibble andlw 0x0f ;clear LCD handshaking lines movwf LCD_PORT movwf LCD_DATA_PORT bcf LCD_PORT,LCD_RS ;Instruction call Pulse_E ;inform lcd data ready. Send low nibble call Delay100 ;Wait until lcd ready. Led_Off LED_YELLOW retlw 0x00 |
| | |
| | (permalink) | |
| Super Moderator | Quote:
All equates are is a text substitution, just like using 'search and replace' in a word processor. | |
| | |
| | (permalink) |
| Experienced Member | I think I understand what your saying nigel, but if you look at my code youll see that the LCD control lines (R/W, R/S, E) remain unchanged. I leave them alone on port A. The only modification I have made is to also copy the data onto portB as well as A. And for some reason this does not work. Please Ignore any routines with suffix A. These are just old routines. Below is the code with all needless routines removed. Code: LIST p=16F628a ;tell assembler what chip we are using
include "P16F628a.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__cONFIG _CP_OFF &_PWRTE_OFF & _WDT_OFF &_DATA_CP_OFF & _MCLRE_OFF & _INTOSC_OSC_NOCLKOUT &_LVP_OFF
cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
temp
delayCountA
delayCountB
delayCountC
messageCounter
tmp1 ;temporary storage
tmp2
templcd ;temp store for 4 bit mode
templcd2
NumL ;Binary inputs for decimal convert routine
NumH
TenK ;Decimal outputs from convert routine
Thou
Hund
Tens
Ones
endc
LED_PORT Equ PORTB
LCD_DATA_PORT Equ PORTB
LED_TRIS Equ TRISB
LED_GREEN Equ 0x00
LED_YELLOW Equ 0x01
LCD_PORT Equ PORTA
LCD_TRIS Equ TRISA
LCD_RS Equ 0x04 ;LCD handshake lines
LCD_RW Equ 0x06
LCD_E Equ 0x07
org 0x0000
call Delay100
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
goto Initialise
Text addwf PCL, f
retlw ' '
retlw ' '
retlw 'H'
retlw 'e'
retlw 'r'
retlw 'b'
retlw 'e'
retlw 'r'
retlw 't'
retlw 'M'
retlw 'u'
retlw 'n'
retlw 'c'
retlw 'h'
retlw ' '
retlw ' '
retlw 0x00
LCD_Init
call Delay100
movlw 0x28 ;4bit 2 lines 5x7
call LCD_Cmd
movlw 0x0c ;Display On
call LCD_Cmd
movlw 0x06 ;charactor increment on
call LCD_Cmd
call LCD_Clear
call LCD_Line2
retlw 0x00
Initialise clrf count
clrf PORTA
clrf PORTB
clrf messageCounter
SetPorts
BANKSEL LCD_TRIS
CLRF LCD_TRIS ;MAKE ALL PORTS OUTPUTS
CLRF LED_TRIS
Led_On LED_GREEN
call Delay100
call LCD_Init
call Message
movlw 0x02
call LCD_Cmd
goto $
Message
clrf messageCounter
messagego
movf messageCounter, w ;Set charactor index
call Text ;retrieve charactor
xorlw 0x00
btfsc STATUS, Z ;Check if its 0
retlw 0x00
call LCD_Char
incf messageCounter , f
goto messagego
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LCD HD44780 Instructions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Clears the screen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_Clear
movlw 0x01
call LCD_Cmd
retlw 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;LCD CORE ROUTINES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LCD_Cmd
Led_On LED_YELLOW
movwf templcd
swapf templcd, w ;swap nibbles around, so we send the high nibble first on a0-a3
andlw 0x0f ;clear LCD handshaking lines
movwf LCD_PORT ;set data
movwf LCD_DATA_PORT
bcf LCD_PORT,LCD_RS ;set up instruction
call Pulse_E ;Inform lcd data ready. Send high nibble
movf templcd, w ;Select lower nibble
andlw 0x0f ;clear LCD handshaking lines
movwf LCD_PORT
movwf LCD_DATA_PORT
bcf LCD_PORT,LCD_RS ;Instruction
call Pulse_E ;inform lcd data ready. Send low nibble
call Delay100 ;Wait until lcd ready.
Led_Off LED_YELLOW
retlw 0x00
LCD_Char
Led_On LED_YELLOW
movwf templcd ;store charactor
swapf templcd, W ;swap nibbles around, so that we send high nibble first on a0-a3
andlw 0x0f ;clear LCD handshaking lines
movwf LCD_PORT ;set data on pins a0-a3
movwf LCD_DATA_PORT
bsf LCD_PORT, LCD_RS ;setup to write charactor
call Pulse_E ;Inform lcd data ready, send high nibble
movf templcd, W ;Select stored charactor
andlw 0x0F ;Clear lcd handshaking lines, leaving data on a0-a3
movwf LCD_PORT ;set data on pins a0-a3
movwf LCD_DATA_PORT
bsf LCD_PORT, LCD_RS ;setup to write character
call Pulse_E ;send data.
call LCD_Busy
Led_Off LED_YELLOW
retlw 0x00
Pulse_E
bsf LCD_PORT, LCD_E ;make e high
nop
bcf LCD_PORT,LCD_E ;e low, signals data ready
retlw 0x00
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7 ;delay 1mS
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
;This routine downloaded from http://www.piclist.com
Convert: ; Takes number in NumH:NumL
; Returns decimal in
; TenK:Thou:Hund:Tens:Ones
swapf NumH, w
iorlw B'11110000'
movwf Thou
addwf Thou,f
addlw 0XE2
movwf Hund
addlw 0X32
movwf Ones
movf NumH,w
andlw 0X0F
addwf Hund,f
addwf Hund,f
addwf Ones,f
addlw 0XE9
movwf Tens
addwf Tens,f
addwf Tens,f
swapf NumL,w
andlw 0X0F
addwf Tens,f
addwf Ones,f
rlf Tens,f
rlf Ones,f
comf Ones,f
rlf Ones,f
movf NumL,w
andlw 0X0F
addwf Ones,f
rlf Thou,f
movlw 0X07
movwf TenK
; At this point, the original number is
; equal to
; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
; if those entities are regarded as two's
; complement binary. To be precise, all of
; them are negative except TenK. Now the number
; needs to be normalized, but this can all be
; done with simple byte arithmetic.
movlw 0X0A ; Ten
Lb1:
addwf Ones,f
decf Tens,f
btfss 3,0
goto Lb1
Lb2:
addwf Tens,f
decf Hund,f
btfss 3,0
goto Lb2
Lb3:
addwf Hund,f
decf Thou,f
btfss 3,0
goto Lb3
Lb4:
addwf Thou,f
decf TenK,f
btfss 3,0
goto Lb4
retlw 0x00
LCD_Busy
bsf STATUS, RP0 ;set bank 1
movlw 0x0f ;set Port for input
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
bcf LCD_PORT, LCD_RS ;set LCD for command mode
bsf LCD_PORT, LCD_RW ;setup to read busy flag
bsf LCD_PORT, LCD_E
swapf LCD_PORT, w ;read upper nibble (busy flag)
bcf LCD_PORT, LCD_E
movwf templcd2
bsf LCD_PORT, LCD_E ;dummy read of lower nibble
bcf LCD_PORT, LCD_E
btfsc templcd2, 7 ;check busy flag, high = busy
goto LCD_Busy ;if busy check again
bcf LCD_PORT, LCD_RW
bsf STATUS, RP0 ;set bank 1
movlw 0x00 ;set Port for output
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
return
end Last edited by HerbertMunch; 1st October 2007 at 11:46 AM. |
| | |
| | (permalink) |
| Super Moderator | Why would you want to only move part of the LCD to a different port?. The routines were written to use a single port, and (as you've perhaps found out?) may well require modification to work across different ports. |
| | |
| | (permalink) | |
| Experienced Member | Quote:
| |
| | |
| | (permalink) | |
| Experienced Member | Quote:
As far as I can tell, it will require no further modification, as Im still using ports 0-3 for data. Last edited by HerbertMunch; 1st October 2007 at 04:14 PM. | |
| | |
| | (permalink) |
| Experienced Member | hi herbert, Post the full code [yours] and I'll run in thru my simulator. Add any necessary comments
__________________ Eric "Good enough is Perfect" PIC tutorials: Gramo's: www.digital-diy.net/ Bill's: www.blueroomelectronics.com/ |
| | |
| | (permalink) |
| Experienced Member | Ok thanks mate. Ill clean it up, and resubmit. |
| | |
| | (permalink) | |
| Experienced Member | Quote:
Where did you get the original code from,, point me to it.
__________________ Eric "Good enough is Perfect" PIC tutorials: Gramo's: www.digital-diy.net/ Bill's: www.blueroomelectronics.com/ | |
| | |
| | (permalink) |
| Experienced Member | It’s an amalgamation of Nigels LCD tutorials, slightly modified by me. Found Here. Ive taken out the read busy flag code though. When I connect it up to A0-A3, all is well. When I connect it up to B0-B3 it doesnt even initiliase the LCD! I feel like im just bagging my head against a music festival toilette! I just cant work out why this doesnt work. All the pins (B) are functioning properly as outputs. I have pulsed and scoped all of them. Last edited by HerbertMunch; 1st October 2007 at 05:27 PM. |
| | |
| | (permalink) | |
| Super Moderator | Quote:
| |
| | |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Mobile phone LCD panel | flemmard | Electronic Projects Design/Ideas/Reviews | 2 | 3rd November 2007 10:05 PM |
| Newbie needs help with LCD backlight dimming | Mongoose | General Electronics Chat | 6 | 21st September 2007 11:23 PM |
| Nokia 7110 LCD + questions regarding code and behaviour of LCD. | MrNobody | Micro Controllers | 2 | 19th September 2007 07:50 AM |
| Writing 2 Graphics Lcd Using Pic | cyprio7 | General Electronics Chat | 8 | 18th September 2007 02:07 AM |
| LCD Troubles | Kyle-s4h | Micro Controllers | 13 | 11th September 2007 12:30 PM |