Modificar este código a algo más complejo

Iniciado por Meta, 3 Agosto 2014, 05:47 AM

0 Miembros y 3 Visitantes están viendo este tema.

Meta

#10
Hola:

Pensé que guardando el valor contador, es suficiente con solo un byte recordar las dos tablas donde van. Voy a examinarlo mejor tu código.

Le has puesto dos variables. ADDR y VALUE para guardar.

Saludo.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Meta

Hola:

Ahora me funciona todo.

Código (asm) [Seleccionar]
;
; Un pulsador en RA4 va incrementando un Contador, entre [1-4].
; La salida se envía a un display de 7 seg. en PORTB, y hacia salidas en PORTA.
; El Contador queda guardado en la EEPROM.
;
; (Contador)  |RB 76543210 |RA 76543210
; ------------|------------------------
;       1     |   00000011 |   00000010
;       2     |   00100100 |   00000101
;       3     |   00001100 |   00000110
;       4     |   00111100 |   00001001
;
; PORTA:
;  RA0 : OE1
;  RA1 : OE2
;  RA2 : A21
;  RA3 : AUX
;  RA4 : Pulsador
;
; PORTB : display de 7 segmentos. a = RB0
;

;*******************************************************************************
; Listado y condiciones de ensamblado

    LIST    P=16F88           ; 4 Mhz
    INCLUDE <P16F88.INC>
    ;radix       hex
    ERRORLEVEL  -302            ; Turn off banking message

;*******************************************************************************
; Fusibles

    __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO

; _CP_OFF           : Protección de código
; _DEBUG_OFF        : Debug en circuito
; _WRT_PROTECT_OFF  : Protección a escritura en memoria de programa
; _CPD_OFF          : Protección de código de datos
; _LVP_OFF          : Programación en baja tensión
; _BODEN_OFF        : Reset por Brown-out
; _MCLRE_ON         : Reset por pin externo
; _PWRTE_ON         : Retraso al reset
; _WDT_OFF          : Watchdog
; _XT_OSC           : Oscilador externo del tipo XT


;*******************************************************************************
; Definiciones

; Máscaras de E/S de los puertos. 0 = salida, 1 = entrada
;                    |76543210|
#DEFINE PUERTO_A    b'00010000'
#DEFINE PUERTO_B    b'00000000'

; Incorporar sentencias de comprobación de la EEPROM
#DEFINE test_eeprom 0

;*******************************************************************************
; Variables
Variables   UDATA_SHR
Contador    RES 1                   ; Contador en la SRAM

; ******************************************************************************
; EEPROM

; Dirección del Contador dentro de la EEPROM
EE_Contador EQU 0x02

; Debemos desplazarnos a la zona de memoria más allá del 0x2100, que corresponde
; a la zona de la EEPROM en la mayoría de los PIC (ver documentación).
; Este valor es el que se grabará en la EEPROM en el momento de grabar el programa
; en el µcontrolador.
    ORG     0x2100 + EE_Contador
    DE      0x01                               ; valor inicial de ee_Contador

;*******************************************************************************

    ORG    0x0000

Inicio
    banksel ANSEL           ; bank 1
    clrf    ANSEL           ; puerto A digital
    movlw   PUERTO_A        ; definir E/S puerto A
    movwf   TRISA
    movlw   PUERTO_B        ; definir E/S puerto B
    movwf   TRISB
    movlw   b'01100000'     ; 4 MHz
    movwf   OSCCON
    call    EEPROM_LeeDato


#if test_eeprom
; Comprobar que el Contador es correcto (esta parte es opcional)
    decf    Contador, w     ; leemos el Contador y le quitamos 1
    andlw   0x3             ; nos quedamos solo con los bits inferiores
    addlw   0x1             ; volvemos a sumarle 1
    movwf   Contador        ; y lo guardamos
#endif
    goto    Visualiza       ; ir a presentar

; Bucle principal
Principal
    btfsc   PORTA, RA4      ; leer pulsador
    goto    Principal       ; No, esperar
;
; Se ha pulsado el botón
    call    incrementa_Contador
Visualiza
    call    visualiza_Contador
    call    salida_hacia_A

; Esperar liberación del botón
Espera_levantar
    call    Retardo_100ms   ; Esperar la suelta del botón

    btfss   PORTA, RA4      ; leer pulsador
    goto    Espera_levantar ; No, esperar

; Repetir
    goto    Principal


; ******************************************************************************
;; salida_hacia_A
;
; Según el valor del Contador ([1-4]), lo transforma en otro, basado en una
; tabla y lo saca por el puerto A
;

salida_hacia_A
    call    transforma_Contador
    movwf   PORTA           ; visualiza en puerto A
    return

transforma_Contador
    decf    Contador, w     ; leemos el Contador y le restamos 1
    addwf   PCL, f          ; saltamos dentro de la tabla

    ;                            |76543210|
    retlw   b'00000010'
    retlw   b'00000101'
    retlw   b'00000110'
    retlw   b'00001001'

; ******************************************************************************
;; incrementa_Contador
;
; Incrementa el valor de la variable Contador, entre 1 y 4, inclusives.
;

incrementa_Contador
    bcf     Contador, 2     ; Si el Contador valía 4, ahora vale 0
    incf    Contador, f     ; Incrementa el Contador
    call    EEPROM_EscribeDato

; ******************************************************************************
;; visualiza_Contador
;
; Muestra el valor del Contador en el display de 7 segmentos
;

visualiza_Contador
    movfw   Contador        ; leemos Contador
    call    w_a_digito      ; transformación a dígito 7 segmentos
    movwf   PORTB           ; visualiza en puerto B
    return

w_a_digito         addwf   PCL, f          ; salta al dígito indexado por w

;            |76543210|
    retlw   b'00111111'     ; 0
    retlw   b'00000110'     ; 1
    retlw   b'01011011'     ; 2
    retlw   b'01001111'     ; 3
    retlw   b'01100110'     ; 4
    retlw   b'01101101'     ; 5
    retlw   b'01111101'     ; 6
    retlw   b'00000111'     ; 7
    retlw   b'01111111'     ; 8
    retlw   b'01101111'     ; 9

; ----------------------------------------------------------------------------------------------------
; Espera = 100ms
; Frecuencia de reloj = 4Mhz
;
; Espera real = 0.1 segundos = 100000 ciclos
; Error = 0.00 %

Retardo_var        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1

Retardo_code       code

Retardo_100ms
;99993 cycles
movlw 0x1E
movwf Retardo_100ms_d1
movlw 0x4F
movwf Retardo_100ms_d2
Retardo_100ms_0
decfsz Retardo_100ms_d1, f
goto $+2
decfsz Retardo_100ms_d2, f
goto Retardo_100ms_0

;3 cycles
goto $+1
nop

;4 cycles (including call)
return

; ******************************************************************************

; Leer valor del Contador en la EEPROM
EEPROM_LeeDato
    banksel EEADR           ; bank 2
    movlw   EE_Contador     ; dirección de la EEPROM a leer
    movwf   EEADR

    banksel EECON1          ; bank 3
    bcf     EECON1, EEPGD   ; acceso a la memoria de datos
    bsf     EECON1, RD      ; inicia la lectura

    banksel EEDATA          ; bank 2
    movf    EEDATA, w       ; dato leído en W
    movwf   Contador        ; guardar en SRAM
    ;
    banksel PORTA           ; bank 0, durante el programa
    return

; Escribe el Contador en la EEPROM
EEPROM_EscribeDato
    banksel EECON1          ; bank 3
    btfsc   EECON1, WR      ; esperar para poder escribir
    goto    $-1

    banksel EEADR           ; bank 2
    movlw   EE_Contador     ; dirección donde vamos a escribir
    movwf   EEADR

    movf    Contador, w     ; el valor que vamos a escribir
    movwf   EEDATA

    banksel EECON1          ; bank 3
    bcf     EECON1, EEPGD   ; acceso a la memoria de datos
    bsf     EECON1, WREN    ; activa la escritura

    ;                    bcf     INTCON, GIE     ; desactivar interrupciones

    movlw   b'01010101'     ; valores mágicos (requeridos)
    movwf   EECON2
    movlw   b'10101010'
    movwf   EECON2

    bsf     EECON1, WR      ; comienza la escritura

    ;                    bsf     INTCON, GIE     ; reactiva interrupciones

    bcf     EECON1, WREN    ; desactiva escrituras

    banksel PORTA           ; volvemos a bank 0
    return
                    END




Gracias por tu tiempo.  :D
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Meta

Buenas:

Voy hacerles una pregunta. Sobre el código de arriba quiero hacer algo parecido del PIC16F88 al PIC16F630 para saber si realmente funciona. Hablo de adaptación del código y usando un decodificador 74LS48.

Transformar este esquema...


Con este otro.

Habiendo el primer circuito con menos componentes. ¿Por qué usar el segundo esquema también?

Porque otras personas que quieren montar el circuito no pueden debido a que su local de electrónica favorita no tienen el PIC16F88 y si el PIC16F630 junto con el decodificador de 7 segmentos 74LS48.

Partiendo del código de abajo del PIC16F88 para analizarlo bien.

; Un pulsador en RA4 va incrementando un Contador, entre [1-4].
; La salida se envía a un display de 7 seg. en PORTB, y hacia salidas en PORTA.
; El Contador queda guardado en la EEPROM.
;
; (Contador)  |RB 76543210 |RA 76543210
; ------------|------------------------
;       1     |   00000011 |   00000010
;       2     |   00100100 |   00000101
;       3     |   00001100 |   00000110
;       4     |   00111100 |   00001001
;
; PORTA:
;  RA0 : OE1
;  RA1 : OE2
;  RA2 : A21
;  RA3 : AUX
;  RA4 : Pulsador
;
; PORTB : display de 7 segmentos. a = RB0
;

;*******************************************************************************
; Listado y condiciones de ensamblado

    LIST    P=16F88           ; 4 Mhz
    INCLUDE <P16F88.INC>
    ;radix       hex
    ERRORLEVEL  -302            ; Turn off banking message

;*******************************************************************************
; Fusibles

    __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO

; _CP_OFF           : Protección de código
; _DEBUG_OFF        : Debug en circuito
; _WRT_PROTECT_OFF  : Protección a escritura en memoria de programa
; _CPD_OFF          : Protección de código de datos
; _LVP_OFF          : Programación en baja tensión
; _BODEN_OFF        : Reset por Brown-out
; _MCLRE_ON         : Reset por pin externo
; _PWRTE_ON         : Retraso al reset
; _WDT_OFF          : Watchdog
; _XT_OSC           : Oscilador externo del tipo XT


;*******************************************************************************
; Definiciones

; Máscaras de E/S de los puertos. 0 = salida, 1 = entrada
;                    |76543210|
#DEFINE PUERTO_A    b'00010000'
#DEFINE PUERTO_B    b'00000000'

; Incorporar sentencias de comprobación de la EEPROM
#DEFINE test_eeprom 0

;*******************************************************************************
; Variables
Variables   UDATA_SHR
Contador    RES 1                   ; Contador en la SRAM

; ******************************************************************************
; EEPROM

; Dirección del Contador dentro de la EEPROM
EE_Contador EQU 0x02

; Debemos desplazarnos a la zona de memoria más allá del 0x2100, que corresponde
; a la zona de la EEPROM en la mayoría de los PIC (ver documentación).
; Este valor es el que se grabará en la EEPROM en el momento de grabar el programa
; en el µcontrolador.
    ORG     0x2100 + EE_Contador
    DE      0x01                               ; valor inicial de ee_Contador

;*******************************************************************************

    CODE    0x0000

Inicio
    banksel ANSEL           ; bank 1
    clrf    ANSEL           ; puerto A digital
    movlw   PUERTO_A        ; definir E/S puerto A
    movwf   TRISA
    movlw   PUERTO_B        ; definir E/S puerto B
    movwf   TRISB
    movlw   b'01100000'     ; 4 MHz
    movwf   OSCCON
    call    EEPROM_LeeDato


#if test_eeprom
; Comprobar que el Contador es correcto (esta parte es opcional)
    decf    Contador, w     ; leemos el Contador y le quitamos 1
    andlw   0x3             ; nos quedamos solo con los bits inferiores
    addlw   0x1             ; volvemos a sumarle 1
    movwf   Contador        ; y lo guardamos
#endif
    goto    Visualiza       ; ir a presentar

; Bucle principal
Principal
    btfsc   PORTA, RA4      ; leer pulsador
    goto    Principal       ; No, esperar
;
; Se ha pulsado el botón
    call    incrementa_Contador
Visualiza
    call    visualiza_Contador
    call    salida_hacia_A

; Esperar liberación del botón
Espera_levantar
    call    Retardo_100ms   ; Esperar la suelta del botón

    btfss   PORTA, RA4      ; leer pulsador
    goto    Espera_levantar ; No, esperar

; Repetir
    goto    Principal


; ******************************************************************************
;; salida_hacia_A
;
; Según el valor del Contador ([1-4]), lo transforma en otro, basado en una
; tabla y lo saca por el puerto A
;

salida_hacia_A
    call    transforma_Contador
    movwf   PORTA           ; visualiza en puerto A
    return

transforma_Contador
    decf    Contador, w     ; leemos el Contador y le restamos 1
    addwf   PCL, f          ; saltamos dentro de la tabla

    ;                            |76543210|
    retlw   b'00000010'
    retlw   b'00000101'
    retlw   b'00000110'
    retlw   b'00001001'

; ******************************************************************************
;; incrementa_Contador
;
; Incrementa el valor de la variable Contador, entre 1 y 4, inclusives.
;

incrementa_Contador
    bcf     Contador, 2     ; Si el Contador valía 4, ahora vale 0
    incf    Contador, f     ; Incrementa el Contador
    call    EEPROM_EscribeDato

; ******************************************************************************
;; visualiza_Contador
;
; Muestra el valor del Contador en el display de 7 segmentos
;

visualiza_Contador
    movfw   Contador        ; leemos Contador
    call    w_a_digito      ; transformación a dígito 7 segmentos
    movwf   PORTB           ; visualiza en puerto B
    return

w_a_digito
    addwf   PCL, f          ; salta al dígito indexado por w

;            |76543210|
    retlw   b'00111111'     ; 0
    retlw   b'00000110'     ; 1
    retlw   b'01011011'     ; 2
    retlw   b'01001111'     ; 3
    retlw   b'01100110'     ; 4
    retlw   b'01101101'     ; 5
    retlw   b'01111101'     ; 6
    retlw   b'00000111'     ; 7
    retlw   b'01111111'     ; 8
    retlw   b'01101111'     ; 9

; ----------------------------------------------------------------------------------------------------

Retardo_var        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1

Retardo_code       code

Retardo_100ms
;99993 cycles
movlw 0x1E
movwf Retardo_100ms_d1
movlw 0x4F
movwf Retardo_100ms_d2
Retardo_100ms_0
decfsz Retardo_100ms_d1, f
goto $+2
decfsz Retardo_100ms_d2, f
goto Retardo_100ms_0

;3 cycles
goto $+1
nop

;4 cycles (including call)
return

; ******************************************************************************

; Leer valor del Contador en la EEPROM
EEPROM_LeeDato
    banksel EEADR           ; bank 2
    movlw   EE_Contador     ; dirección de la EEPROM a leer
    movwf   EEADR

    banksel EECON1          ; bank 3
    bcf     EECON1, EEPGD   ; acceso a la memoria de datos
    bsf     EECON1, RD      ; inicia la lectura

    banksel EEDATA          ; bank 2
    movf    EEDATA, w       ; dato leído en W
    movwf   Contador        ; guardar en SRAM
    ;
    banksel PORTA           ; bank 0, durante el programa
    return

; Escribe el Contador en la EEPROM
EEPROM_EscribeDato
    banksel EECON1          ; bank 3
    btfsc   EECON1, WR      ; esperar para poder escribir
    goto    $-1

    banksel EEADR           ; bank 2
    movlw   EE_Contador     ; dirección donde vamos a escribir
    movwf   EEADR

    movf    Contador, w     ; el valor que vamos a escribir
    movwf   EEDATA

    banksel EECON1          ; bank 3
    bcf     EECON1, EEPGD   ; acceso a la memoria de datos
    bsf     EECON1, WREN    ; activa la escritura

    ;                    bcf     INTCON, GIE     ; desactivar interrupciones

    movlw   b'01010101'     ; valores mágicos (requeridos)
    movwf   EECON2
    movlw   b'10101010'
    movwf   EECON2

    bsf     EECON1, WR      ; comienza la escritura

    ;                    bsf     INTCON, GIE     ; reactiva interrupciones

    bcf     EECON1, WREN    ; desactiva escrituras

    banksel PORTA           ; volvemos a bank 0
    return
    END


Antes de tocar algo.

¿Debo saber algo más?

Un saludo.

PD: Espero que no sea mucho de machacarte las neuronas por una adapación en asm.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/