Este es el codigo que encontre ojo que es para un avr , no para un pic ; fijate en la parte donde explica "Function set" en ingles :en el codigo es asi , lo repite 2 veces ; trate de hacer lo mismo con la biblioteca del picbasic pro la PBPPIC14.LIB pero no me resulta.Estoy usando un 16f84 a 4 Mhz , alguna sugerencia?
de todas maneras gracias por contestar.:
ldi temp,0b00101000 ; Function set 4 bit mode, 2 lines 5X7 pixels
rcall COMMAND_DISPLAY ; write to display -first write sets 4 bit
; Second function set added by DC
ldi temp,0b00101000 ; Function set 4 bit mode, 2 lines 5X7 pixels
rcall COMMAND_DISPLAY ; write to display -second write to set N and F
***************Aqui Empieza el programita ************
; Begin assembly souce.;; Character receive and display for Truly MTC-C162DPLY-2N 2 line X 16 char LCD.
; Requires AT90S2313 or equivalent with 4 MHz clock.
;
; Below are the connections to the Truly Display
; Pin Function (connection)
; 1 GND
; 2 VCC (+5V)
; 3 Contrast (0to +5V from wiper of 10 pot)
; 4 RS (Register Select 1=data 0=command)
; 5 R/W (tie to ground for write-only)
; 6 OE (Enable - data clocked on neg transition)
; 7-10 D0 - D3 lower 4 data bits (not used - ground these)
; 11-14 D4-D7 upper 4 data bits (connects to AVR90S2313 PB4 through PB7 respectively).
;
; The AT90S2313 routines to control the display, based on the Hitachi HD44780 were written by
; Richard Hosking (downloaded from
http://members.iinet.net.au/~richardh/avrlcd.htm in June 2003).
; The routines from Richard Hosking are COMMAND_DISPLAY, DATA_DISPLAY, and DisplayInit. The
; only changes to these routines are the addition of a few nop commands and a small modification
; to the "Function set" command discussed below. Thanks to Mr. Hosking"s well-commented code and
; assistance, the code was easily used and modified.
;
; The display is driven in the 4 bit mode. The Truly display uses a Samsung KS0070B controller
; that appears to differ from the Hitachi HD44780 controller in that the Samsung requires an
; additional 4 bit write operation during "Function set" when in 4 bit mode. This was accomplished
; by writing the "Function set" command twice to the controller twice instead of once as in
; Mr. Hosking"s original code. I expect that this would work without modification with the Hitachi
; controller as the second write would be a redundant command for the Hitachi controller.
;
; Note that
;
; Below re the connections for the AT90S2313
; Pin Function (Connection)
; VCC +5V (decoupled)
; GND ground
; XTAL1 Clock (see data sheet)
; XTAL2 Clcok (see data sheet)
; TXD Serial out (RS-232 inverting buffer to remote device - NOT USED)
; RXD Serial in (RS-232 inverting receive buffer)
; PD2-PD6 Unassigned (not connected)
; PB0,PB1 Unassigned (not connected)
; PB2 R/S pin on Truly LCD (Truly module pin 4)
; PB3 OE pin on Truly LCD (Truly module pin 6)
; PB4-PB7 D4-D7 on Truly LCD (Truly module pins 11-14 respectively)
;
; Note that unused I/O pins are pulled up with the weak pull-up (direction bits
; set to inputs, data bits written with a logic "1"
.
;
; Behavior of the receive and display code:
;
; Upon the application of power, communications protocol and code date and revision letter are
; displayed. "9600" Refers to 9600 baud, "1" refers to 1 stop bit being required, and
; "N" refers to no parity bits are expected. The next 7 characters uniquely identify the
; firmware revision level.
;
; Incoming characters are display on the LCD module on the lower of the two lines on the
; display, referred to here as line two. The upper line is referred to as line 1. the first
; 16 characters are displayed and any additional characters are not. Control characters,
; defined as those represented by ASCII values below $1F are not displayed.
;
; Linefeed characters cause the display to wait for the first non-control
; character following the linefeed before copying line 2 to line 1 (scrolling the display),
; clearing line 2 and positioning the cursor at the start of line 2.
;
; The display responds to carriage return characters ($0D)by placing the cursor to the
; fist (leftmost) position of line two.
;
; The display cursor is on.
;
; A note about how this code works:
;
; The display is two lines of 16 characters.
;
; The maximum data rate for allowable operation is 9600 baud with 1 stop bit and no parity.
;
; All display write operations are "open loop" timing. That is to say that delay loops are
; used to assure that display write operations don"t proceed faster than the display can handle.
; Therefore, if the controller"s clock rate is changed, the timing routines will have to be
; modified accordingly. Mr. Hosking has thoughtfully indicated the delay time expected for each
; routine.
;
; Upon coming out of reset, the display is initialized and the data format and firmware revision
; are displayed.
;
; An 8 character circular buffer is used to capture incoming characters and a 16 line buffer
; is is used to store a copy of the line two (lower line) of the display so it can be copied
; to line one during scrolling. The circular buffer is necessary because scrolling of the display
; takes 1.8 character times at 9600 baud, and without the buffer, a character would be lost each
; time display content is scrolled.
;
; Incoming characters cause and interrupt and each character is stored in an 8 character
; circular buffer.
;
; The main loop of the program, named "forever" continuously checks to see if new characters
; have been written to the buffer and processes new characters. Displayable characters,
; defined as those with ASCII codes above $1F, are written to display line 2 and to a 16
; character buffer in RAM. Linefeed and carriage return are the only control characters that
; recognized. Carriage returns cause the line buffer to be erased and its pointer set to the start
; of the buffer. Linefeeds cause a flag to be set, which will cause display scrolling when the first
; displayable character after the linefeed is read from the circular buffer
;
; Display scrolling, in response to the first character read from the circular buffer after a
; linefeed calls the routine "linefeed". Linefeed scrolls the display upward one line, leaving
; line two clear with the cursor positioned at the start of the line. In scrolling the display
; linefeed copies the line buffer, which contains a copy of the contents of line two of the display
; to line one, resets the line buffer by clearing it and setting the pointer to the start, then it
; clears line two and sets the cursor to the start of line two.
;
;
;
;
;
;***********************************************************
; Original AVR LCD routines
; written by
; Richard Hosking
; then slightly modified for Truly MTC-C162DPLY-2N
;***********************************************************
.include "2313def.inc"
.def charcount =r1 ;Number of characters displayed on line being written
.def delay2 =r16 ;Temporary register.
.def temp =r17 ;Temporary register.
.def temp1 =r18
.def outchar =r19; ;Char to send by UART.
.def inchar =r20 ;Char received by UART
.def flagreg =r21 ;Flags
.def charbuf =r22 ;Char read from circular buffer
.def gpcount =r23 ;Genral purpose counter (was YH in earlier version)
; YL ;UART circular buffer write ponter.
; ZL ;UART circultar buffer read pointer
; XL ;16 char line buffer pointer
.equ lbufsiz =10
.equ circbufsiz =64
.equ OE =8 ;Bit 3 port B display enable (also directly addressed).
.equ RS =4 ;Bit 2 in port B display register select (also directly addressed).
.equ cbufbot =$60 ;Bottom of circular UART receive buffer.
.equ cbuftop =$67 ;Top of circular UART receive buffer.
.equ lbufbot =$70 ;Bottom of display line buffer.
.equ lbuftop =$7F ;Top of display line buffer.
;Baudrate Calculation
.equ clock = 4000000 ;clock frequency
.equ baudrate = 9600 ;choose a baud rate
.equ baudconstant = (clock/(16*baudrate))-1
;Flagreg bit assignments
; bit 0 Pending linefeed if high.
; bit 1
; bit 2
; bit 3
; bit 4
; bit 5
; bit 6
; bit 7
;Memory uage:
;Ring buffer from $60 through $67
;Line buffer from $70 to $7F
;******************************
.cseg
.org $00
rjmp start ; Reset
rjmp start
rjmp start
rjmp start
rjmp start
rjmp start
rjmp start
rjmp UartRecInt ;UART interrupt
HelloString: ;TEXT TO BE TYPED ON FIRST LINE WHEN POWER IS APPLIED
.db "9600 1 N 030929A"
.db 00,00
start:
ldi temp,RAMEND ;Init Stack Pointer
out SPL,temp
ldi temp,0b00000011 ;Weak pullups on inputs
out PORTB,temp
ldi temp,0b11111100
out DDRB,temp ;PORTB = all outputs except bits 0,1
ldi temp,0b11111111 ;Weak pullups on inputs
out PORTD,temp
ldi temp,0b00000000 ;PORTD - all inputs
ldi flagreg,$00 ;Set all flags to zero.
ldi temp,$00
mov charcount,temp
rcall ClearLineBuffer ;Initialize line buffer.
rcall DisplayInit
ldi temp,baudconstant
out ubrr,temp ;load baudrate
sbi ucr,txen ;Enable the UART transmitter
sbi ucr,rxen ;Enable the receiver..
rcall sendhello ;write line 1 power-up information
rcall Hometwo ;Position cursor for input on line two.
clr XH ;Clear XH, YH, ZY for processors with 16 bit RAM addressing
clr YH
clr ZH
ldi YL,cbufbot ;Set Y and Z circ buff pointers to bottom.
ldi ZL,cbufbot
sbi UCR,7 ;Emable UART Interrupt.
sei ;Global interrupt flag set (enabled).
forever: ;Waiting for new data from circular buffer
;Get waiting char from circular buffer if there is one.
cp YL,ZL ;Is circular buffer read pointer alredy pointing to latest entry?
breq Buffempty ;If so, there is no new data in the buffer.
ld charbuf,Z+ ;If pointers are not equal, then read next char in buffer.
cpi ZL,cbuftop + 1 ;Advance circular buffer read pointer to next value.
brne NoZeroZL ;If end of buffer, wrap around to start of buffer.
ldi ZL,cbufbot
NoZeroZL:
;Handle the new character as either a cotnrol char or a displaybale char.
;If bufchar is a control char,test for CR and LF
cpi charbuf,$1F ;If not a control char branch to displayable char routine..
brpl ItsDisplayable
cpi charbuf,$0D ;If this is a carriage return character,
brne noCR ;Set cursor to start of bottom line.
ldi XL,lbufbot ;Its a CR so set ponters back to start of line.
ldi temp,$00
mov charcount,temp
rcall hometwo ;Put cursor back in first column of line two.
noCR:
cpi charbuf,$0A ;If its a linfeed char then
brne NotALineFeed ;set linfeed pending flag.
ori flagreg,0b00000001
NotALineFeed:
rjmp Buffdone
ItsDisplayable: ;If not a control char then do line feed if pending then
;write to display and to line buffer.
sbrc flagreg,0 ;If linefeed i spending, then do it
rcall linefeed
cpi XL,lbuftop+1 ;Don"t store if buffer at limit.
breq Xfull
st X+,charbuf
mov temp,charbuf
rcall DATA_DISPLAY
Xfull:
Buffdone:
Buffempty:
rjmp forever
SendHello: ;Send HelloString
rcall Homeone
ldi ZH,high(2*HelloString) ; Load high part of byte address into ZH
ldi ZL,low(2*HelloString) ; Load low part of byte address into ZL
moretosend:
lpm ; Load byte from program memory into r0
tst r0 ; Check if we"ve reached the end of the message
breq finishsendstering ; If so, return
mov temp,r0
rcall DATA_DISPLAY
adiw ZL,1 ; Increment Z registers
rjmp moretosend
finishsendstering:
ret
linefeed: ;Handle a linefeed char
;Clear line 1 (top line), copy line two to line one, clear
;line two, the position the cursor in first column of line two.
push gpcount
rcall hometwo ;Put cursor at start of line 2 so it can be cleared.
ldi gpcount,$10 ;Number of chars in line.
clearmore:
ldi temp,$20 ;Fill line with spaces (erase).
rcall DATA_DISPLAY
dec gpcount
brne clearmore
rcall homeone ;Copy line buffer to line 1, reset XL to bottom.
ldi XL,lbufbot
ldi temp,$00
mov charcount,temp
MoreToCopy:
ld temp,X+
rcall DATA_DISPLAY
cpi XL,lbuftop + 1
brne MoreToCopy
rcall ClearLineBuffer
andi flagreg,$0b11111100 ;Clear linefeed pending and enable flagsb.
rcall hometwo
pop gpcount
ret ;Done
ClearLineBuffer: ;Fill line buffer with spaces, set XL to bottom.
ldi XL,lbufbot
ldi temp,$00
mov charcount,temp
ldi temp,$20
MoreToSpace:
st X+,temp
cpi XL,lbuftop + 1
brne MoreToSpace
ldi XL,lbufbot
ret
recchar:
sbis usr,rxc ;Wait for a char.
rjmp recchar
in inchar,udr ;Read the char.
ret
emitchar:
sbis usr,udre ;wait until the register is cleared
rjmp emitchar
out udr,outchar ;send the byte
ret ;go back
HomeOne: ;Home cursor to start of first top line of display.
ldi temp,$80
rcall COMMAND_DISPLAY
ret
HomeTwo: ;Home cursor to start of bottom line of display
ldi temp,$C0
rcall COMMAND_DISPLAY
ret
;************************************************
;
; Write command to display
; command word in temp
; built in 50 usec delay
; by Richard Hosking
;************************************************
COMMAND_DISPLAY:
mov temp1,temp ;Copy data to temp1
andi temp,0b11110000 ;mask off lower 4 bits, make OE and RS low
sbr temp,OE ;OE bit high
out PORTB,temp ;write upper 4 bits to display
nop ;wait 1 usec total command
nop ; Stabilize line
nop ;Added by DC to bring up to 1 us for 4 mHz clock
nop ;Added by DC to bring up to 1 us for 4 mHz clock
cbi PORTB,3 ;OE low to clock in data
swap temp1 ;get lower 4 bits
andi temp1,0b11110000 ; mask off lower 4 bits, make OE and RS low
sbr temp1,OE ;OE high
out PORTB,temp1 ;write lower 4 bits to LCD ;
nop ;
nop
nop ;Added by DC to bring up to 1 us for 4 mHz clock
nop ;Added by DC to bring up to 1 us for 4 mHz clock ;
cbi PORTB,3 ;OE low to clock in data
ldi temp,100 ;Wait about 50 usec
D4:
dec temp
brne D4
ret ; return
;
;******************************************************
;
; Writes data to display
; incorporates 50 usec delay
; data in temp
; by Richard Hosking
;********************************************************
DATA_DISPLAY:
mov temp1,temp ; Copy data to temp1
andi temp,0b11110000 ; mask off lower 4 bits
sbr temp,OE ; OE bit high
sbr temp,RS ; data/command bit high
out PORTB,temp ; write upper 4 bits to display
nop ; wait 1 usec total command
nop ; Stabilize line
cbi PORTB,3 ; OE low to clock in data
;
swap temp1 ; get lower 4 bits
andi temp1,0b11110000 ; mask off lower 4 bits
sbr temp1,OE ; OE high
sbr temp1,RS
out PORTB,temp1 ; write lower 4 bits to LCD ;
nop ;
nop ;
cbi PORTB,3 ; OE low to clock in data
;
ldi temp,100 ; Wait about 50 usec
; ldi temp,200 ; Wait about 50 usec
D5 :
dec temp
brne D5
;
ret ; return
;*********************************************************************
; Delay 2 msec with a 4MHz clock
;*********************************************************************
WAIT_2msec:
ldi temp1,$0B
D24002:
ldi Delay2,$FF
D24001: dec Delay2
brne D24001
dec temp1
brne D24002
ret
;*************************************************************************
; Display setup
; Port B bit 3 OE Enable - clocks on neg transition
; 2 RS Register Select
; command=0, data=1
; bits 4-7 data 4 bits, high nibble first
; ASCII format
; RW grounded (write)
; Note that some commands take up to 1.6 msec for display to implement
; at a nominal display clock rate of 250 KHz
; Display initialize routine after power up
; by Richard Hosking
;************************************************************************
;
DisplayInit: ;Initialize Display
ldi temp,50 ;Wait at least 15msec after
D1: ;powerup before writing
rcall WAIT_2msec ;to display
dec temp
brne D1
ldi temp,0b00111000 ;System set
out PORTB,temp
nop
nop ;Data write cycle must be >1000usec
cbi PORTB,3 ;OE low to clock in data
;
rcall WAIT_2msec ;Wait 4 msec
rcall WAIT_2msec
;
ldi temp,0b00111000 ;System set
out PORTB,temp
nop
nop ; Data write cycle must be >1000usec
cbi PORTB,3 ; OE low to clock in data
;
rcall WAIT_2msec ; wait at least 100usec
;
ldi temp,0b00111000 ;System set
out PORTB,temp
nop ;
nop ;
cbi PORTB,3 ; OE low to clock in data
rcall WAIT_2msec ; Wait at least 40usec (2 msec)
ldi temp,0b00101000 ; Function set 4 bit mode, 2 lines 5X7 pixels
rcall COMMAND_DISPLAY ; write to display -first write sets 4 bit
; Second function set added by DC
ldi temp,0b00101000 ; Function set 4 bit mode, 2 lines 5X7 pixels
rcall COMMAND_DISPLAY ; write to display -second write to set N and F
ldi temp,0b00001000 ;Display off, cursor off
; blink off
rcall COMMAND_DISPLAY
;
ldi temp,0b00000001 ; Display clear
rcall COMMAND_DISPLAY
rcall WAIT_2msec ; Need to wait 1.6 msec after clear
;
ldi temp,0b00000110 ; Entry mode set
; Increment RAM, dont shift display
rcall COMMAND_DISPLAY
;
ldi temp,0b00001110 ; Display on, cursor on ,blink off
rcall COMMAND_DISPLAY
;
rcall WAIT_2msec ; Need to wait 1.6 msec after clear
ret
UartRecInt: ;Uart interrupt service -Write received char into a circular buffer
push temp
rcall recchar ;Get the char from the UART.
st Y+,inchar
cpi YL,cbuftop + 1
brne NoZeroYL
ldi YL,cbufbot
NoZeroYL:
pop temp
reti