include <p16f877.inc>
list p=16f877
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _CP_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _WRT_ON
;*****************************************************
;Declaracion de variables y constantes
;*****************************************************
#define lcd PORTD ;puerto d para el el lcd
#define rs PORTC,0 ;
#define en PORTC,1 ;
cargar_timer equ .178
;****************************
;Para la rutina de divicion
;****************************
TRUE equ 1 ;
FALSE equ 0 ;
SIGNED equ FALSE ;divicion sin signo
;****************************
udata 0x20
cont_timer res 1
;****************************
;Para la rutina de divicion
;****************************
ACCaLO res 1
ACCaHI res 1
ACCbLO res 1
ACCbHI res 1
ACCcLO res 1
ACCcHI res 1
ACCdLO res 1
ACCdHI res 1
temp res 1
sign res 1
;*****************************************************
n1 res 1
W_TEMP res 1
STATUS_TEMP res 1
PCLATH_TEMP res 1
;***************************************************
;Para la rutina de convercion bin16 a BCD
;***************************************************
count res 1
;temp res 1
H_byte res 1
L_byte res 1
R0 res 1
R1 res 1
R2 res 1
;***************************************************
PDel0 res 1 ;para el terardo de 10ms
PDel1 res 1 ;
n_lcd res 1 ;contador de caracteres para el LCD
org 0x00
goto inicio
org 0x04
;**********************************************
;Bloque de interrupciones
;**********************************************
interrupciones
push
MOVWF W_TEMP
SWAPF STATUS,W
CLRF STATUS
MOVWF STATUS_TEMP
MOVF PCLATH,W
MOVWF PCLATH_TEMP
CLRF PCLATH
btfsc INTCON,INTF
goto interrupcion_externa
btfss INTCON,TMR0IF
goto salida_de_interrupcion
;************************************************
interrupcion_temporizada
bcf INTCON,TMR0IF
btfss PORTB,1
goto i0
banksel OPTION_REG ;bank 1
bsf OPTION_REG,T0CS ;timer0 stop
banksel PORTB ;bank 0
bcf PORTB,1
i0
decfsz n1,F
goto siguiente_carga
bsf PORTB,1
siguiente_carga
movlw cargar_timer
movwf TMR0
goto salida_de_interrupcion
;************************************************
interrupcion_externa
movlw cargar_timer+.12
movwf TMR0
banksel OPTION_REG ;bank1
btfss OPTION_REG,INTEDG
goto config_flanco_subida
config_fanco_bajada
bcf OPTION_REG,INTEDG
goto $+2
config_flanco_subida
bsf OPTION_REG,INTEDG
bcf OPTION_REG,T0CS ;timer0 run
banksel INTCON ;bank0
bcf INTCON,INTF
movfw cont_timer
movwf n1
salida_de_interrupcion
pop
MOVF PCLATH_TEMP, W
MOVWF PCLATH
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
retfie
;*********************************************
inicio
;*********************************************
;Cionfiguracion de las interrupciones
;*********************************************
movlw b'10110000'
movwf INTCON
;*********************************************
;configuracion de puertos de entrada y salida
;*********************************************
clrf PORTB
banksel TRISB ;bank 1
movlw b'11111101'
clrf TRISD
bcf TRISC,0
bcf TRISC,1
movwf TRISB
;*********************************************
;Configuracion del ADC
;*********************************************
banksel ADCON0 ;bank 0
movlw b'11000001'
movwf ADCON0
banksel ADCON1 ;bank 1
movlw b'11001110'
movwf ADCON1
;*********************************************
banksel ADCON0 ;bank 0
call limpiar_lcd
call c_der_quieto
call si_visual_no_cur_no_parpadeo
call cursor_home
call esc_mensaje
call desp_cur_iz
call desp_cur_iz
call desp_cur_iz
loop
bsf ADCON0,GO
btfsc ADCON0,GO
goto $-1
movfw ADRESH
movwf ACCbHI
banksel ADRESL ;bank 1
movfw ADRESL
banksel PORTA ;bank 0
movwf ACCbLO
clrf ACCaHI
movlw 0x0a
movwf ACCaLO
call D_divS
movfw ACCbLO
movwf cont_timer
movwf L_byte
clrf H_byte
call B2_BCD
call desp_cur_iz
call desp_cur_iz
call desp_cur_iz
swapf R2,W
andlw 0x0f
iorlw 0x30
call escribir
call desp_cur_der
movfw R2
andlw 0x0f
iorlw 0x30
call escribir
goto loop
;*******************************************
;Subrutinas
;*******************************************
;subrutina de divicion
;*******************************************************************
;SIGNED equ FALSE Set This To 'TRUE' if the routines
; ; for Multiplication & Division needs
; ; to be assembled as Signed Integer
; ; Routines. If 'FALSE' the above two
; ; routines ( D_mpy & D_div ) use
; ; unsigned arithmetic.
;*******************************************************************
; Double Precision Divide ( 16/16 -> 16 )
; ( ACCb/ACCa -> ACCb with remainder in ACCc ) : 16 bit output
; with Quotiont in ACCb (ACCbHI,ACCbLO) and Remainder in ACCc (ACCcHI,ACCcLO).
; NOTE : Before calling this routine, the user should make sure that
; the Numerator(ACCb) is greater than Denominator(ACCa). If
; the case is not true, the user should scale either Numerator
; or Denominator or both such that Numerator is greater than
; the Denominator.
;********************************************************************
D_divS
IF SIGNED
CALL S_SIGN
ENDIF
call setup
clrf ACCcHI
clrf ACCcLO
dloop
bcf STATUS,C
rlf ACCdLO, F
rlf ACCdHI, F
rlf ACCcLO, F
rlf ACCcHI, F
movf ACCaHI,W
subwf ACCcHI,W ;check if a>c
btfss STATUS,Z
goto nochk
movf ACCaLO,W
subwf ACCcLO,W ;if msb equal then check lsb
nochk
btfss STATUS,C ;carry set if c>a
goto nogo
movf ACCaLO,W ;c-a into c
subwf ACCcLO, F
btfss STATUS,C
decf ACCcHI, F
movf ACCaHI,W
subwf ACCcHI, F
bsf STATUS,C ;shift a 1 into b (result)
nogo
rlf ACCbLO, F
rlf ACCbHI, F
decfsz temp, F ;loop untill all bits checked
goto dloop
IF SIGNED
btfss sign,MSB ; check sign if negative
retlw 0
goto neg_B ; negate ACCa ( -ACCa -> ACCa )
ELSE
retlw 0
ENDIF
;*******************************************************************
setup
movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI,W ;move ACCb to ACCd
movwf ACCdHI
movf ACCbLO,W
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
retlw 0
;*******************************************************************
neg_A
comf ACCaLO, F ; negate ACCa ( -ACCa -> ACCa )
incf ACCaLO, F
btfsc STATUS,Z
decf ACCaHI, F
comf ACCaHI, F
retlw 0
;*******************************************************************
; Assemble this section only if Signed Arithmetic Needed
IF SIGNED
S_SIGN
movf ACCaHI,W
xorwf ACCbHI,W
movwf sign
btfss ACCbHI,MSB ; if MSB set go & negate ACCb
goto chek_A
comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc STATUS,Z
decf ACCbHI
comf ACCbHI
chek_A
btfss ACCaHI,MSB ; if MSB set go & negate ACCa
retlw 0
goto neg_A
ENDIF
;********************************************************************
; Binary To BCD Conversion Routine
; This routine converts a 16 Bit binary Number to a 5 Digit
; BCD Number. This routine is useful since PIC16C55 & PIC16C57
; have two 8 bit ports and one 4 bit port ( total of 5 BCD digits)
; The 16 bit binary number is input in locations H_byte and
; L_byte with the high byte in H_byte.
; The 5 digit BCD number is returned in R0, R1 and R2 with R0
; containing the MSD in its right most nibble.
;*******************************************************************;
B2_BCD
bcf STATUS,0 ; clear the carry bit
movlw .16
movwf count
clrf R0
clrf R1
clrf R2
loop16
rlf L_byte, F
rlf H_byte, F
rlf R2, F
rlf R1, F
rlf R0, F
decfsz count, F
goto adjDEC
RETLW 0
adjDEC
movlw R2
movwf FSR
call adjBCD
movlw R1
movwf FSR
call adjBCD
movlw R0
movwf FSR
call adjBCD
goto loop16
adjBCD
movlw 3
addwf 0,W
movwf temp
btfsc temp,3 ; test if result > 7
movwf 0
movlw 30
addwf 0,W
movwf temp
btfsc temp,7 ; test if result > 7
movwf 0 ; save as MSD
RETLW 0
;**************************************************************
; Libreria de subrutinas para el manejo de LCD alfanumerico
;**************************************************************
; Retardo de 10ms para el LCD (Frec xtal=4MHz)
;Se deben configurar manualmente los puertos para que seran
;utilizados para el LCD
;**************************************************************
;cblock
;PDel0
;PDel1
;endc
;#define lcd PORTB
;#define rs PORTA,3
;#define en PORTA,0
;*******************************************************
retardo movlw .15 ;.8
movwf PDel0
PLoop1 movlw .249
movwf PDel1
PLoop2 clrwdt
clrwdt
decfsz PDel1, 1
goto PLoop2
decfsz PDel0, 1
goto PLoop1
PDelL1 goto PDelL2
PDelL2 clrwdt
return
;*******************************************************************
; Habilita el regisyro de control del LCD
;*******************************************************************
comando
bcf rs
movwf lcd
bsf en
nop
nop
bcf en
call retardo
return
;*******************************************************************
; Habilita el registro de datos del LCD requiere dato en w
;*******************************************************************
escribir
bsf rs
movwf lcd
bsf en
nop
nop
bcf en
call retardo
return
;*******************************************************************
; Comandos para el LCD
;*******************************************************************
limpiar_lcd
movlw b'00000001'
call comando
return
;*******************************************************************
cursor_home
movlw b'00000010'
call comando
return
;*******************************************************************
; Modo de funcionamiento
;*******************************************************************
; desplazamiento de cursor a la izquierda, lcd permanese quieto
;*******************************************************************
c_iz_quieto
movlw b'00000100'
call comando
return
;********************************************************************
; desplazamiento de cursor a la izquierda, lcd se desplaza
;********************************************************************
c_iz_desplaza
movlw b'00000101'
call comando
return
;********************************************************************
; desplazamiento de cursor a la derecha, lcd permanese quieto
;********************************************************************
c_der_quieto
movlw b'00000110'
call comando
return
;********************************************************************
; desplazamiento de cursor a la derecha, lcd permanese quieto
;********************************************************************
c_der_desplaza
movlw b'00000111'
call comando
return
;********************************************************************
; Comtrol ON/OFF
;********************************************************************
;No se visualiza datos, el cursor no se ve, cursor no parpadea
;********************************************************************
no_visual_no_cur_no_parpadeo
movlw b'00001000'
call comando
return
;********************************************************************
;No se visualiza datos, el cursor no se ve, cursor parpadea
;********************************************************************
no_visual_no_cur_si_parpadeo
movlw b'00001001'
call comando
return
;********************************************************************
;No se visualiza datos, el cursor se ve, cursor no parpadea
;********************************************************************
no_visual_si_cur_no_parpadeo
movlw b'00001010'
call comando
return
;********************************************************************
;No se visualiza datos, el cursor se ve, cursor parpadea
;********************************************************************
no_visual_si_cur_si_parpadeo
movlw b'00001011'
call comando
return
;********************************************************************
; Se visualiza datos, el cursor no se ve, cursor no parpadea
;********************************************************************
si_visual_no_cur_no_parpadeo
movlw b'00001100'
call comando
return
;********************************************************************
; Se visualiza datos, el cursor no se ve, cursor parpadea
;********************************************************************
si_visual_no_cur_si_parpadeo
movlw b'00001101'
call comando
return
;********************************************************************
;Se visualiza datos, el cursor se ve, cursor no parpadea
;********************************************************************
si_visual_si_cur_no_parpadeo
movlw b'00001110'
call comando
return
;********************************************************************
;Se visualiza datos, el cursor se ve, cursor parpadea
;********************************************************************
si_visual_si_cur_si_parpadeo
movlw b'00001111'
call comando
return
;********************************************************************
; Desplazamienro de cursor/LCD
;********************************************************************
; Se desplaza el cursor a la izquierda
;********************************************************************
desp_cur_iz
movlw b'00010000'
call comando
return
;********************************************************************
; Se desplaza el cursor a la derecha
;********************************************************************
desp_cur_der
movlw b'00010100'
call comando
return
;********************************************************************
; Se desplaza el LCD a la izquierda
;********************************************************************
desp_lcd_iz
movlw b'00011000'
call comando
return
;********************************************************************
; Se desplaza el LCD a la derecha
;********************************************************************
desp_lcd_der
movlw b'00011100'
call comando
return
;********************************************************************
; Transferencia de Informacion
;********************************************************************
; Bus en modo de 4 y 8 bits
;********************************************************************
bus_4_bits
movlw b'00101000'
call comando
return
;********************************************************************
bus_8_bits
movlw b'00111000'
call comando
return
;*********************************************************************
;Acceso a la CGRam(cargar en w la direccion,64 direciones,8 caracteres)
;*********************************************************************
cg_ram
iorlw b'01000000'
call comando
return
;*********************************************************************
; Acceso a la DDRam(cargar en w la direccion, 40 caracteres por linea)
;*********************************************************************
dd_ram_linea_1
iorlw b'10000000'
call comando
return
;*********************************************************************
dd_ram_linea_2
iorlw b'11000000'
call comando
return
;********************************************************************
; Escribir un mensage el el LCD
;********************************************************************
;cblock
;n_lcd ;contador de caracteres
;endc
;***********************************************************************
esc_mensaje
clrf n_lcd
incf PCLATH
lcd_0
movfw n_lcd
call men_0
xorlw 0
btfsc STATUS,Z
goto lcd_1
call escribir
incf n_lcd
goto lcd_0
lcd_1
return
;***************************************************
men_0
addwf PCL,F
dt "Disparo a: . ms.",0
;***************************************************
end