TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: CDankutsuou en 20 de Noviembre de 2008, 19:30:23
-
Saludos. Anteriormente he estado rondando estos foros, nomás viendo threads, pero hasta anteayer me registré porque me preguntaba si podían responderme alguna dudas.
Ya leí e investigué varios documentos sobre introducciones al PIC16F873 y al MPLAB, pero aun asi no veo como hacerle.
Mi problema es:
- Crear un teclado (4x3)
- Introduzco un password de 4 digitos, solito se guarda, nada de boton aceptar.
- Al volverlo a poner, si es acertado saca una señal cuadrada, si es falso, suena un buzzer.
- Boton de reset (esto es ¿dándole 0 lógico al MCLR no?)
Bueno, el teclado ya esta (lei también en estos foros sobre problemas de passwords y varios teclados, gracias), todo esta conectado.
RB0 a RB3 : salidas a las filas (de arriba para abajo)
RB4 a RB6 : entradas de las columnas (iquierda a derecha)
Ya les cree la subrutina de 20 ms para eliminar el bounce o rebote.
RC3 salida de la señal cuadrada, ya cree la subrutina de la señal de 20 MHz.
RC4 salida a buzzer.
Lo único que no le hayo, es como manejar datos en el PIC y la posterior comparación, esto usando MPLAB y el set de 35 instrucciones del PIC.
Segun leí, a partir de la dirección 20H son los registro de propósito genearal. Se como guardarlo, pero tengo dudas sobre como crear el password.
El PIC se la pasa escaneando el teclado, al presionar una tecla se active la subrutina de dicha tecla, pero ¿cómo le hago para identificar el número del dígito?
No se si sea algo como C++, usando contadores que aumenten cada que ingreso un nuevo dígito, pero no encuentro como crear un dato en el PIC que aumente y me marque el bit donde debo guardar. Algo así:
MOVWF 20H,0 para luego al presionar otra tecla, grabar en
MOVWF 20H,1
¿No se puede esto? tener "dirección,n" y hacer n+1 cada que ingrese una tecla, esto en la subrutina de cada tecla (0~9,A y B). Y ¿siendo "n" una dirección? O sea
MOVWF 20H,213H
Y me han dicho que estas cosas se pueden programar en C++, lo cual sería genial porque a eso si le sé. Y supongo esa es mi mayor falla, que quiero ver esto como si fuera lenguaje C++. Y la lógica que me falla porque también tardé mucho en entenderle a los FOR y WHILE, y como hacerlos con las istrucciones del PIC.
Nuevamente saludos, y gracias de antemano.
-
que te parece la idea de utilizar direccionamiento indirecto,esto se hace con los registros INDF y FSR, algo puedes leer por acá:
http://www.todopic.com.ar/foros/index.php?topic=17233.0
y si no te convence podes buscar más info de ellos en el foro y el la hoja de datos del micro que utilizas
-
Yo he realizado un trabajo sobre esto.
Lo que yo hise, fue escanear el teclado, cuando se presionó un botón, guardar el número de botón en una pocición de la ram, luego continuo escaneando el teclado y cuando se presiona la siguiente tecla, la guardo en la pocición siguiente en la RAM de la primer tecla guardada, repito el ciclo hasta completar los 4 dígitos (también he creado una clave de 4 dígitos). Una vez que se almacenaron los 4 dígitos de la clave, me dirijo a una rutina que verifica las teclas guardada en la RAM y las comparo con la almacenada en la EEPROM.
El reset, se activa con 0 lógico, por lo que tiene que estar a 1 lógico.
¿cómo es la exploración de tu teclado?
-
A ver, yo tengo esto, basado lo que escrribió la maestra (supongo este al menos por el camino correcto):
TEST CLRF PORTB
BSF PORTB,0
BTFSS PORTB,4
GOTO SIGUE05
CALL DELAY20MS
BTFSS PORTB,4
GOTO SIGUE05
CALL TECLA0
SIGUE05 BTFSS PORTB,5
GOTO SIGUE06
CALL DELAY20MS
BTFSS PORTB,5
GOTO SIGUE06
CALL TECLA1
SIGUE06 BTFSS PORTB,6
GOTO SIGUE10
CALL DELAY20MS
BTFSS PORTB,6
GOTO SIGUE10
CALL TECLA2
SIGUE10 BCF PORTB,0
BSF PORTB,1
BTFSS PORTB,4
GOTO SIGUE15
CALL DELAY20MS
BTFSS PORTB,4
GOTO SIGUE15
CALL TECLA3
SIGUE15 BTFSS PORTB,5
GOTO SIGUE16
CALL DELAY20MS
BTFSS PORTB,5
GOTO SIGUE16
CALL TECLA4
SIGUE16 BTFSS PORTB,6
GOTO SIGUE20
CALL DELAY20MS
BTFSS PORTB,6
GOTO SIGUE20
CALL TECLA5
SIGUE20 BCF PORTB,1
BSF PORTB,2
BTFSS PORTB,4
GOTO SIGUE25
CALL DELAY20MS
BTFSS PORTB,4
GOTO SIGUE25
CALL TECLA6
SIGUE25 BTFSS PORTB,5
GOTO SIGUE26
CALL DELAY20MS
BTFSS PORTB,5
GOTO SIGUE26
CALL TECLA7
SIGUE26 BTFSS PORTB,6
GOTO SIGUE30
CALL DELAY20MS
BTFSS PORTB,6
GOTO SIGUE30
CALL TECLA8
SIGUE30 BCF PORTB,2
BSF PORTB,3
BTFSS PORTB,4
GOTO SIGUE35
CALL DELAY20MS
BTFSS PORTB,4
GOTO SIGUE35
CALL TECLA9
SIGUE35 BTFSS PORTB,5
GOTO SIGUE36
CALL DELAY20MS
BTFSS PORTB,5
GOTO SIGUE36
CALL TECLAA
SIGUE36 BTFSS PORTB,6
GOTO INICIO
CALL DELAY20MS
BTFSS PORTB,6
GOTO TEST
CALL TECLAB
GOTO TEST
Leon Pic:
Si también quiero hacerle así, grabo elprimer dígito en, no se, 23H, el segundo en 24H, y así.
Pero lo que tengo duda es como hacerle para pasar del registro 23 al 24. No puedo sumar una direción ¿o si?
Por ejemplo:
Si quiero meter la 5753
En la subrutina 5, habrá un contador CONTDIG que indique "0", entonces lo grabó en 23H. Aumento CONTDIG.
Al presionar 7, en la subrutina OCNTDIG valdrá 1, entonces lo grabará en "23H+1"
Asi, hasta que CONTDIG valga 4, asi va a programar para confirmar el password y así... pero no se implementarlo de 1 en 1 que es como se hace en los PIC.... Mugrosas funciones RISC.....
¿No va por ahí? La cosa es que, repito, lo único que he usado en mi vida es C++, y quiero verlo así, pero no se implementarlo o adecuarlo a las instrucciones básicas del PIC.
Cryn
No se de que me estás hablando, per deja lo checo. Se que he visto ese INDF en el datasheet... Gracias.
Hoy pregunté por la escuela, y varios me dicen "Si se puede programar en C++", pero nadie sabe como. A lo mucho me dijeron que el MPLAB lo soporta, para asi crear el .asm y posteriormente el .hex.
¡Saludos! y gracias.
-
Para leer tu teclado:
RB0 1 2 3
RB1 4 5 6
RB2 7 8 9
RB3 10 11 12
RB4 RB5 RB6
Indiqué el número de tecla. Obviamente el número no tiene que necesariamente corresponder a su significado(en un teclado común la posición 11 correspondería a la tecla 0 por ejemplo, la 10 al asterísco y la 12 al numeral).
;/////////////////////////////////
Tecla EQU 0xXX ;Indicará tecla actualmente leída
i EQU 0xXX+1 ;Contador
Aux EQU 0xXX+2 ;Variable Auxiliar
CantTeclas EQU 0xXX+3 ;Cantidad de teclas almacenadas al momento(0<CantTeclas<5)
;Estos 8 bytes a continuación deben ir ordenados consecutivamente y en este orden
Dig1Pass EQU 0xXX+4 ;Para almacenar el primer Digito del Password
Dig2Pass EQU 0xXX+5 ;Para almacenar el segundo Digito del Password
Dig3Pass EQU 0xXX+6 ;Para almacenar el tercer Digito del Password
Dig4Pass EQU 0xXX+7 ;Para almacenar el cuarto Digito del Password
Dig1Access EQU 0xXX+8 ;Para almacenar el primer Digito del Codigo ingresado
Dig2Access EQU 0xXX+9 ;Para almacenar el segundo Digito del Codigo ingresado
Dig3Access EQU 0xXX+10 ;Para almacenar el tercer Digito del Codigo ingresado
Dig4Access EQU 0xXX+11 ;Para almacenar el cuarto Digito del Codigo ingresado
Banderas EQU 0xXX+12 ;Indicadores que guardan el estado actual del sistema
#define YaIngresoPass Banderas,0
#define Onda Banderas,1
#define Buzzer Banderas,2
;//////////////////////
ValorTeclas ;Devuelve el valor ASCII según la tecla presionada(Se pueden cambiar a gusto)
addwf PCL,F
retlw "1"
retlw "2"
retlw "3"
retlw "4"
retlw "5"
retlw "6"
retlw "7"
retlw "8"
retlw "9"
retlw "*"
retlw "0"
retlw "#"
retlw "?" ;No debería caer nunca acá(si tecla=12 es porque no se encontró nada en el teclado) pero igual, por las dudas...:D
;/////////////////////////////////
;Lee el teclado. La variable Tecla contiene el numero de tecla presionada si es que hay alguna. Caso contrario Tecla vuelve valiendo .12
LeerTeclado
movlw .4
movwf i ;Indicar que el proceso se va a realizar 4 veces(son 4 filas, no?)
clrf Tecla ;Inicializar Tecla a 0
movlw 0x0F
iorwf PORTB ;Poner todas las filas en Alto
bcf STATUS,C ;Preparar Carry para inyectar un cero en RB0 en la primera rotación
ProxFila
rlf PORTB,W ;Rotar sin afectar al RB7(si no importara afectar a RB7(ya sea porque no lo usas o está configurado como entrada) el código se acortaría un poco...)
andlw 0x7F ;enmascarar bit7
movwf Aux ;guardar los 7 bis excepto el RB7
movlw 0x80
andwf PORTB,F ;poner a cero todos menos el RB7
movf Aux,W
iorwf PORTB,F ;y ahora incluir Aux en PORTB para conseguir el valor deseado
btfss PORTB,4 ;Columna1?
return ;Si.Volver
incf Tecla,F ;No. Incrementar Tecla
btfss PORTB,5 ;Columna2?
return ;Si.Volver
incf Tecla,F ;No. Incrementar Tecla
btfss PORTB,6 ;Columna3?
return ;Si.Volver
incf Tecla,F ;No. Incrementar Tecla
bsf STATUS,C ;Preparar el Carry para inyectar un 1 por la derecha del PuertoB
decfsz i,F ;Ya escaneó las 4 filas?
goto ProxFila ;No, entonces proxima fila!
return ;Si...volver(Tecla=.12)
;//////////////////////
Programa_Principal
;Falta config inicial!
clrf CantTeclas ;Indicar 0 teclas ingresadas al momento
clrf Banderas ;Inicializar estado del sistema
movlw Dig1Pass
movwf FSR ;Cargar la posicion RAM de donde se guardará el primer digito ingresado del password en el registro de acceso indirecto
Loop
call LeerTeclado ;Buscar tecla presionada(si usaras la interrupción RB4-RB7 para detectarla quedaría más profesional)
movf Tecla,w
xorlw .12 ;Si tecla=12, no hay tecla presionada
btfsc STATUS,Z
goto Loop ;entonces, volver a Loop
;Se encontró una tecla!
;call DemoraAntiRebote ;Faltaría hacer esta subrutina
pageselw ValorTeclas ;Acomodar PCLATH para manejar la tabla correctamente
movf Tecla,W
call ValorTeclas ;buscar su valor ASCII
movwf INDF ;y guardarla en donde corresponda
incf FSR,F ;apuntar a próximo digito
incf CantTeclas,F ;incrementar cantidad de teclas presionadas
movf CantTeclas,w
xorlw 4
btfss STATUS,Z ;Se presionaron 4 teclas?
goto Loop ;no, seguir leyendo
clrf CantTeclas ;si. Reiniciar cantidad de teclas presionadas
btfsc YaIngresoPass,0 ;ya se ha ingresado el password?
goto Comparar ;Si. Entonces comparar valor ingresado con el password
bsf YaIngresoPass,0 ;No se había ingresado password, indicar que ahora si.
goto Loop ;Y volver al Loop para leer si las proximas 4 teclas a presionar concuerdan con el password
;//////////////////////
;/////////////////////////////////
Comparar
movlw .4
movwf i ;indicar 4 digitos a comparar
movlw Dig1Pass
movwf FSR ;apuntar al primer digito del Password
prox
movf INDF,W
movwf Aux ;Guardar valor actual en registro auxiliar
movlw .4
addwf FSR,F ;incrementar el acceso indirecto en 4(es decir,a la posición RAM del digito de acceso
;corespondiente(Dig1Pass+4=Dig1Access,Dig2Pass+4=Dig2Access,etc)
movf INDF,w
xorwf Aux,W ;Compararlos
btfss STATUS,Z ;Iguales?
goto NoCoinciden ;No.Ir a setear modo Buzzer
movlw .3
subwf FSR,F ;Apuntar al próximo digito del password
decfsz i,f ;Ya comparé los 4 digitos?
goto prox ;No, entonces comparar el próximo
Coinciden ;Coindicieron!
bcf Buzzer ;Desactivar modo buzzer y activar modo onda
bsf Onda
movlw Dig1Access
movwf FSR ;Cargar acceso indirecto para volver a leer el primer digito de acceso
goto Loop ;Volver al Loop
NoCoinciden ;No coincidieron
bcf Onda ;Desactivar modo onda y activar modo buzzer
bsf Buzzer
movlw Dig1Access
movwf FSR ;Cargar acceso indirecto para volver a leer el primer digito de acceso
goto Loop ;Volver al Loop
;//////////////////////
Lo programé "on the fly"(al vuelo), es decir que puede que haya errores y obviamente falta la parte de configuración inicial,etc...espero que lo estudies meticulosamente para poder comprender la idea que desarrollé acá. No es fácil si no sabes de assembly, pero con hoja, papel y mejor aún un buen simulador se puede.
Saludos.
-
A simple vista parece que no tiene errores.
CDankutsuou.
Ademas del Assembler, al pic se lo puede programar en Proton en CCS (que es lenguaje C para pic), pero necesitas del compilador necesario para ello. Actualmente, y en las últimas versiones del MPLAB, trae compiladores gratuitos para estos lenguajes pero con limitaciones.