TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Mi en 21 de Junio de 2008, 07:22:38
-
hola!
estoy haciendo un proyecto, tengo que controlar dos persianas (simuladas por leds). cada boton del teclado hace una funcion diferente (un boton sube una, otro la baja, otro activa el sensor de luz,fotoresistencia). Mi problema es que no se hacer un menu con el teclado para ello. Soy nuevo en este tema, he programado en alto nivel pero en asembler no se y no se como hacer una menu para que si pulsa un boton vaya a una funcion, si pulsa otro, haga otra. Agradeceria cualquier ayuda. Gracias
-
Saludos Mi!
Te recomiendo que uses el buscador del foro en la sección "Almacén del Assembler"... allí encontrarás mucha información que de seguro te será útil.
En cuanto a esto:
no se como hacer una menu para que si pulsa un boton vaya a una funcion, si pulsa otro, haga otra.
Es algo relativamente fácil de hacer (digo "relativamente" porque cuando uno empieza no parece tan fácil, pero una vez que lo entiendas no se te hará difícil) , puedes usar las interrupciones por cambio de estado en portb (aunque no especificas que pic usas, supongo que tu pic posee esa característica)...
Ok saludos, nos leemos! :mrgreen:
-
De seguras programas en otro lenguaje. Lo puedes hacer en lenguaje C.
-
Es verdad Mi, si sabes programar en otros lenguajes, pues te caería muy bien el C o yo diría que hasta el basic...
Por ejemplo el mikroBasic está de lujo! ya soporta punto flotante! :P
También esta el niple que es como decir visual basic para microcontroladores... aunque yo no lo he probado y por eso no te puedo dar una opinión con buen fundamento.
Ok luego nos cuentas qué lenguaje has elegido y cómo vas con tu proyecto.
Saludos, nos leemos! :mrgreen:
-
te aconcejo que programes en BASIC de PROTON es muy facil ...
igual y qui te pongo una url de un manual completo de Assembler:
http://perso.wanadoo.es/pictob/tecprg.htm
-
hola, es un trabajo que me han mandado y hay que hacer en ensamblador, si pudiera usar C lo haria porque he utilizado mas que esto.
el pic que uso es 16f874, creo que todo el codigo esta bien pero al cargar a la placa no funciona, no tengo ni idea que puede ser, no me da errores.tal vez pueda estar en la rutina de asociar cada tecla a una funcion pero no lo se. Agradeceria que me hechaseis un vistazo al codigo y me podais decir algo.Muchas gracias
El codigo:
;EJERCICIO persianas
;*******************************
LIST P=16F874
INCLUDE "P16F874.INC"
;************************************************************************
; Variables
TMP1 EQU 27h
TMP2 EQU 28h
PULS EQU 29
; Constantes de tiempo
klcdw EQU 0FFh
; Registros del micro
W EQU 0
F EQU 1
STATUS EQU 03h
PORTA EQU 05h
INTCON EQU 0Bh
PORTD EQU 08h
;**************************************************
;*************ASIGNACION DE PUERTOS DE LEDS**********
P_LED EQU PORTA
b_LED0 EQU 0
b_LED1 EQU 0
;***********************************************
;***********VARIABLES DEL CONVERSOR******
CAD0 EQU 2A
CAD1 EQU 2B
;***********************************************
;PUERTOS LCD
P_LCDen EQU PORTD
b_LCDen EQU 4
P_LCDrw EQU PORTD
b_LCDrw EQU 5
P_LCDdi EQU PORTD
b_LCDdi EQU 6
P_LCDDA EQU PORTD
;*********************************************
;CONFIGURACION LCD
lcd_set EQU b'00100000'
lcd_mod EQU b'00000110'
lcd_on EQU b'00001100'
lcd_off EQU b'00001000'
lcd_to EQU d'200'
;**********************************************
;Comandos LCD
lcd_clr EQU b'00000001'
cur_hm EQU b'00000010'
cur_on EQU b'00001010'
cur_off EQU b'00001000'
cur_rm EQU b'00010100'
cur_lm EQU b'00010000'
cur_12 EQU b'11000000'
;**********************************************
SAVEPCL EQU 20
SAVEFSR EQU 21
SAVEST EQU 22
SAVEW EQU 23
;*************************************
;puerto del teclado
PKYBD EQU PORTB
bKYBD EQU 0
;**************************************
;variables del teclado
TEC_numv EQU 24
TEC_ant EQU 25
TEC_flg EQU 26
F_rep EQU 0
;****************************************
;constantes del teclado
self1 EQU B'00000111'
self2 EQU B'00001011'
self3 EQU B'00001101'
self4 EQU B'00001110'
selfa EQU B'00000000'
nminv EQU 10
;***********************************************
ORG 003
GOTO PROGPPAL ;salto al programa principal
;*************************************************
;****************************************************
PROGPPAL
CALL KYBINIT
;*************************Inicializar teclado*********
BSF STATUS,RP0 ;Pone a "1" el bit RP0(el bit 5) del registro STATUS
MOVLW B'00000111' ;Mueve al acumulador "W" el literal 07h
MOVWF ADCON1&7F ;Mueve el contenido del acumulador a ADCON1 haciendo un AND de 7F
BCF P_LED,b_LED0 ;Pone a "0" el bit b_LED al registro P_LED
BCF P_LED,b_LED1
CALL LCDINIT ; Inicializar el LCD
CALL LCDDOUT ; Pone LCD como entrada
BCF STATUS,RP0 ;Pone a "0" el bit RP0 del registro STATUS
;**************************
; BSF INTCON,GIE
MOVLW cur_hm ; Cursor a home
CALL LCDIWR ; Se manda a la pantalla
MOVLW B'00001111' ; Enceder cursor
CALL LCDIWR ; Se manda a la pantalla
MOVLW B'00000110' ; Auto mover cursor a la derecha
CALL LCDIWR ; Se manda a la pantalla
LAZOPPAL:
CALL MENS
GOTO LAZOPPAL
;**********************************************
; LCDINIT
; Inicializa pantalla y puerto de pantalla
LCDINIT:
BSF STATUS, RP0 ; Se reconfigura puerto de datos LCD
MOVLW 0F0h ; 4 bits de datos = Salida
ANDWF P_LCDDA,F ;
BCF P_LCDdi,b_LCDdi ; Dato/instrucción = Salida
BCF P_LCDrw,b_LCDrw ; Read/Write = Salida
BCF P_LCDen,b_LCDen ; Strobe = Salida
BCF STATUS, RP0 ;
BCF P_LCDdi,b_LCDdi ; Dato/instrucción = Instrucción
BCF P_LCDrw,b_LCDrw ; Read/Write = Write
BCF P_LCDen,b_LCDen ; desactiva el strobe
MOVLW 0F0h ; Se prepara primer dato de inicialización de 4 bits
ANDWF P_LCDDA,F ; (que hay que enviar 3 veces)
MOVLW B'0011' ;
IORWF P_LCDDA,F ;
MOVLW D'20' ; Se esperan 20ms
CALL LCDWAIT ;
BSF P_LCDen,b_LCDen ; Primer envio
BCF P_LCDen,b_LCDen ; activa strobe / desactivar strobe
MOVLW D'5' ; Se esperan 5ms
CALL LCDWAIT ;
BSF P_LCDen,b_LCDen ; Primer envio
BCF P_LCDen,b_LCDen ; activa strobe / desactivar strobe
MOVLW D'1' ; Se esperan 1ms
CALL LCDWAIT ;
BSF P_LCDen,b_LCDen ; Primer envio
BCF P_LCDen,b_LCDen ; activa strobe / desactivar strobe
MOVLW D'5' ; Se esperan 5ms
CALL LCDWAIT ;
MOVLW 0F0h ; Se prepara segundo dato de inicialización de 4 bits
ANDWF P_LCDDA,F ;
MOVLW B'0010' ;
IORWF P_LCDDA,F ;
BSF P_LCDen,b_LCDen ; Envio
BCF P_LCDen,b_LCDen ; activar strobe / desactivar strobe
MOVLW D'5' ; Se esperan 5ms
CALL LCDWAIT ;
MOVLW lcd_set ; Se envia instrucción ara fijar tipo de pantalla
CALL LCDIWR ;
MOVLW D'5' ; Se esperan 5ms
CALL LCDWAIT ;
MOVLW lcd_off ; Se envia instrucción para apagar pantalla
CALL LCDIWR ;
MOVLW lcd_on ; Se envia instrucción para encender pantalla
CALL LCDIWR ;
MOVLW lcd_mod ; Se envia instrucción para forma de operar pantalla
CALL LCDIWR ;
MOVLW lcd_clr ; Se envia instrucción para limpiar pantalla
CALL LCDIWR ;
MOVLW D'100' ; Se esperan 100ms
CALL LCDWAIT ;
RETURN
;***********************************************
; LCDDWR
; LCD Data write
; Recibe: W=Dato a escribir
LCDDWR:
BSF P_LCDdi,b_LCDdi ; Dato/instrucción = Dato
GOTO LCDWRAUX ;
;***********************************************
; LCDIW
; LCD Instruction write
; Recibe: W=Dato a escribir
LCDIWR:
BCF P_LCDdi,b_LCDdi ; Dato/instrucción = instrucción
GOTO LCDWRAUX ;
LCDWRAUX:
BCF P_LCDrw,b_LCDrw ; Read/Write = Write
MOVWF TMP1 ; Se guarda dato para posterior uso
MOVLW 0F0h ; Se borran bits lsb del puerto
ANDWF P_LCDDA,F ;
SWAPF TMP1,W ; Se escribe el nible superior
ANDLW 00Fh ;
IORWF P_LCDDA,F ;
BSF P_LCDen,b_LCDen ; activa el strobe
BCF P_LCDen,b_LCDen ; desactiva el strobe
MOVLW 0F0h ; Se borran bits lsb del puerto
ANDWF P_LCDDA,F ;
MOVF TMP1,W ; Se escribe nible inferior
ANDLW 00Fh ;
IORWF P_LCDDA,F ;
BSF P_LCDen,b_LCDen ; activa el strobe
BCF P_LCDen,b_LCDen ; desactiva el strobe
CALL LCDBSY ;
RETURN ;
;***********************************************
; LCDWAIT
; Recibe: W=Número de milisegundos a esperar
LCDWAIT:
MOVWF TMP1 ; Se almacena el número de milisegundos en CONT1
LCDW1:
MOVLW klcdw ; Se almacena contador básico
MOVWF TMP2 ;
LCDW2:
NOP ; Ajustando al milisegundo
NOP ;
DECFSZ TMP2,F ; Se decrementa contador básico
GOTO LCDW2 ; hasta llegar a cero
DECFSZ TMP1,F ; Se repite el contador básico tantas
GOTO LCDW1 ; veces como número de milisegundos
RETURN ;
;************************************************
; LCDBSY
; LCD Busy: espera desocupación de LCD (con time-out)
; Retorna: W=0 desocupado / W=1 error time-out superado
LCDBSY:
MOVLW lcd_to ; Se prepara contador de time-out
MOVWF TMP1 ;
CALL LCDDIN ; Se pone el bus como entrada
BCF P_LCDdi,b_LCDdi ; Dato/instrucción = Instrucción
BSF P_LCDrw,b_LCDrw ; Read/Write = Read
LCDBS1:
BSF P_LCDen,b_LCDen ; activar strobe / desactivar strobe
BCF P_LCDen,b_LCDen ;
MOVF P_LCDDA,W ; Se lee nibble MSN con busy flag BF
BSF P_LCDen,b_LCDen ; acivar strobe / desactivar strobe
BCF P_LCDen,b_LCDen ;
ANDLW 08h ;
BTFSS STATUS,Z ; Si BF=0 el LCD esta desocupado
GOTO LCDBS2 ;
DECFSZ TMP1,F ; Se verifica si hay time-out
GOTO LCDBS1 ;
CLRF TMP1 ; Hay time-out
CALL LCDDOUT ;
RETLW 01 ; Retorna error por time-out
LCDBS2: ; Desocupado
CALL LCDDOUT ;
RETLW 00 ; Retorna desocupado sin errores
;******************************************************
; CURADD
; Lee dirección del cursor
; Retorna: W=dirección del cursor (0-79d)
CURADD:
CALL LCDDIN ; Se rconfigura puerto de datos LCD como entrada
BCF P_LCDdi,b_LCDdi ; Dato/instrucción = Instruccion
BSF P_LCDrw,b_LCDrw ; Read/Write = Write
BSF P_LCDen,b_LCDen ; activar strobe / desactivar strobe
BCF P_LCDen,b_LCDen ;
MOVF P_LCDDA,W ; Se lee nibble MSN
ANDLW 07h ;
MOVWF TMP1 ;
SWAPF TMP1,F ;
BSF P_LCDen,b_LCDen ; activar strobe / desactivar strobe
BCF P_LCDen,b_LCDen ;
MOVF P_LCDDA,W ; Se lee nibble MSN
ANDLW 0Fh ;
IORWF TMP1,W ;
CALL LCDDOUT ;
RETURN ;
;*********************************************************
; LCDIN
; Rutina de uso particular. Pone el bus de datos LCD como entrada
LCDDIN: ;
BSF STATUS, RP0 ; Se reconfigura puerto de datos LCD
MOVLW 00Fh ; como entrada
IORWF P_LCDDA,W ;
MOVWF P_LCDDA ;
BCF STATUS, RP0 ;
RETURN ;
;*********************************************************
; LCDOUT
; Rutina de uso particular. Pone el bus de datos LCD como salida
LCDDOUT: ;
BSF STATUS, RP0 ; Se reconfigura puerto de datos LCD
MOVLW 0F0h ; como salida
ANDWF P_LCDDA,W ;
MOVWF P_LCDDA ;
BCF STATUS, RP0 ;
MOVF TMP1,W ;
RETURN ;
;****************************************
INITTMR0:
BSF STATUS,RP0
MOVLW B'00000111'
MOVWF ADCON1&7F
BCF PKYBD,bKYBD
BCF STATUS,RP0
RETURN
;******************************
ORG 100
TRATECLA:
CLRF PCLATH
BSF PCLATH,0
BCF PCLATH,1
ADDWF PCL,F
RETLW 0
RETLW '1'
RETLW '2'
RETLW '3'
RETLW '4'
RETLW '5'
RETLW '6'
RETLW '7'
RETLW '8'
RETLW '9'
RETLW 'D'
RETLW 'A'
RETLW '0'
RETLW 'B'
RETLW 'C'
KYBINIT:
BSF STATUS,RP0
MOVLW B'11110000'
MOVWF PKYBD
BCF OPTION_REG&7F,NOT_RBPU
BCF STATUS,RP0
MOVLW selfa
MOVWF PKYBD
CLRF TEC_ant
CLRF TEC_flg
CLRF TEC_numv
RETURN
LEETECLADO:
CLRF TMP2
MOVLW selfa
MOVWF PKYBD
XORWF PKYBD,W
BTFSC STATUS,Z
GOTO LEETEC_RET
CLRF TMP1
INCF TMP1,F
MOVLW self1
CALL LEETEC1
MOVLW self2
CALL LEETEC1
MOVLW self3
CALL LEETEC1
MOVLW self4
CALL LEETEC1
LEETEC_RET:
MOVLW selfa
MOVWF PKYBD
MOVF TMP2,W
RETURN
LEETEC1:
MOVWF PKYBD
MOVF TMP2,F
BTFSS STATUS,Z
RETURN
BTFSS PKYBD,4
GOTO LEETEC2
INCF TMP1,F
BTFSS PKYBD,5
GOTO LEETEC2
INCF TMP1,F
BTFSS PKYBD,6
GOTO LEETEC2
INCF TMP1,F
BTFSS PKYBD,7
GOTO LEETEC2
INCF TMP1,F
RETURN
LEETEC2:
MOVF TMP1,W
MOVWF TMP2
RETURN
ELIMREB:
MOVWF TMP1
XORWF TEC_ant,W
BTFSC STATUS,Z
GOTO ELIM_IG
MOVF TMP1,W
MOVWF TEC_ant
CLRF TEC_numv
RETLW 0
ELIM_IG:
MOVLW nminv
SUBWF TEC_numv,W
BTFSC STATUS,Z
GOTO ELIM_EST
INCF TEC_numv,F
RETLW 0
ELIM_EST:
MOVF TMP1,W
RETURN
REPORTT:
IORLW 0
BTFSC STATUS,Z
GOTO RE_NTEC
RE_TEC:
BSF STATUS,Z
BTFSC TEC_flg,F_rep
RETLW 0
BSF TEC_flg,F_rep
BCF STATUS,Z
RETURN
RE_NTEC:
BCF TEC_flg,F_rep
ANDLW 0
RETURN
;***************************************
;******INICIALIZAR EL CONVERSOR***********
INITAD:
BSF STATUS, RP0
MOVLW B'10000101'
MOVWF ADCON1&7F
BSF TRISA&7F,0
BSF TRISA&7F,1
BSF TRISA&7F,3
BCF STATUS,RP0
BCF ADCON0,ADCS1
BCF ADCON0,ADCS0
BCF ADCON0,CHS2
BCF ADCON0,CHS1
BCF ADCON0,CHS0
BCF ADCON0,ADON
RETURN
;****************************************
;CAN0
;Fija el canal 0 para la conversion AD
BCF ADCON0,CHS2
BCF ADCON0,CHS1
BCF ADCON0,CHS0
RETURN
;****************************************
;CAN1
;Fija el canal 1 para la conversion AD
BCF ADCON0,CHS2
BCF ADCON0,CHS1
BSF ADCON0,CHS0
RETURN
;*****************************************
;CONVAD
;Conversion AD
CONVAD:
BSF ADCON0,GO
CONVAD1:
BTFSC ADCON0,GO
GOTO CONVAD1
MOVF ADRESH,W
MOVWF CAD1
BSF STATUS,RP0
MOVF ADRESL&7F,W
BCF STATUS,RP0
MOVWF CAD0
RETURN
; *******************************************
; LLamada a subrutina de mensajes a LCD
MENS:
CALL LEETECLADO
CALL TRATECLA
MOVWF PULS
BTFSC PULS,3
CALL COMP1
BTFSC PULS,3
RETURN
BTFSC PULS,2
CALL COMP2
BTFSC PULS,2
RETURN
BTFSC PULS,1
CALL COMP3
BTFSC PULS,1
RETURN
CALL MENSINITs1
RETURN
; ******************************************
; Comprobar el 8 y 9
COMP1:
BTFSC PULS,0
CALL MENSINITat
BTFSS PULS,0
CALL MENSINITa2
RETURN
;*******************************************
;COMPROBAR 4,5,6,7
COMP2:
BTFSC PULS,1
CALL COMP21
BTFSC PULS,1
RETURN
BTFSC PULS,0
CALL MENSINITb2
BTFSS PULS,0
CALL MENSINITb1
RETURN
;*******************************************
;COMPROBAR 6,7
COMP21:
BTFSC PULS,0
CALL MENSINITa1
BTFSS PULS,0
CALL MENSINITbt
RETURN
;******************************************
;COMPROBAR 2,3
COMP3:
BTFSC PULS,0
CALL MENSINITst
BTFSS PULS,0
CALL MENSINITs2
RETURN
;*******************************************
;*********SUBIR*****************************
SUBIR:
MOVLW A'S'
CALL LCDIWR
MOVLW A'U'
CALL LCDIWR
MOVLW A'B'
CALL LCDIWR
MOVLW A'I'
CALL LCDIWR
MOVLW A'R'
CALL LCDIWR
MOVLW A' '
CALL LCDIWR
MOVLW A'P'
CALL LCDIWR
MOVLW A'E'
CALL LCDIWR
MOVLW A'R'
CALL LCDIWR
MOVLW A'S'
CALL LCDIWR
MOVLW A'I'
CALL LCDIWR
MOVLW A'A'
CALL LCDIWR
MOVLW A'N'
CALL LCDIWR
MOVLW A'A'
CALL LCDIWR
RETURN
;*********BAJAR*****************************
BAJAR:
MOVLW A'B'
CALL LCDIWR
MOVLW A'A'
CALL LCDIWR
MOVLW A'J'
CALL LCDIWR
MOVLW A'A'
CALL LCDIWR
MOVLW A'R'
CALL LCDIWR
MOVLW A' '
CALL LCDIWR
MOVLW A'P'
CALL LCDIWR
MOVLW A'E'
CALL LCDIWR
MOVLW A'R'
CALL LCDIWR
MOVLW A'S'
CALL LCDIWR
MOVLW A'I'
CALL LCDIWR
MOVLW A'A'
CALL LCDIWR
MOVLW A'N'
CALL LCDIWR
MOVLW A'A'
CALL LCDIWR
RETURN
;*********MODO AUTOMATICO******************
AUTO:
MOVLW A'M'
CALL LCDIWR
MOVLW A'o'
CALL LCDIWR
MOVLW A'd'
CALL LCDIWR
MOVLW A'o'
CALL LCDIWR
MOVLW A' '
CALL LCDIWR
MOVLW A'a'
CALL LCDIWR
MOVLW A'u'
CALL LCDIWR
MOVLW A't'
CALL LCDIWR
MOVLW A'o'
CALL LCDIWR
MOVLW A'm'
CALL LCDIWR
MOVLW A'á'
CALL LCDIWR
MOVLW A't'
CALL LCDIWR
MOVLW A'i'
CALL LCDIWR
MOVLW A'c'
CALL LCDIWR
MOVLW A'o'
CALL LCDIWR
RETURN
;*********SUBIR PERSIANA 1******************
MENSINITs1:
CALL SUBIR
MOVLW A' '
CALL LCDIWR
MOVLW A'1'
CALL LCDIWR
BSF P_LED,b_LED0
RETURN
;*********SUBIR PERSIANA 2******************
MENSINITs2:
CALL SUBIR
MOVLW A' '
CALL LCDIWR
MOVLW A'2'
CALL LCDIWR
BSF P_LED,b_LED1
RETURN
;*********SUBIR PERSIANAS******************
MENSINITst:
CALL SUBIR
MOVLW A'S'
CALL LCDIWR
BSF P_LED,b_LED0
BSF P_LED,b_LED1
RETURN
;*******************************************
;*********BAJAR PERSIANA 1******************
MENSINITb1:
CALL BAJAR
MOVLW A' '
CALL LCDIWR
MOVLW A'1'
CALL LCDIWR
BCF P_LED,b_LED0
RETURN
;*********BAJAR PERSIANA 2******************
MENSINITb2:
CALL BAJAR
MOVLW A' '
CALL LCDIWR
MOVLW A'2'
CALL LCDIWR
BCF P_LED,b_LED1
RETURN
;*********BAJAR TODAS******************
MENSINITbt:
CALL BAJAR
MOVLW A'S'
CALL LCDIWR
BCF P_LED,b_LED0
BCF P_LED,b_LED1
RETURN
;********AUTO PERSIANA 1**************
MENSINITa1:
CALL AUTO
MOVLW A' '
CALL LCDIWR
MOVLW A'1'
CALL LCDIWR
RETURN
;********AUTO PERSIANA 2*************
MENSINITa2:
CALL AUTO
MOVLW A' '
CALL LCDIWR
MOVLW A'2'
CALL LCDIWR
RETURN
;********AUTO TODAS******************
MENSINITat:
CALL AUTO
RETURN
END
-
MI. La verdad es que el código está dificil de entender por que no está comentado, y no se para que es cada instrucción.
También, no veo que allas configurado los puertos. Esto debe ser el problema. ¿Con qué software simulas tus programas?
Cuando quemes al pic, asegurate de que esté desactivado estas dos opciones de la palabra de configuración, BODEN y LVP.
A medidas que nos vallas contandod e los avanzes, haremos lo mismo, avanzando en el problema.
-
hola yo estoy haciendo un circuito muy parecido pero con un 16f876, solo que no me envia los datos a la pc... no se porque si alguien puede ayudarme gracias..
aqui les dejo el codigo.
;*****************************************************
;***********proyecto de microprocesadores*************
;este proyecto realiza una comunicacion de un teclado*
;matricial 4x4d esde el circuito al pc por medio de **
;una interfaz creada conel max232 y se realiza por el*
;puerto seria de la pccon un conector DB9, el pic ****
;usado es el 16f876A tambien posee 4 leds que indica**
;en binario el numero introducido en el teclado*******
;codigo fuente del programa
list p=16f876
Radix HEX
Include "p16f876.inc"
;*******************
;ETIQUETAS USADAS
;*******************
cblock 20h
tx
dato
endc
DATO_L EQU 0X20 ;dato leido del teclado
COLUMNA EQU 0X21 ;
r1 EQU 0X22 ;variable de la subrutina
r2 EQU 0X23 ;de perdida de tiempo
r3 EQU 0X24 ;
ORG 0x0000 ;
goto configura ;
ORG 0X0004
;****************************
;SUBRUTINA DE CONFIGURACION
;****************************
configura
bcf STATUS,RP1 ;cambio al banco de memoria 1
bsf STATUS,RP0
movlw b'10000000' ;
movwf TRISC ;RC6 -entrada RC7-salida
movlw 0xF0
movwf TRISB ;
movlw b'00100100' ;usart a alta velocidad
movwf TXSTA ;y activacion de la transmision
movlw .25
movwf SPBRG ;velocidad de 9600 baudios
bcf STATUS, RP0 ;regresa al banco de memoria 0
bsf RCSTA,SPEN ;activacion de la USART
;*******************************
;PROGRAMA PRINCIPAL
;*******************************
main
;*******************************
;sub rutina de columna
;*******************************
col_1
movlw b'00001110' ;activa columna 1
call act_col
col_2
movlw b'00001101' ;activa columna 2
call act_col
col_3
movlw b'00001011' ;activa columna 3
call act_col
col_4
movlw b'00001111' ;activa columna 4
call act_col
goto main ;regresa al ciclo
;***********************************
;subrutina de activacion de columnas
;***********************************
act_col
movwf PORTB
movwf COLUMNA
MOVF PORTB,W ;leer el puerto B
andlw 0xF0 ;elimina la parte baja del byte
movwf DATO_L ;mueve la lectura a DATO 0x20
btfss DATO_L,4
call fil_1
btfss DATO_L,5
call fil_2
btfss DATO_L,6
call fil_3
btfss DATO_L,7
call fil_4
return
;***********************************
;subrutina de las filas
;***********************************
fil_1
btfss COLUMNA,0
movlw 0x0C
btfss COLUMNA,1
movlw 0x0D
btfss COLUMNA,2
movlw 0x0E
btfss COLUMNA,3
movlw 0x0F
call tx_dato
movwf PORTC
call retardo
return
fil_2
btfss COLUMNA,0
movlw 0x08
btfss COLUMNA,1
movlw 0x09
btfss COLUMNA,2
movlw 0x0A
btfss COLUMNA,3
movlw 0x0B
call tx_dato
movwf PORTC
call retardo
return
fil_3
btfss COLUMNA,0
movlw 0x04
btfss COLUMNA,1
movlw 0x05
btfss COLUMNA,2
movlw 0x06
btfss COLUMNA,3
movlw 0x07
call tx_dato
movwf PORTC
call retardo
return
fil_4
btfss COLUMNA,0
movlw 0x00
btfss COLUMNA,1
movlw 0x01
btfss COLUMNA,2
movlw 0x02
btfss COLUMNA,3
movlw 0x03
call tx_dato
movwf PORTC
call retardo
return
;***********************************
;subrutina de transmision de datos
;***********************************
tx_dato
bcf STATUS,RP0
bcf STATUS,RP1
movwf TXREG
bsf STATUS,RP0 ; cambio a banco 1
tx_dat_w
btfss TXSTA,TRMT
goto tx_dat_w
bcf STATUS,RP0 ;regresa a banco 0
return
;***********************************
;subrutina de perdida de tiempo
;***********************************
retardo
bcf STATUS,RP0 ;CAMBIAR A PAGINA 0
bcf STATUS,RP1 ;CAMBIAR A PAGINA 1
movlw .01
movwf r1
ciclo_3
movlw .120
movwf r2
ciclo_2
movlw .166
movwf r3
ciclo_1
decfsz r3,1
goto ciclo_1
decfsz r2,1
goto ciclo_2
decfsz r1,1
goto ciclo_3
end