Problema con codigo 12c509

Buenas tardes :)

Primero, decir que me estoy iniciando en esto del ensamblador y los pics, asique si veis alguna burrada es vil causa de la ignorancia...

Estoy practicando con un pic12c509a que ha caido en mis manos y desde el principio he tenido bastantes problemas (alguna instruccion diferente, registros distintos..)... en la red hay mucho del pic16 y muy poco del pic12, pero como soy un poco cabezota me he mamado el datasheet y he hecho lo que he podido...

Estoy usando MPLAB X y Proteus

El programa/circuito consta de dos partes:
La primera parte registra las pulsaciones de un pulsador y aumenta un contador que se resetea al pasar de 5. El programa comprueba el numero de pulsaciones y si es mayor de 5 , resta 5 para que coincida con el valor mostrado en el lcd7seg de pulsaciones (0-4).

-esta parte va bien-

La segunda parte deberia de, al pulsar un boton de "validacion", enviar un HIGH a traves de las 3 diferentes salidas segun la parte anterior. Para verificar esto, he conectado las 3 salidas a un deco 7seg y de este a otro lcd7seg, así , al "validar" se deberia mostrar un digito igual al mostrado en la primera parte.

- esta parte no me va bien-

El problema:
cuando selecciono el 0 y valido, muestra un 0
cuando selecciono el 1 y valido, muestra un 1 (exepto si mantengo pulsado el "validador" que me muestra un 1 que por un brevisimo instante se transforma en un 3)
cuando selecciono el 2,3 y 4 y valido, muestra un 1 (exepto si mantengo pulsado el "validador" que me muestra un 1 que por un brevisimo instante se transforma en un 3)
..edito... ahora muestra un 4 en los valores de 1,2,3 y 4 :confused:


Algunas cuestiones:
- He probado a crear tablas de mil formas diferentes, pero al simularlas en el proteus me dan "error violation acces..." o simplemente no funcionan
-Casi todo esta con goto's porque no entiendo muy bien el tema de los stacks? y siempre me daba error en cuanto ponia un call más
-He simulado "step by step" mil veces el programa en MPLAB, pero o no se, o no va :( buscar como cambian los registros GPIO y TRIS (el resto (W,Z, PC...)si que veo como cambian). Incluso he probado el Real Pic Simulator.. el caso es que en las tablas donde se muestran siempre me salen como 00000000.. no cambian

Las preguntas:
-¿Que error tengo en mi codigo?
-Como puedo mejorar lo que funciona?
-¿Puedo ver los valores de GPIO (si estan en 1 o 0) y TRIS (si estan como In o Out) y si es si, donde?

Código:
list p = 12C509A

    include <P12C509A.inc>
    __CONFIG _IntRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF ; desactivo el MCLR para poder usar  ese pin

    #define outdeco GPIO, 0 ;ahora GPIO-0 se llamara outdeco
    #define validator GPIO, 3 ; el boton de validacion se llamara validator
    #define inboton GPIO, 1 ; el boton selector se llamara inboton
    #define gp2 GPIO, 2 ; 2 , 3 y 4 son los pines de salida para el 7seg
    #define gp4 GPIO, 4
    #define gp5 GPIO, 5

ledcontador equ 07h ;declaracion de variables a usar
CounterA equ 08h ;variables para el delay
CounterB equ 09h
CounterC equ 0Ah


;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++       EMPIEZA                   ++++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 org 0x00 ; inicio del programa
 goto start ; saltamos a start

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++ TABLA PARA LOS NUMEROS   ++++++++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;no hay nada porque me daba error en el proteus

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
start ; Configuracion de I/O y clear de pines
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    movlw b'001010' ; carga el literal en W (1=ONLY IN 0=OUT)
    tris GPIO  ;y lo pasa al puerto GPIO configurando GP1 y GP3 como entradas
                ;y el resto como salidas
    clrf GPIO ;  asi tambien dejamos todos los bits de GPIO en low
    clrf ledcontador ; lo limpiamos porque aparecia un 255 en el File Register ?¿
                        ;al simularlo
    movlw b'11001000' ; 11 pullups y wakeon desactivadas, el otro 1 es para el wdt off
    OPTION ; si no meto esto no va bien (no tengo muy claro q este bien)

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
loop ;bucle de comprobacion del accionamiento del boton ++++++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


      btfsc inboton     ;Comprueba el bit 0 de GPIO (GP1) si esta 1 y si lo está salta linea
      goto sumayon
      btfss inboton     ;Comprueba que el bit 0 de GPIO (GP1) esta a 0 y si tal salta
      nop               ;sigue el programa
      btfsc validator   ;Comprueba q GP3 esta a 0 (boton SI presionado) y llama funcion
      goto callplay     ;Funcion callplay para iniciar juego seleccionado
      btfss validator   ;Si GP3 esta a 1 (boton SIN presionar) go loop
      nop               ; Una vez tenemos un numero de juego elegido lo activamos
     goto loop         ; el bucle se repite hasta que hay pulsaciones

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++     RUTINA DE SELECCION Y COMPROBACION    ++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


sumayon bsf outdeco ; Pone en SET outdeco (GP0) o sea mete un flanco de subida..
        call delay1sec ; espera 1 sec aprox
        call delay1sec
        bcf outdeco ; ..Pone en CLEAR outdeco (gp0) (termina el PULSO al CLK del contador)

        incf ledcontador, 1 ; +1 al contador de seleccion de juego y se almacena en El
        nop
                ; Snippet:  8-bit if (A >= 5) BUCLE QUE COMPRUEBA QUE LEDCONTADOR NO SEA
                ; MAYOR QUE 5, Y SI LO ES, LO RESTA PARA QUE CONCUERDE CON EL LED
                 movlw	5
                 subwf	ledcontador, W		; W = A-5
                 btfss	STATUS, C		; Check for borrow..
                 goto	loop	; SI es NO C=0, A<5, GOTO loop
                                ; SI es SI  RESTAMOS A LEDCONTADOR 5 Y SE LO REASIGNAMOS.
                 decf ledcontador,1
                 decf ledcontador,1
                 decf ledcontador,1
                 decf ledcontador,1
                 decf ledcontador,1
                 goto loop


;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++   RUTINA DE ACTIVACION JUEGO ELEGIDO  +++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
si0	movf	ledcontador, W
	subwf	b'00000000', W		; W =  B-A
	btfsc	STATUS, Z		; Check if zero..
	goto	sisi0
    goto    si1		; Z=0, A != B, result is si1
sisi0 movlw b'000000'
    movwf GPIO
    goto	loop
si1 bcf STATUS, Z
    movf	ledcontador, 0
	subwf	b'00000001', 0		; W =  B-A
	btfsc	STATUS, Z		; Check if zero..
	goto	sisi1
    goto   si2		; Z=0, A != B, result is sinoes
sisi1   bsf gp5
    bsf gp4
    bsf gp2
    goto	loop
si2 movf	ledcontador, 0
	subwf	b'00000010', 0		; W =  B-A
	btfsc	STATUS, Z		; Check if zero..
	goto sisi2
    goto	si3			; Z=0, A != B, result is sinoes
sisi2    bcf gp5
    bsf gp4
    bcf gp2
	goto	loop
si3 movf	ledcontador, W
	subwf	b'00000011', W		; W =  B-A
	btfsc	STATUS, Z		; Check if zero..
	goto sisi3
    goto	si4			; Z=0, A != B, result is sinoes
sisi3    bcf gp5
    bsf gp4
    bsf gp2
	goto	loop
si4 movf	ledcontador, W
	subwf	b'00000100', W		; W =  B-A
	btfsc	STATUS, Z		; Check if zero..
	goto	sinoes			; Z=0, A != B, result is sinoes
sisi4    bsf gp5
    bcf gp4
    bcf gp2
	goto	loop






;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++++++++++++++   RUTINA DE DELAY  +++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

delay1sec   movlw D'2'  ; OJO HE CAMBIADO EL 6 POR EL 2 (ya NO es 1 sec)
  movwf CounterC ; el 3er contador no lo usare, pero dejo q cargue el valor
  movlw D'24'
  movwf CounterB
  movlw D'168'
  movwf CounterA
looping
 decfsz CounterA,1
 goto looping
 decfsz CounterB,1
 goto looping
 decfsz CounterC,1 ; NO quito (SI modifico) el ultimo contador porque 1s es mucho
 goto looping
 return


 end

Muchas gracias por el interes :D



Esta es la tabla que me da error en Proteus de"internal exception: violation in module 'PIC12C5.DLL' [10008CAE]"
Código:
callplay
    addwf PCL         ;   GP5 GP4 GP2
    retlw b'00000000' ;0   0   0   0
    retlw b'00000100' ;1   0   0   1
    retlw b'00010000' ;2   0   1   0
    retlw b'00010100' ;3   0   1   1
    retlw b'00100000' ;4   1   0   0

 end
 

Adjuntos

  • CUENTAYVALIDA.jpg
    CUENTAYVALIDA.jpg
    80.4 KB · Visitas: 12
  • PIC12C509A_selector.rar
    20.2 KB · Visitas: 4
Última edición:
sigo dandole vueltas y la simulacion me falla en proteus y en el real pic simulator (error de out of code)....
he seguido investigando y he "descubierto" un nuevo factor: la calibracon del oscilador interno.... podria ir por ahi la cosa???:confused:
 
Despues de varios dias volviendome loco y revisando mucha documentacion y foros, como casi siempre la solucion era mas o menos "sencilla":

- el pin GP2 aun asignandole un OUT (salida) a traves de TRIS, se queda en alta impedancia pues el bit 5 (T0CS) de OPTION estando a 1 , tiene mas prioridad. Es decir, para que GP2 sea de salida, ese bit tiene que estar a 1.

- Ojo con MPLAB X, pues si elegimos en __CONFIG el oscilador interno, al generar el archivo, escribe una linea con RETLW que nos dara error en Proteus del tipo "stack underflow". Para evitarlo, tuve que generar el HEX con Proteus, desensamblarlo con PICDisasm y borrar esos RETLW. En Real Pic Simulator tendremos un error de "Out of Code"

-Ojo con las calibraciones del oscilador interno. En ningun caso (MPLAB X, Proteus y RealPicSimulator) y con ninguna combinacion de las vistas por los foros e incluso en la documentacion de Microchip he podido llevarla a cabo. Yo decidi, despues de muchisimas horas, pasar del tema.

-NO es lo mismo
;__CONFIG _OSC_IntRC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
__CONFIG _IntRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
, el primer CONFIG en Proteus y RealPicsimulator da error.

-Aunque se recomienda colocar las tablas al principio del programa para evitar errores con el PCL, yo tuve que ponerla al final, justo antes de la subrutina de "Delay", para evitar, de nuevo, en Proteus, errores de underflow.

-Esta solucion es valida para PIC12C508, PIC12C509, PIC12C508A, PIC12C509A, PIC12C609 y sus versiones reprogramables PIC12F508, PIC12F509 y PIC12F609, de los que por cierto, no he encontrado casi nada en la red....

-Bueno, y ya que estoy, compartire el codigo "bueno" por si alguien le apetece ahorrarse los 6 dias que he tardado en escribir el ******* programa :LOL:... Incluye algunas de las lines que me daban error (tienen un ; delante)

Código:
list p = 12C509A
    include <P12C509A.inc>

    ;__CONFIG _OSC_IntRC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
    __CONFIG _IntRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
    ;__CONFIG _OSC_ExtRC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
    ;__CONFIG _ExtRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF

    #define outdeco GPIO, 0 ;ahora GPIO-0 se llamara outdeco
    #define validator GPIO, 3 ; el boton de validacion se llamara validator
    #define inboton GPIO, 1 ; el boton selector se llamara inboton
    #define gp2 GPIO, 2 ; 2 , 3 y 4 son los pines de salida para el 7seg
    #define gp4 GPIO, 4
    #define gp5 GPIO, 5

    cblock 0x07
ledcontador  ;Declaracion de variables a usar
Delay_Count 
Delay_Count2
d1
d2
d3
     endc

;Inicio del programa++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     org 0x00 

                                             ;goto start ; saltamos a start
                                             ;org 0x04
                                             ;movlw 0x80
                                             ;MOVWF     OSCCAL

         movlw b'00000000' ; bit5(T0CS) en 0 para habilitar GP2
         OPTION


; Inicialización de puertos y variables ++++++++++++++++++++++++++++++++++++++++
start    movlw b'001010'  ;Carga el literal en W (1=ONLY IN 0=OUT)
         tris GPIO        ;GP1 y GP3 son entradas
         clrf GPIO        ; Inicializa GPIO y ledcontador
         clrf ledcontador 
         nop
        
; Comprobación de botones +++++++++++++++++++++++++++++++++++++++++++++++++++++
loop
        btfsc inboton ;Normalmente en SET esta GP1, si CLEAR => salta
        goto valida
        goto pulso
valida  btfsc validator ; NOrmalmente en SET esta GP3 , idem
        goto loop
        goto okgo
        goto loop

; Acción de PULSO en el boton selector de juego (GP1) ++++++++++++++++++++++++++
pulso   incf ledcontador,1 ;Manda un pulso por GP0
        bsf outdeco
        call delay
        bcf outdeco
        goto loop
; Acción de VALIDACIÓN en el boton de validación (GP3) +++++++++++++++++++++++++
okgo    movlw	5
        subwf	ledcontador, W	; W= a-5
        btfss	STATUS, C       ; Mira si ha habido acarreo
        goto	alcodigo        ; SI es NO C=0, A<5, GOTO loop
         decf ledcontador,1     ; SI es SI  RESTAMOS A LEDCONTADOR 5 Y SE LO REASIGNAMOS.
         decf ledcontador,1
         decf ledcontador,1
         decf ledcontador,1
         decf ledcontador,1
         goto alcodigo
alcodigo movf ledcontador, W
         call codificacion
         movwf GPIO
                                       
    goto loop
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;+++++++++++     TABLAS    +++++++++++++++++++++++++++++++++++++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

codificacion
    addwf PCL,F         ;   GP5 GP4 GP2
    retlw b'00000000' ;0   0   0   0
    retlw b'00000100' ;1   0   0   1
    retlw b'00010000' ;2   0   1   0
    retlw b'00010100' ;3   0   1   1
    retlw b'00100000' ;4   1   0   0
;++++++++++++++++++++++++++++++++++++++++++++++++++
;++++++++++    SUBRUTINAS  ++++++++++++++++++++++++
;++++++++++++++++++++++++++++++++++++++++++++++++++

delay ; SUBRUTINA de retardo (aprox. 1sec)
    movlw	d'3'  ;8 para 1 sec
	movwf	d1
	movlw	d'3' ;47 para 1 sec
	movwf	d2
	movlw	d'2' ;3 para 1 sec
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0
	goto	$+1
	return




     ;ORG          0x3FF ; ultima direccion del 509a donde esta el valor de calibraccion
     ;RETLW      0x80 ; valor q le ponemos

     end
 
Atrás
Arriba