Manejar bien el oscilador del PIC

Hola:

Es raro que maneje un PIC12F629. Estoy probándolo y tengo muchas dudas. Antes que nada como hago el PIC12F629 pongo el cableado????????

Por ejemplo, el Power ON donde lo conecto. Aquí hice un ejemplo que no se si es válido. Necesito una entrada de un PIN y 4 salidas.

tabla-553975.png


Esto del mundo de la calibración del PIC12F629 es un mundo. En el MPALB X lo he puesto a 4 MHz del oscilador interno, no se que habré hecho realmente. Quiero saber qué frecuencia estoy usando exactamente ya que debo controlar tiempo como retardos. He estado buscando por Internet pero no me deja claro hasta llegar por ahora hacer este código de inicio.

Código:
    ; ZONA DE DATOS*****************************************************************
    LIST P=12F629 ; Procesador usado.
    INCLUDE <P12F629.INC> ; Fichero que definen las etiquetas.

    __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 

    CBLOCK  0x20
    ENDC

; ZONA DE CÓDIGOS***************************************************************
    ORG     0                               ; El programa comienza en la dirección 0.
    goto    Inicio
    ORG     0x04
;    goto    ServicioInterrupcion

Inicio
    bsf STATUS,RP0                          ;Selecciona banco 1.
    call    0x3FF
    movwf   OSCCAL
    movlw   b'00111011'                     ;1 = entrada y 0 = salida.
    movwf   TRISIO
    bcf STATUS,RP0                          ;Selecciona banco 0.
    movlw   b'00000111'                     ; Desactivar comparadores.
    movwf   CMCON
    clrf    GPIO                             ; Limpiar.

Principal
;   |GP0 GP1 GP4 GP5
;---+----------------
;1) | 0   1   0   0
;2) | 1   0   1   0
;3) | 0   1   1   0
;4) | 1   0   0   1



;   INCLUDE  <RETARDOS.inc>

    ORG     0x3FF
    retlw   b'00100000'
    END
Antes de meterme al código principal, quiero saber si todo anda correcto, por ahora no me da fallos pero no se si es el más adecuado. Otra cosa es el esquema del PIC12F629 que no se si es el más adecuado para hacer el diseño.

Cualquier sugerencia es de gran ayuda. ;)

Saludo.
 
Hola, Meta.

Para la aplicación que estás haciendo te sirve el PIC12F629. La conexión es muy sencilla; sólo tienes que alimentar el chip por las patas adecuadas, poner la pata 4 a +V (a través de una resistencia si quieres) para que no se te resetee, y el resto ya es el circuito que quieras hacer (tus 4 LEDs y el pulsador).

No veo en tu esquema el Power ON del que hablas, pero si es un interruptor colócalo al principio de la alimentación, para que cuando lo apagues no haya tensión en ninguna de las patas del PIC.

Creo que debería haber una instrucción ORG antes de tu etiquera Inicio; y si no vas a utilizar las interrupciones pon una instrucción de retorno en la dirección ServicioInterrupcion, pero no pongas el "goto ServicioInterrupcion" como comentario, ya que cuando se produzca una interrupción se va a ejecutar lo que tienes a partir de la etiqueta Inicio.

Supongo que el código que has adjuntado es sólo una parte. Si no, está incompleto. ¿Qué pasa a partir del "clrf GPIO"?

Estás utilizando el oscilador RC del PIC (a menos que en el MPLAB hayas especificado otra cosa y le indiques que no utilice la configuración que viene en el código). De esa forma no te sirve la calibración del oscilador, y no vas a alcanzar 4 MHz.

Ánimo, que cuando superes las primeras dificultades verás cuánto partido puedes sacar de los microcontroladores.
 
Al usar el reloj interno existe cierta pérdida de precisión, si los retardos exigen de ella te recomiendo que armes el oscilador de 4MHz externo y lo conectes a OSC1. El pin que te hará falta lo compensas utilizando MCLR como entrada adicional
 
Hola, Meta.

Para la aplicación que estás haciendo te sirve el PIC12F629. La conexión es muy sencilla; sólo tienes que alimentar el chip por las patas adecuadas, poner la pata 4 a +V (a través de una resistencia si quieres) para que no se te resetee, y el resto ya es el circuito que quieras hacer (tus 4 LEDs y el pulsador).

Entra la alimentación del PIC hay que colocar un condensador de 100 nF en paralelo para que no haya ruido, es opocional pero eficaz.

No veo en tu esquema el Power ON del que hablas, pero si es un interruptor colócalo al principio de la alimentación, para que cuando lo apagues no haya tensión en ninguna de las patas del PIC.

Esto se hará o no depende de lo que quiera hacer el PIC. Mi idea ahora es, tener bien configurado el PIC con el oscilador interno a 4 MHz.

Creo que debería haber una instrucción ORG antes de tu etiquera Inicio; y si no vas a utilizar las interrupciones pon una instrucción de retorno en la dirección ServicioInterrupcion, pero no pongas el "goto ServicioInterrupcion" como comentario, ya que cuando se produzca una interrupción se va a ejecutar lo que tienes a partir de la etiqueta Inicio.

Exacto, aún estoy con el desarrollo del código.

Supongo que el código que has adjuntado es sólo una parte. Si no, está incompleto. ¿Qué pasa a partir del "clrf GPIO"?

Estoy intentado aún en completar el código, antes de ello, quiero asegurarme que la configuración del oscilador interno funcione bien, luego continúo con el código.


Estás utilizando el oscilador RC del PIC (a menos que en el MPLAB hayas especificado otra cosa y le indiques que no utilice la configuración que viene en el código). De esa forma no te sirve la calibración del oscilador, y no vas a alcanzar 4 MHz.

No se cual escoger en la configuración, prefiero tenerlo programado en .asm principal que en el MPLAB X o MPLAB 8. Quiero un oscilador interno, que no tenga que usar ningún componente externo, ni para osciladores, ni el botón de Reset externo del PIC.

Si no alcanza justo los 4 MHz, al menos quiero saber cuanto MHz está funcionando el PIC más o menos aproximado porque voy a usar retardos que lo haré aquí para introducirlo como antirrebotes edl pulsador.


Ánimo, que cuando superes las primeras dificultades verás cuánto partido puedes sacar de los microcontroladores.

Me cuesta más entender un PIC12F que un PIC18F en asm, ;)


Cuando tenga clarísimo toda la configuración del PIC...

__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

...haré ya la programación principal como indica abajo.

¿Qué pongo en _INTRC_OSC_NOCLKOUT?

Por lo que parece hay que escoger bien.
Código:
_FOSC_LP             EQU  H'3FF8'    ; LP oscillator: Low power crystal on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN
_LP_OSC              EQU  H'3FF8'    ; LP oscillator: Low power crystal on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN
_FOSC_XT             EQU  H'3FF9'    ; XT oscillator: Crystal/resonator on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN
_XT_OSC              EQU  H'3FF9'    ; XT oscillator: Crystal/resonator on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN
_FOSC_HS             EQU  H'3FFA'    ; HS oscillator: High speed crystal/resonator on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN
_HS_OSC              EQU  H'3FFA'    ; HS oscillator: High speed crystal/resonator on GP4/OSC2/CLKOUT and GP5/OSC1/CLKIN
_FOSC_EC             EQU  H'3FFB'    ; EC: I/O function on GP4/OSC2/CLKOUT pin, CLKIN on GP5/OSC1/CLKIN
_EC_OSC              EQU  H'3FFB'    ; EC: I/O function on GP4/OSC2/CLKOUT pin, CLKIN on GP5/OSC1/CLKIN
_FOSC_INTRCIO        EQU  H'3FFC'    ; INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN
_INTRC_OSC_NOCLKOUT  EQU  H'3FFC'    ; INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN
_FOSC_INTRCCLK       EQU  H'3FFD'    ; INTOSC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN
_INTRC_OSC_CLKOUT    EQU  H'3FFD'    ; INTOSC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN
_FOSC_EXTRCIO        EQU  H'3FFE'    ; RC oscillator: I/O function on GP4/OSC2/CLKOUT pin, RC on GP5/OSC1/CLKIN
_EXTRC_OSC_NOCLKOUT  EQU  H'3FFE'    ; RC oscillator: I/O function on GP4/OSC2/CLKOUT pin, RC on GP5/OSC1/CLKIN
_FOSC_EXTRCCLK       EQU  H'3FFF'    ; RC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, RC on GP5/OSC1/CLKIN
_EXTRC_OSC_CLKOUT    EQU  H'3FFF'    ; RC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, RC on GP5/OSC1/CLKIN
tablon-554969.png


Otra cosa clara, prefiero que me digan ustedes que saben más que yo sobre os PIC12F, los mejores pines para usarlo uno como entrada y 4 para salidas, ya me dirán. Luego hago el cuadro de arriba otra vez con sus respondientes pines.

Muchísimas gracias por la ayuda y aclaración. Tengo ya ganas de hacer la programación del PIC para acabar el código completo.

Les subo un PDF que les puede servir de ayuda del 12F6xx.

;)
 

Adjuntos

  • Calibrar oscilador interno (12F6xx).pdf
    82.4 KB · Visitas: 49
Última edición:
Hola de nuevo, Meta.

Mira, analizando el datasheet de tu PIC encuentro que el valor correcto para el oscilador sería este:

_FOSC_INTRCIO EQU H'3FFC' ; INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN

Con este ya tienes 4 MHz, que variarán un poquito dependiendo de la calibración; pero ten por seguro que los alcanzas sin problemas.

En cuanto a los pines adecuados, creo que has elegido bien. Es más, te diría que puedes ahorrarte la resistencia del pulsador si utilizas la Pull up interna del GP2.



Vale, y ahora veo que el que tú has utilizado tiene el mismo valor. No sé por qué ponen constantes con distinto nombre y el mismo valor. Sólo vale para confundirnos :(
 
Última edición:
Hola:

Un ejemplo de prueba solo con un Led a la salida y un pulsador. Este caso camié al _FOSC_INTRCIO.

Código:
    ; ZONA DE DATOS*****************************************************************
    LIST P=12F629 ; Procesador usado.
    INCLUDE <P12F629.INC> ; Fichero que definen las etiquetas.

    __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _FOSC_INTRCIO

    CBLOCK  0x20
    ENDC

#DEFINE Pulsador    GPIO,0        ; Pulsador conectado a RA4.
#DEFINE LED            GPIO,1        ; Línea donde se conecta el diodo LED.

; ZONA DE CÓDIGOS***************************************************************
    ORG     0                               ; El programa comienza en la dirección 0.
    goto    Inicio
;    ORG     0x04
;    goto    ServicioInterrupcion

Inicio
    BANKSEL OSCCAL                          ;Selecciona banco 1.
    call    0x3FF
    movwf   OSCCAL
    movlw   b'00000001'                     ;1 = entrada y 0 = salida.
    movwf   TRISIO
    BANKSEL CMCON                          ;Selecciona banco 0.
    movlw   b'00000111'                     ; Desactivar comparadores.
    movwf   CMCON
    clrf    GPIO                             ; Limpiar.

Principal
;   |GP0 GP1 GP4 GP5
;---+----------------
;1) | 0   1   0   0
;2) | 1   0   1   0
;3) | 0   1   1   0
;4) | 1   0   0   1

    btfsc    Pulsador            ; ¿Pulsador presionado?, ¿(Pulsador)=0?
    goto    Fin                    ; No. Vuelve a leerlo.
;    call    Retardo_20ms        ; Espera que se estabilicen los niveles de tensión.
    btfsc    Pulsador            ; Comprueba si es un rebote.
    goto    Fin                    ; Era un rebote y sale fuera.
    btfsc    LED                    ; Testea el último estado del LED.
     goto    EstabaEncendido
EstabaApagado
    bsf        LED                    ; Estaba apagado y lo enciende.
    goto    EsperaDejePulsar
EstabaEncendido
    bcf        LED                    ; Estaba encendido y lo apaga.
EsperaDejePulsar
    btfss    Pulsador            ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar    ; No. Espera que deje de pulsar.
Fin
    goto    Principal

    INCLUDE  <RETARDOS.inc>

    ORG     0x3FF
    retlw   b'00100000'
    END
Sobre el PULL-UP. ¿Cómo lo pondrías?Aquí encontré algo, hay qu eleerlo y hacer pruebas bien.

WEAK PULL-UP
Cada uno de los pines GPIO, excepto GP3, tiene una opción 'weak pull-up' configurable individualmente. Los bits de control WPUx habilitan o deshabilitan cada una de las pull-up. Consulta el registro 3-3. Cada pull-upl se desactiva automáticamente cuando el pin de puerto está configurado como una salida. Los pull-ups están deshabilitados en un Power-on Reset por el bit /GPPU (Registro OPTION_REG).

gpioreg_3_m.gif
gpioreg_3_m.gif


bit 7-6: Sin implementar. Leídos como 0
bit 5-4: WPU<5:4>: bits del Registro Weak Pull-up
1 = Pull-up habilitado
0 = Pull-up deshabilitado
bit 3: Sin implementar. Leído como 0
bit 2-0: WPU<2:0>: bits del Registro Weak Pull-up
1 = Pull-up habilitado
0 = Pull-up deshabilitado

Notas:
1 - /GPPU debe estar habilitado para que las pull-up internas lo estén también. Para ello, en el registro 'OPTION REGISTER (ADDRESS: 81h), el bit 7 ha de ser un 1
2 – Weak pull-up se deshabilita automáticamente si el pin está como salida (TRISIO = 0).

Continuaré hacer esta tabla.
tablon-554969.png


Un antrada y 4 salidas.

Saludo.
 
Última edición:
Pues el pull up, como tú mismo has descrito. Tienes que meter el valor 0x04 en el registro de Pull up para que el bit correspondiente al GP2 esté a 1. Tienes que activar también el bit /GPPU. Y en cuanto al circuito, simplemente quita la resistencia del pulsador, y te olvidas de la conexión a +V, ya que eso lo tienes dentro del PIC. Es decir, que te quedaría solamente el pulsador intercalado entre la pata GP2 y masa.
 
Hola:

Cambio de pines y esquema:
kjh-555295.gif


GP0 en la entrada, PG3 no se usa y las demás son salidas del Led.

¿Sices que puedo usar GP0 de entrada sin poner resistencias? No, no lo has dicho, si a sus salidas. Haber si me sale.

Por lo que entiendo, he hecho esto:

Código:
    bcf     OPTION_REG,NOT_GPPU             ;Activa Pull Up.
    movlw   b'00110111'                     ;Habilitar Pull Up.
    movwf   WPU
En el simulador no me da nada, no hace nada, quizás ea el oscilador mal configurado.

Código:
    ; ZONA DE DATOS*****************************************************************
    LIST P=12F629 ; Procesador usado.
    INCLUDE <P12F629.INC> ; Fichero que definen las etiquetas.

    __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _FOSC_INTRCIO

    CBLOCK  0x20
    ENDC

#DEFINE Pulsador    GPIO,0        ; Pulsador conectado a RA4.
#DEFINE Led1        GPIO,1        ; Línea donde se conecta el diodo Led.
#DEFINE Led2        GPIO,2
#DEFINE Led3        GPIO,4
#DEFINE Led4        GPIO,5

; ZONA DE CÓDIGOS***************************************************************
    ORG     0                               ; El programa comienza en la dirección 0.
    goto    Inicio
;    ORG     0x04
;    goto    ServicioInterrupcion

Inicio
    BANKSEL OSCCAL                          ;Selecciona banco 1.
    call    0x3FF
    movwf   OSCCAL
    movlw   b'00001001'                     ;1 = entrada y 0 = salida.
    movwf   TRISIO
    bcf     OPTION_REG,NOT_GPPU             ;Activa Pull Up.
    movlw   b'00110111'                     ;Habilitar Pull Up.
    movwf   WPU
    BANKSEL CMCON                           ;Selecciona banco 0.
    movlw   b'00000111'                     ;Desactivar comparadores.
    movwf   CMCON
    clrf    GPIO                            ;Limpiar.

Principal
;   |GP1 GP2 GP4 GP5
;---+----------------
;1) | 0   1   0   0
;2) | 1   0   1   0
;3) | 0   1   1   0
;4) | 1   0   0   1

    btfsc    Pulsador            ; ¿Pulsador presionado?, ¿(Pulsador)=0?
    goto    Fin                    ; No. Vuelve a leerlo.
    call    Retardo_20ms        ; Espera que se estabilicen los niveles de tensión.
    btfsc    Pulsador            ; Comprueba si es un rebote.
    goto    Fin                    ; Era un rebote y sale fuera.
    btfsc    Led1                ; Testea el último estado del LED.
     goto    EstabaEncendido
EstabaApagado
    bsf        Led1                ; Estaba apagado y lo enciende.
    goto    EsperaDejePulsar
EstabaEncendido
    bcf        Led1                ; Estaba encendido y lo apaga.
EsperaDejePulsar
    btfss    Pulsador            ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar    ; No. Espera que deje de pulsar.
Fin
    goto    Principal

    INCLUDE  <RETARDOS.inc>

    ORG     0x3FF
    retlw   b'11111111'
    END
Algo no anda bie, si no me enciende el led y apagarlo, no me sale algo bien. En el MPLAB X 1.60 me funciona de maravilla con el ejemplo de arriba, si lo prueba con Proteus 7.10 SP0, nada de nada.

Otra cosa:
Para los que usan el PIC12F629. Quiero saber si alguien del foro puede leer este PIc virgen, mirar en la última dirección y decir qué valor tiene.

pic-555290.gif

Este ejemplo me viene el 3428. En realidad es sacado de un 12F675 en mi caso y quiero saber el de ustedes cual es su valor. Cuanta más personas me confirmen, mejor que mejor.

Saludo.
 
Última edición:
Meta, el pull-up es sólo para la entrada de pulsador. Ahora que has cambiado el esquema y el pulsador va en el GP0, el valor para WPU sería un 1 (00000001 binario).

Para las salidas da igual lo que configures en sus correspondientes pull-ups pero bueno, desde mi punto de vista está más bonito si sólo activas el pull-up de la pata GP0.
 
Algo no anda bien, si no me enciende el led y apagarlo, no me sale algo bien. En el MPLAB X 1.60 me funciona de maravilla con el ejemplo de arriba, si lo prueba con Proteus 7.10 SP0, nada de nada.
No te funciona en el simulador porqué dejaste sin conexión GP3/MCLR
GP0 en la entrada, GP3 no se usa y las demás son salidas del Led.
Mencionas que GP3 no se usa, sin embargo en tu código tienes configurado _MCLRE_ON
Así que cámbialo a OFF, coloca una Resistencia pull-up, o manda GP3 a VDD.

Cuando usas call 0x3FF, sirve para retornar en W el valor encontrado en esa dirección, y lo mueves a OSSCAL.
En esa dirección se encuentra el valor de calibración de fábrica del oscilador interno.
Si se sobre escribe esa locación, te retornará el valor escrito, que obviamente ya no servirá para OSCCAL.
Así que remueve la parte de tu código en donde tienes...
ORG 0x3FF
retlw b'11111111'
Ya que esa instrucción provocará un mal funcionamiento del oscilador interno.
Seguramente el valor 0xFF lo pusiste por la referencia de la hoja de datos, para máxima frecuencia.
Pero ese valor desconfigura la calibración del oscilador interno.
En el log de simulación de ISIS te mostrará esto...
Código:
[COLOR=Red][PIC12 LOAD] RETLW instruction for OSCCAL in last memory location (0x03FF) has been over-written with 0x34FF.[/COLOR]
Otra cosa:
Para los que usan el PIC12F629. Quiero saber si alguien del foro puede leer este PIC virgen, mirar en la última dirección y decir qué valor tiene.

Este ejemplo me viene el 3428. En realidad es sacado de un 12F675 en mi caso y quiero saber el de ustedes cual es su valor. Cuanta más personas me confirmen, mejor que mejor.
Ese valor cambia de PIC en PIC, por ejemplo, ahorita leí uno nuevo con el valor 0x3432
Donde 0x34 es un RETLW y 0x32 es el valor de calibración de fábrica para OSCCAL.
Así que al hacer call 0x3FF, W retorna con el valor 0x32 (En mi caso)

Saludos.
 
Hola:

Pues si @melghost, es mucho más bonito colocarlo como dices. :)
Código:
movlw   b'0000001'
movwf   WPU
Hola @d-rkbytes:
No encuentro para ver esto en el Proteus:
[PIC12 LOAD] RETLW instruction for OSCCAL in last memory location (0x03FF) has been over-written with 0x34FF.
He encontrado este enlace ahora, me ha ayudado entender algunas cosas.

Código hasta el momento.
Código:
;ZONA DE DATOS*****************************************************************
    LIST P=12F629 ; Procesador usado.
    INCLUDE <P12F629.INC> ; Fichero que definen las etiquetas.

    __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _FOSC_INTRCIO

    CBLOCK  0x20
    ENDC

#DEFINE Pulsador    GPIO,0        ; Pulsador conectado a RA4.
#DEFINE Led1        GPIO,1        ; Línea donde se conecta el diodo Led.
;#DEFINE Led2        GPIO,2
;#DEFINE Led3        GPIO,4
;#DEFINE Led4        GPIO,5

;ZONA DE CÓDIGOS***************************************************************
    ORG     0                               ; El programa comienza en la dirección 0.
    goto    Inicio

Inicio
    BANKSEL OSCCAL                          ;Selecciona banco 1.
    call    0x3FF
    movwf   OSCCAL
    movlw   b'00001001'                     ;1 = entrada y 0 = salida.
    movwf   TRISIO
    movlw   b'00001111'
    movwf   OPTION_REG                      ;Activa Pull Up.
    movlw   b'0000001'
    movwf   WPU                             ; Activada Pull Up del GP0.
;    bsf   WPU,WPU0
    BANKSEL CMCON                           ;Selecciona banco 0.
    movlw   b'00000111'                     ;Desactivar comparadores.
    movwf   CMCON

Principal
;GP0|GP1 GP2 GP4 GP5
;---+----------------
;1) | 0   1   0   0
;2) | 1   0   1   0
;3) | 0   1   1   0
;4) | 1   0   0   1

    btfsc    Pulsador            ; ¿Pulsador presionado?, ¿(Pulsador)=0?
    goto    Fin                    ; No. Vuelve a leerlo.
    call    Retardo_20ms        ; Espera que se estabilicen los niveles de tensión.
    btfsc    Pulsador            ; Comprueba si es un rebote.
    goto    Fin                    ; Era un rebote y sale fuera.
    btfsc    Led1                ; Testea el último estado del LED.
     goto    EstabaEncendido
EstabaApagado
    bsf        Led1                ; Estaba apagado y lo enciende.
    goto    EsperaDejePulsar
EstabaEncendido
    bcf        Led1                ; Estaba encendido y lo apaga.
EsperaDejePulsar
    btfss    Pulsador            ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar    ; No. Espera que deje de pulsar.
Fin
    goto    Principal

    INCLUDE  <RETARDOS.inc>

    ORG     0x3FF
    retlw   0x20
    END
Me funciona en el simulador el PIC, hay algo que no entiendo.
¿Por qué se queda encendido el GP5 apague o encienda el GP1?

pic-555290.gif

Me están ayuydando a enteder este PIC. Muchísimas gracias el apoyo. He sufrido más entender el 12F que un 16F eincluso un 18F en asm.
 
Hombre, no sabría decirte por qué está encendido el GP5; probablemente tu simulador no asume que tenga que comenzar apagado, y dado que no lo inicializas en ningún momento, puede ser que sólo por eso coincida que se ha quedado encendido.

Lo que sí está claro es que en tu programa no le pides que se apague. Cuando enciendes el GP1 lo haces con la instrucción BSF (o sea, poner a 1 un bit concreto). Esa instrucción no afecta a los demás bits del registro. Por tanto, si el bit 5 estaba a 1, se quedará a 1.

Y para apagar, lo mismo. Lo haces con BCF (poner a 0 un bit concreto). Los demás bits del registro quedan inalterados.
 
Buenas:

Ahora le puse este trozo de código clrf GPIO.

Código:
Inicio
    BANKSEL OSCCAL                          ;Selecciona banco 1.
    call    0x3FF
    movwf   OSCCAL
    movlw   b'00001001'                     ;1 = entrada y 0 = salida.
    movwf   TRISIO
    movlw   b'00001111'
    movwf   OPTION_REG                      ;Activa Pull Up.
    movlw   b'0000001'
    movwf   WPU                             ; Activada Pull Up del GP0.
    BANKSEL CMCON                           ;Selecciona banco 0.
    movlw   b'00000111'                     ;Desactivar comparadores.
    movwf   CMCON
    clrf    GPIO
No se si es el adecuado para ponerlo ahí. Porque tengo intensión de guardar la configuración de salida o de los Leds en la EEPROM interna del PIC12F629.

Sospecho que se me apagarán los Leds al iniciar el PIC aunque cargue la configuración de la EEPROM al final.

¿Es cierto?

Así que debo hacer algo para evitarlo.
 
Pero los LEDs estarán apagados cuando esté apagado el PIC. Desde que enciendes el PIC hasta que se encienden los LEDs correspondientes tendrás un pequeño retardo correspondiente al tiempo de reset interno del PIC, pero es un tiempo insignificante. No entiendo muy bien qué importancia tiene ese tiempo de LEDs apagados.
 
No encuentro para ver esto en el Proteus:
[PIC12 LOAD] RETLW instruction for OSCCAL in last memory location (0x03FF) has been over-written with 0x34FF.
Para ver el log de la simulación dale un click al recuadro de mensajes.
Este recuadro se encuentra a la derecha de los botones Play, Step, Pause y Stop, hasta abajo de la ventana.
Con un solo click aparece la ventana Simulation Log

Esta opción también aparece en el menú Debug, únicamente cuando sé está en tiempo de ejecución.
 
Gracias por la aclaración.

Quiero dar el siguiente paso, hacer funcionar la tabla de abajo.

;GP2|GP0 GP1 GP4 GP5
;---+----------------
;1) | 0 1 0 0
;2) | 1 0 1 0
;3) | 0 1 1 0
;4) | 1 0 0 1

¿Cómo hago los pasos a seguir de un pulsador para tener sus correspondientes salidas?

Esto no es tan fácil.

Pensé un usar la RAM llamándola FlagsModos (Modos de banderas) para detectar en qué nivel está realmente la configuración de salidad de los Leds. Dejo claro en este momento usar el GP2 como entrada y las demás como salida de Led e ignorando el GP3, aunque está configurada como entrada.

Vi en el datasheet que GP2 hace de servicio de interrupción externa detectando flanco, así que me parece buena idea.

Por lo que he hecho hasta ahora, me sale el Modo2 cuando tiene que empezar desde el Modo1 en el Proteus.

En cuanto al MPLAB X 1.60, me va de maravilla.

Código:
;-(FlagsModos)=b'00000001'. Está en el modo "Modo1".
;-(FlagsModos)=b'00000010'. Está en el modo "Modo2".
;-(FlagsModos)=b'00000100'. Está en el modo "Modo3".
;-(FlagsModos)=b'00001000'. Está en el modo "Modo4".
;
;
;GP2|GP0 GP1 GP4 GP5
;---+----------------
;1) | 0   1   0   0
;2) | 1   0   1   0
;3) | 0   1   1   0
;4) | 1   0   0   1
;
;ZONA DE DATOS*****************************************************************
    LIST P=12F629                          ;Procesador usado.
    INCLUDE <P12F629.INC>                  ;Fichero que definen las etiquetas.

    __CONFIG   _CP_ON & _CPD_ON & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _FOSC_INTRCIO

    CBLOCK  0x20
    FlagsModos
    ENDC

#DEFINE ModoPulsador    GPIO,2              ; ModoPulsador conectado a RA4.
#DEFINE Led1            GPIO,0              ; Línea donde se conecta el diodo Led.
#DEFINE Led2            GPIO,1
#DEFINE Led3            GPIO,4
#DEFINE Led4            GPIO,5
#DEFINE Modo4           FlagsModos,3
#DEFINE Modo3           FlagsModos,2
#DEFINE Modo2           FlagsModos,1
#DEFINE Modo1           FlagsModos,0

;ZONA DE CÓDIGOS***************************************************************
    ORG     0                   ;El programa comienza en la dirección 0.
    goto    Inicio

    ORG     0x04
    goto    ServicioInterrupcion

Inicio
    BANKSEL OSCCAL              ;Selecciona banco 1.
    call    0x3FF
    movwf   OSCCAL
    bsf     ModoPulsador        ;Pulsador como entrada.
    bcf     Led1                ;Led se configura como
    bcf     Led2                ;salidas.
    bcf     Led3
    bcf     Led4
    movlw   b'00001111'
    movwf   OPTION_REG          ;Activa Pull Up.
    movlw   b'0000001'
    movwf   WPU                 ;Activada Pull Up del GP0.
    BANKSEL CMCON               ;Selecciona banco 0.
    movlw   b'00000111'         ;Desactivar comparadores.
    movwf   CMCON
    movlw   b'10010000'         ;Activa la interrupción extena(INTE) y
    movwf   INTCON              ;la general (GIE).
    bsf     STATUS,C

;La sección "Principal" es mantenimiento. Sólo espera las interrupciones.

Principal
    goto    Principal

;Subrutina "ServicioInterrupcion" *********************************************
ServicioInterrupcion
    btfss   ModoPulsador        ;¿Estás presionando el pulsador "ModoPulsador"?
    call    CambiarModo
FinInterrupcion
    bcf     INTCON,INTF
    retfie

;Subrutina "CambiarModo" ******************************************************

CambiarModo
;    call    Retardo_20ms        ;Espera a que se estabilicen niveles de tensión.
    btfsc   ModoPulsador        ;Si es un rebote, sale fuera.
    goto    FinCambiarModo
    btfss   Modo4               ;Detecta si está en el último modo.
    goto    ModoSiguiente       ;Si no, pasa al modo siguiente.
Modo1_Principal
    movlw   b'00000001'         ;Actualiza el registro FlagsModos pasando al
    movwf   FlagsModos          ;modo inicial "Modo1" o el primer juego.
    goto    FinCambiarModo
ModoSiguiente                   ;Desplaza un "1" a la izquierda del registro
    rlf     FlagsModos,F        ;FlagsModos para ajustar secuencialmente
    bcf     STATUS,C            ;cada uno de los modos de funcionamiento.

FinCambiarModo
    btfsc   ModoPulsador        ;Ahora a esperar que dejes de pulsar.
    goto    FinCambiarModo
    btfsc   Modo1
    goto    ROM1
    btfsc   Modo2
    goto    ROM2
    btfsc   Modo3
    goto    ROM3
    btfsc   Modo4
    goto    ROM4
ROM1
    bcf     Led1
    bsf     Led2
    bcf     Led3
    bcf     Led4
    goto Retorno
ROM2
    bsf     Led1
    bcf     Led2
    bsf     Led3
    bcf     Led4
    goto Retorno
ROM3
    bcf     Led1
    bsf     Led2
    bsf     Led3
    bcf     Led4
    goto Retorno
ROM4
    bsf     Led1
    bcf     Led2
    bcf     Led3
    bsf     Led4
Retorno
    return

    INCLUDE  <RETARDOS.inc>

    ORG     0x3FF
    retlw   0x20
    END
Abajo puedes descargar el hex junto con el archivo de Proteus 7.10 SP0.

Si alguien se atreve ser capaz de probarlo en una protoboard, que saquen foto y comenten si realmente les funciona.

Saludo.
 

Adjuntos

  • Proteus y hexv01.zip
    14 KB · Visitas: 10
Última edición:
Al final lo medio hice, ajajjaja. :)
Con vuestras pistas y sugerencias.

Me falta dos cosas que no me sale.

En el Proteus me funciona como dije antes, primero el Modo2 cuando tiene que ser el Modo1. En los MPLAB v8 y MPLAB X funciona como debe ser. No entiendo nada, haber si hay alguien que lo haga realidad.

Ahora voy a probar con la EEPROM interna del PIC si puedo almacenar información y luego leerla.

Quiero hacer que cuando pulse un botón y deje unos de los 4 modos que hay en sus 4 salidas de Leds, al apagar el PIC, lo vuelva a encender recupere los datos almacenados. Se guardaré, me imagino en el momento de pulsar dicho botón.

Ya les comentaré.
 
Por ahora no me sale las cosas. A pesar quehe puesto los códigos en subrutinas de lectura y escritura del PIC.

Código completo del programa.

Código:
;-(FlagsModos)=b'00000001'. Está en el modo "Modo1".
;-(FlagsModos)=b'00000010'. Está en el modo "Modo2".
;-(FlagsModos)=b'00000100'. Está en el modo "Modo3".
;-(FlagsModos)=b'00001000'. Está en el modo "Modo4".
;
;
;GP2|GP0 GP1 GP4 GP5
;---+----------------
;1) | 0   1   0   0
;2) | 1   0   1   0
;3) | 0   1   1   0
;4) | 1   0   0   1
;
;ZONA DE DATOS*****************************************************************
    LIST P=12F629                          ;Procesador usado.
    INCLUDE <P12F629.INC>                  ;Fichero que definen las etiquetas.

    __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _FOSC_INTRCIO

    CBLOCK  0x20
    FlagsModos
    GuardarConfig
    ENDC

    ORG     0x2100
    DE      b'00000010'

#DEFINE ModoPulsador    GPIO,2              ; ModoPulsador conectado a RA4.
#DEFINE Led1            GPIO,0              ; Línea donde se conecta el diodo Led.
#DEFINE Led2            GPIO,1
#DEFINE Led3            GPIO,4
#DEFINE Led4            GPIO,5
#DEFINE Modo4           FlagsModos,3
#DEFINE Modo3           FlagsModos,2
#DEFINE Modo2           FlagsModos,1
#DEFINE Modo1           FlagsModos,0

;ZONA DE CÓDIGOS***************************************************************
    ORG     0                   ;El programa comienza en la dirección 0.
    goto    Inicio

    ORG     0x04
    goto    ServicioInterrupcion

Inicio
    clrw
    call    EEPROM_LeeDato
    movwf   GuardarConfig
    BANKSEL OSCCAL              ;Selecciona banco 1.
    call    0x3FF
    movwf   OSCCAL
    bsf     ModoPulsador        ;Pulsador como entrada.
    bcf     Led1                ;Led se configura como
    bcf     Led2                ;salidas.
    bcf     Led3
    bcf     Led4
    movlw   b'00001111'
    movwf   OPTION_REG          ;Activa Pull Up.
    movlw   b'0000001'
    movwf   WPU                 ;Activada Pull Up del GP0.
    BANKSEL CMCON               ;Selecciona banco 0.
    movlw   b'00000111'         ;Desactivar comparadores.
    movwf   CMCON
    movlw   b'10010000'         ;Activa la interrupción extena(INTE) y
    movwf   INTCON              ;la general (GIE).
    bsf     STATUS,C

;La sección "Principal" es mantenimiento. Sólo espera las interrupciones.

Principal
    goto    Principal

;Subrutina "ServicioInterrupcion" *********************************************
ServicioInterrupcion
    btfss   ModoPulsador        ;¿Estás presionando el pulsador "ModoPulsador"?
    call    CambiarModo
FinInterrupcion
    bcf     INTCON,INTF
    retfie

;Subrutina "CambiarModo" ******************************************************

CambiarModo
;    call    Retardo_20ms        ;Espera a que se estabilicen niveles de tensión.
    btfsc   ModoPulsador        ;Si es un rebote, sale fuera.
    goto    FinCambiarModo
    btfss   Modo4               ;Detecta si está en el último modo.
    goto    ModoSiguiente       ;Si no, pasa al modo siguiente.
Modo1_Principal
    movlw   b'00000001'         ;Actualiza el registro FlagsModos pasando al
    movwf   FlagsModos          ;modo inicial "Modo1" o el primer juego.
    goto    FinCambiarModo
ModoSiguiente                   ;Desplaza un "1" a la izquierda del registro
    rlf     FlagsModos,F        ;FlagsModos para ajustar secuencialmente
    bcf     STATUS,C            ;cada uno de los modos de funcionamiento.

FinCambiarModo
    btfsc   ModoPulsador        ;Ahora a esperar que dejes de pulsar.
    goto    FinCambiarModo
    btfsc   Modo1
    goto    ROM1
    btfsc   Modo2
    goto    ROM2
    btfsc   Modo3
    goto    ROM3
    btfsc   Modo4
    goto    ROM4
ROM1
    bcf     Led1
    bsf     Led2
    bcf     Led3
    bcf     Led4
    goto Retorno
ROM2
    bsf     Led1
    bcf     Led2
    bsf     Led3
    bcf     Led4
    goto Retorno
ROM3
    bcf     Led1
    bsf     Led2
    bsf     Led3
    bcf     Led4
    goto Retorno
ROM4
    bsf     Led1
    bcf     Led2
    bcf     Led3
    bsf     Led4
Retorno
    return

;Subrutinas EEPROM ************************************************************
EEPROM_LeeDato
    bsf     STATUS,RP0      ;Selecciona banco 1.
    movlw   CONFIG_ADDR     ;<<<------------------- ¿Esto para qué es?
    movwf   EEADR           ;Dirección a leer.
    bsf     EECON1,RD       ;Leer EEPROM.
    movf    EEDATA,W        ;Mover dato a W.
    return

EEPROM_EscribeDato
    bsf     STATUS,RP0      ;Selecciona el banco 1.
    bsf     EECON1,WREN     ;Habilita escritura.
    bcf     INTCON,GIE      ;Deshabilita interrupciones.
    movlw   0x55            ;Lo recomienda Microhip hasta...
    movwf   EECON2
    movlw   0xAA
    movwf   EECON2
    bsf     EECON1,WR       ;...aquí. Empieza la escritura.
    bsf     INTCON,GIE      ;Habilita las interrupciones.
    bcf     STATUS,RP0
    return

    INCLUDE  <RETARDOS.inc>

    ORG     0x3FF
    retlw   0x20
    END

Algo no tengo bien hecho, tampoco acabao. Haga o que haga, hace cosas raras.

La idea es:
Quiero hacer esta tabla aquí ababjo.
;GP2|GP0 GP1 GP4 GP5
;---+----------------
;1) | 0 1 0 0
;2) | 1 0 1 0
;3) | 0 1 1 0
;4) | 1 0 0 1

En la EEPROM interna del PIC12F629 he grabado en la dirección 0x00 el valor del paso 1) b'00000100'. Hasta aquí todo bien.

El problema es grabar los demás pasos y leerlo.

Consciste en que se grabe los pasos en la EEPROM en la dirección 0x00 o el que sea al pulsar el botín GP2.

Vamos a suponer que estamos en el paso 3) y se guardó en la EEPROM b'00001001', apagamos el PIC. Luego lo volvemos a enchufar. Lo primero que tiene que hacer el PIC es leer que tiene en la EEPROM.

Saludo.
 
Atrás
Arriba