HOLA A TODOS, RESULTA QUE TENGO UN PROGRAMA ASM QUE FUNCIONA CON MACROS EL CUAL CARGA LOS MENSAJES A SER VISUALIZADOS, DENTRO DEL PROGRAMA LLAMO A LOS MENSAJES Y ESTOS SE VISUALIZAN PERO LLEGAN HASTA CIERTA CANTIDAD DE CARACTERES EN TOTAL MAS O MENOS 18 MENSAJES, Y LUEGO NO SE VISUALIZA NADA, SI LE QUITO CARACTERES A LOS MENSAJES PUEDO CREAR MAS MENSAJES, ¿A QUE SE DEBE ESTO? HAY QUE BORRAR ALGUNA MEMORIA DEL LCD O ES PROBLEMA DEL PROGRAMA? GRACIAS POR LA AYUDA..
RKMACROS.INC
NOLIST
;******************************************************************
;
; A set of standard macros.
;
; Ron Kreymborg
;
;******************************************************************
intoff macro
bcf intcon,gie
btfsc intcon,gie
goto $-2
endm
bank0 macro
bcf STATUS,RP0
endm
bank1 macro
bsf STATUS,RP0
endm
dotris macro arg1, arg2
bsf STATUS,RP0
movlw arg1
movwf arg2
bcf STATUS,RP0
endm
dodelay macro arg1
movlw arg1
call delay
endm
LIST
TIMER.INC
; PRESCL and TIMER computation
NOLIST
; Take the processor clock frequency in Hz (clock), and
; the required time delay in uSecs (dusec), and compute
; a value for the prescaler (PRESCL) and another for
; TMR0 (TMRVAL).
_cycle equ clock >> 2
_dfreq equ 1000000 / dusec
_divr equ _cycle / _dfreq
if (_divr < 512)
error "Delay time too short. Assign PSA to WDT."
endif
_test set _divr / 256
_testB equ _divr % 256
if (_testB > 0)
_test set _test + 1
endif
if (_test > 1)
_temp set 2
PRESCL set 0
endif
if (_test > 2)
_temp set 4
PRESCL set 1
endif
if (_test > 4)
_temp set 8
PRESCL set 2
endif
if (_test >
_temp set 16
PRESCL set 3
endif
if (_test > 16)
_temp set 32
PRESCL set 4
endif
if (_test > 32)
_temp set 64
PRESCL set 5
endif
if (_test > 64)
_temp set 128
PRESCL set 6
endif
if (_test > 128)
_temp set 256
PRESCL set 7
endif
if (_test > 255)
error "Timer requirement is outside range"
endif
TMRVAL equ 256 - (_cycle / _temp / _dfreq)
LIST
LCD_TST.ASM
;******************************************************************
;
; Test program for LCD driver.
;
;******************************************************************
title "LCD Driver (lcd.asm) Test"
list p=pic16f84,r=dec,n=80,x=off,st=off
include ‹p16f84.inc›
include ‹rkmacros.inc›
errorlevel -302 ; no bank warnings
clock equ 10000000 ; my crystal frequency
dusec equ 1000 ; required delay is 1 mSec
include ‹timer.inc› ; (note include must be after
; previous two definitions)
; Data -
CBLOCK 0x0C ; start of data area
dval
pntr
offset
ENDC
;****************************************************************
org 0 ; for future expansion
goto start ;
org 4 ;
retfie ;
; All messages and the sendit/gbyt routines must be in the
; first 256 bytes of program memory.
mess1 dt 0x00,"Lat 38",0xdf,"56'42.4",0x22,0
mess2 dt 0x40,"Lng 178",0xdf,"23'19.8",0x22,0
; Send the message in program memory pointed to by W to the LCD.
sendit movwf pntr ; save pointer to data
clrf offset ; clear "next byte" offset
call gbyt ; get the LCD address
iorlw 0x80 ; set as address command
call lcd_c ; send command
snd1 incf offset,f ; step offset to next byte
call gbyt ; get it
iorlw 0 ; terminating null?
btfsc STATUS,Z
return ; yes, done
call lcd_d ; send to LCD data memory
goto snd1 ; around again
gbyt movf pntr,w ; get base address
addwf offset,w ; add offset
movwf PCL ; get char
;****************************************************************
; Main program begins
start clrwdt ; setup 1mSec timer
bsf STATUS,RP0
movlw b'11010000' | PRESCL ; prescaler to TMR0
movwf OPTION_REG
bcf STATUS,RP0
dotris 0,PORTA ; PORTA all outputs for now
clrf PORTA
call lcd_init ; initialise the LCD driver
movlw mess1 ; send first line
call sendit
movlw mess2 ; send second line
call sendit
loop goto loop
; Delay routine using the internal timer. Will delay for W
; times the value of "dusec" in microseconds.
delay movwf dval
dy1 clrf TMR0
bcf INTCON,T0IF
movlw TMRVAL ; set timer
movwf TMR0
dy2 btfss INTCON,T0IF ; timer overflow yet?
goto dy2 ; no
decfsz dval,f ; yes, all cycles?
goto dy1 ; no
return ; yes, delay finished
include ‹lcd.asm›
end
LCD.ASM
;******************************************************************
;
; Routines to display on a 2x16 character LCD display.
;
; LcdInit - call this subroutine before using the display. It uses
; bits 7-1 of PORTB, leaving bit-0 free (although it will
; be configured as an output).
;
; Lcd_C - Sends the byte in W as a command to the display. Checks
; if busy first.
;
; Lcd_D - Sends the byte in W as data. Checks for busy first.
;
; Assumes it can call a routine called "delay" with a required
; time delay in mSecs in W.
; Uses an additional three (3) levels of the stack.
;
; Address of first line on the LCD is 0
; Address of second line is 64
;
; Ron Kreymborg
;******************************************************************
lcd_com macro arg1
movlw arg1
call lcd_c
endm
; Data -
CBLOCK ; lcd data area
lcd_flags
lcd_temp
ENDC
; Flags -
lcd_Bflg equ 0
lcd_RSflg equ 1
; I/O portB -
lcd_BUSY equ 7 ; input - LCD is busy (0x80)
lcd_R_W equ 3 ; output - LCD Read/Write (0x08)
lcd_RS equ 2 ; output - Register Select (0x04)
lcd_E equ 1 ; output - LCD Enable (0x02)
lcd_init
clrf PORTB
dotris b'00000000',PORTB ; all outputs and low to start
bcf lcd_flags,lcd_RSflg
dodelay 15 ; 15mSec power up delay
movlw b'00110000' ; 8-bit mode
movwf PORTB
call lcd_clk
dodelay 4 ; 4mSec wait
movlw b'00110000' ; 8-bit mode
movwf PORTB
call lcd_clk
dodelay 1 ; 1 mSec wait
movlw b'00110000' ; 8-bit mode
movwf PORTB
call lcd_clk
dodelay 4 ; 4mSec wait
movlw b'00100000' ; set for 4-bit
movwf PORTB
call lcd_clk
; Reset sequence is done - initialise for us
lcd_com b'00101000' ; 4-bits, 2-lines, 5x7
lcd_com b'00001000' ; display off, cursor off, blink off
lcd_com b'00001100' ; display on
lcd_com b'00000001' ; clear display
lcd_com b'00000110' ; increment, no display shift
return
; Check whether the LCD is busy. Loop until it isn't. When
; it's free, output the byte passed in W, MS nibble first.
lcd_d bsf lcd_flags,lcd_RSflg ; set RS flag for data
goto lcd_o1
lcd_c bcf lcd_flags,lcd_RSflg ; clear RS flag for commands
lcd_o1 movwf lcd_temp ; save control word
dotris b'11110000',PORTB ; RB7-4 as inputs for busy
movlw 1 << lcd_R_W
movwf PORTB ; set up for read
lcd_o2 bcf lcd_flags,lcd_Bflg ; assume not busy
bsf PORTB,lcd_E ; clock high
nop ; little wait
btfsc PORTB,lcd_BUSY ; busy set?
bsf lcd_flags,lcd_Bflg ; yes
bcf PORTB,lcd_E ; clock low
nop ; little wait
nop
call lcd_clk ; get low bits but ignore (for now)
btfsc lcd_flags,lcd_Bflg ; was it busy?
goto lcd_o2 ; yes
dotris b'00000000',PORTB ; RB7-4 outputs again
movf lcd_temp,w ; get word to send
call lcd_o3 ; send high nibble
swapf lcd_temp,w ; get word again
lcd_o3 andlw 0xf0 ; just high bits (clears all control bits)
movwf PORTB
btfsc lcd_flags,lcd_RSflg ; was lcd_RS set?
bsf PORTB,lcd_RS ; yes
call lcd_clk ; write current nibble
return
lcd_clk bsf PORTB,lcd_E ; pulse E line high
nop
bcf PORTB,lcd_E
return
end