Autor Tema: Ayuda con funciones internas (PIC16F873)  (Leído 3120 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado CDankutsuou

  • PIC10
  • *
  • Mensajes: 2
Ayuda con funciones internas (PIC16F873)
« 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.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Ayuda con funciones internas (PIC16F873)
« Respuesta #1 en: 20 de Noviembre de 2008, 20:12:38 »
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
.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: Ayuda con funciones internas (PIC16F873)
« Respuesta #2 en: 20 de Noviembre de 2008, 20:51:10 »
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?
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado CDankutsuou

  • PIC10
  • *
  • Mensajes: 2
Re: Ayuda con funciones internas (PIC16F873)
« Respuesta #3 en: 20 de Noviembre de 2008, 23:42:59 »
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.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Ayuda con funciones internas (PIC16F873)
« Respuesta #4 en: 21 de Noviembre de 2008, 05:00:01 »
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.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: Ayuda con funciones internas (PIC16F873)
« Respuesta #5 en: 21 de Noviembre de 2008, 10:32:44 »
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.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.


 

anything