Autor Tema: INCONVENIENTE CON LCD 2X16  (Leído 1460 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado asogen

  • PIC10
  • *
  • Mensajes: 15
INCONVENIENTE CON LCD 2X16
« en: 20 de Octubre de 2012, 22:49:28 »
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 > 8)
_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

« Última modificación: 20 de Octubre de 2012, 23:24:12 por asogen »

Desconectado cesaravila1981

  • PIC10
  • *
  • Mensajes: 25
Re: INCONVENIENTE CON LCD 2X16
« Respuesta #1 en: 21 de Octubre de 2012, 00:25:04 »

hola asogen

note entiendo muy bien cual es el problema dices que solo se ven 18 mesnajes o son 18 caracteres o sea letras o lugares del lcd

yo con un lcd que tuve el año pasado en la escuela no se veian los ultimos caracteres y el maestro nos dijo que en algunos lcd el primer renglon sigue horizontalmente muchas posiciones despues antes de pasar al segundo

nose si me explique bien

pon mas detalles tu circuito seria bien verlo pon una imagen

saludos  :P

"El camino no se acaba... continuaré sin descanso."


 

anything