Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

02/08/2014 #1

Avatar de Meta

Modificar este código a algo más complejo
Hola:

Siendo este código en asm para PIC16F84A, ya lo pasaré a PIC16F88.

Código:
; Implementar una tabla de la verdad mediante el manejo de tablas grabadas en ROM.
; Por ejemplo, la tabla será de 3 entradas y 6 salidas tal como la siguiente:
; 
;         C  B  A  | S5  S4  S3  S2  S1  S0
;         -----------|---------------------------
;         0   0   0   |   0    0    1    0    1    0    ; (Configuración 0).
;         0   0   1   |   0    0    1    0    0    1    ; (Configuración 1).
;         0   1   0   |   1    0    0    0    1    1    ; (Configuración 2).
;         0   1   1   |   0    0    1    1    1    1    ; (Configuración 3).
;         1   0   0   |   1    0    0    0    0    0    ; (Configuración 4).
;         1   0   1   |   0    0    0    1    1    1    ; (Configuración 5).
;         1   1   0   |   0    1    0    1    1    1    ; (Configuración 6).
;         1   1   1   |   1    1    1    1    1    1    ; (Configuración 7).
;
; Las entradas C, B, A se conectarán a las líneas del puerto A: RA2 (C), RA1 (B) y RA0 (A).
; Las salidas se obtienen en el puerto B:
; RB5 (S5), RB4 (S4), RB3 (S3), RB2 (S2), RB1 (S1) y RB0 (S0).
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0                    ; El programa comienza en la dirección 0.
Inicio
    bsf        STATUS,RP0            ; Acceso al Banco 1.
    clrf    TRISB                ; Las líneas del Puerto B se configuran como salida.
    movlw    b'00011111'            ; Las 5 líneas del Puerto A se configuran como entrada.
    movwf    TRISA
    bcf        STATUS,RP0            ; Acceso al Banco 0.
Principal
    movf    PORTA,W                ; Lee el valor de las variables de entrada.
    andlw    b'00000111'            ; Se queda con los tres bits de entrada.
    addwf    PCL,F                ; Salta a la configuración adecuada.
Tabla
    goto    Configuracion0
    goto    Configuracion1
    goto    Configuracion2
    goto    Configuracion3
    goto    Configuracion4
    goto    Configuracion5
    goto    Configuracion6
    goto    Configuracion7
Configuracion0
    movlw     b'00001010'            ; (Configuración 0).
    goto    ActivaSalida
Configuracion1
    movlw     b'00001001'            ; (Configuración 1).
    goto    ActivaSalida
Configuracion2
    movlw     b'00100011'            ; (Configuración 2).
    goto    ActivaSalida
Configuracion3
    movlw     b'00001111'            ; (Configuración 3).
    goto    ActivaSalida
Configuracion4
    movlw     b'00100000'            ; (Configuración 4).
    goto    ActivaSalida
Configuracion5
    movlw     b'00000111'            ; (Configuración 5).
    goto    ActivaSalida
Configuracion6
    movlw     b'00010111'            ; (Configuración 6).
    goto    ActivaSalida
Configuracion7
    movlw     b'00111111'            ; (Configuración 7).
ActivaSalida
    movwf    PORTB                ; Visualiza por el puerto de salida.
    goto     Principal

    END
Partiendo del código de arriba, quiero hacer una tabla de la verdad para un display de 7 segmentos y la otra tabla es para configuración a otra cosa. En dicho display debe contar del 1 al 4.

La idea consiste con un pulsador, incrementar las dos tablas de la verdad.

¿Esto es posible?

Si no entiendes, lo explico de otra manera.

Un saludo.
02/08/2014 #2

Avatar de cosmefulanito04

Usá vectores inicializados con el código en 7 segmentos, en assembler sería usar posiciones de memorias continuas, ejemplo:

Dir Base: 0b01111110 (el 0 en el display)
Dir Base + 1: 0b00110000 (el 1 en el display)
....
Dir Base + 9: 0b01111011 (el 9 en el display)

Entonces desde tú código, solo tenes que leer la posición de memoria acorde al número que necesitas leer:

Leo "Dir Base + 1" => obtengo el 7 segmentos del número 1.

Más detalles, acá tenés una explicación, pero en C:

Funciones varias para PIC en C.
03/08/2014 #3

Avatar de JoaquinFerrero

Lo mejor es usar una tabla de salto, muy típica de estos procesadores:
Código PHP:
;
Implementar una tabla de la verdad mediante el manejo de tablas grabadas en ROM.
;
Por ejemplola tabla será de 3 entradas y 6 salidas tal como la siguiente:
;
;   
C   B   A  |   S5   S4   S3   S2   S1   S0
;   -----------|------------------------------
;   
0   0   0  |   0    0    1    0    1    0    Configuración 0
;   0   0   1  |   0    0    1    0    0    1    Configuración 1
;   0   1   0  |   1    0    0    0    1    1    Configuración 2
;   0   1   1  |   0    0    1    1    1    1    Configuración 3
;   1   0   0  |   1    0    0    0    0    0    Configuración 4
;   1   0   1  |   0    0    0    1    1    1    Configuración 5
;   1   1   0  |   0    1    0    1    1    1    Configuración 6
;   1   1   1  |   1    1    1    1    1    1    Configuración 7
;
Las entradas CBA se conectarán a las líneas del puerto A:
;   
RA2 (C),
;   
RA1 (B), y
;   RA0 (A).
;
Las salidas se obtienen en el puerto B:
;   
RB5 (S5), RB4 (S4), RB3 (S3), RB2 (S2), RB1 (S1y RB0 (S0).
;

ZONA DE DATOS ****************************************************************

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

                processor   16F84A          
1 Mhz
                radix       dec
                errorlevel  
-302            Turn off banking message

;*******************************************************************************
Bibliotecas

                
include p16f84a.inc

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

                __CONFIG _CP_OFF 
&  _WDT_OFF _PWRTE_ON _XT_OSC


ZONA DE CÓDIGOS **************************************************************

                
ORG     0

Inicio
:
                
banksel TRISB           bank 1
                clrf    TRISB           
puerto B como salida

                movlw   
b'00011111'     puerto A como entrada
                movwf   TRISA

                banksel PORTA           
bank 0

Principal
:
                
movf    PORTAw        leer puerto
                andlw   
b'00000111'     nos quedamos sólo con las interesantes

                call    a_digito        
transformación a dígito

                movwf   PORTB           
visualiza
                
goto    Principal

; ******************************************************************************
;; 
a_digito
;
Conversión de un valor almacenado en w [0-7a un valor de tabla.
;

a_digito:       addwf   PCLf          salta al valor indexado por w

                retlw   
b'00001010'     Configuración 0
                retlw   
b'00001001'     Configuración 1
                retlw   
b'00100011'     Configuración 2
                retlw   
b'00001111'     Configuración 3
                retlw   
b'00100000'     Configuración 4
                retlw   
b'00000111'     Configuración 5
                retlw   
b'00010111'     Configuración 6
                retlw   
b'00111111'     Configuración 7

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

                
END 
03/08/2014 #4

Avatar de Meta

Buenas:

Con vuestras ideas he sacado otras ideas. Ahora estoy algo más cerca de lo que quiero. Les recuerdo que quiero un display de 7 segmentos, se mostrará los números 1,2,3 y 4. Usará solo un pulsador en el RA4. Si estás en el número 4, se pondrá el número 1 otra vez.

En la otra tabla de la verdad, he usado las instrucciones bcf y bsf para tenerlo más fácil. Son salidas de datos que de momento he puesto Led como muestra en el dibujo de abajo.

La parte que no me funciona es la del pulsador y necesito ayuda, es decir, que cada pulso que haga, cuente en el display un número tal como dije arriba. Ahora si que estoy perdido.





Código:
; Implementar una tabla de la verdad mediante el manejo de tablas grabadas en ROM.
; Por ejemplo, la tabla será de 1 pulsador y 8 salidas tal como la siguiente
; para el display de 7 segmentos y otras 4 salidas para datos.
; 
;       Pulsador RA4  |  RB7  RB6  RB5  RB4  RB3  RB2  RB1  RB0
;      ---------------|----------------------------------------
;               0   |   0    0    0    0    0    0    1    1    ; (Configuración 0).
;               1   |   0    0    1    0    0    1    0    0    ; (Configuración 1).
;               2   |   0    0    0    0    1    1    0    0    ; (Configuración 2).
;               3   |   0    0    1    1    1    1    0    0    ; (Configuración 3).

;
; La otra tabla para datos que usan los puertos A0, 1, 2 y 3.
; Hex    Dec    Datos    OE1    OE2    A21    AUX
;3    0    1    0    1    0    0
;5B    1    2    1    0    1    0
;4F    2    3    0    1    1    0
;66    3    4    1    0    0    1
; 
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

#DEFINE    OE1    PORTA,0
#DEFINE    OE2    PORTA,1
#DEFINE    A21    PORTA,2
#DEFINE    AUX    PORTA,3
#DEFINE    Pulsador    PORTA,4

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0        ; El programa comienza en la dirección 0.
Inicio
    bsf    STATUS,RP0    ; Acceso al Banco 1.
    clrf    TRISB     ; Las líneas del Puerto B se configuran como salida.
    bcf    OE1    ; PORTA,0 o OE1 como salida.
    bcf    OE2    ; PORTA,1 o OE2 como salida.
    bcf    A21    ; PORTA,2 o A21 como salida.
    bcf    AUX    ; PORTA,3 o AUX como salida.
    bsf    Pulsador    ; PORTA,4 o Pulsador como entrada.
    bcf    STATUS,RP0      ; Acceso al Banco 0.
Principal
    movf    PORTA,W         ; Lee el valor de las variables de entrada.
    andlw    b'00000111'     ; Se queda con los tres bits de entrada.
    addwf    PCL,F           ; Salta a la configuración adecuada.
Tabla
    goto    Configuracion0
    goto        Configuracion1
    goto        Configuracion2
    goto        Configuracion3
Configuracion0
    bcf    OE1
    bsf    OE2
    bcf    A21
    bcf    AUX
    movlw         b'00000011'            ; (Configuración 0).
    goto        ActivaSalida
Configuracion1
    bsf    OE1
    bcf    OE2
    bsf    A21
    bcf    AUX
    movlw         b'01011011'            ; (Configuración 1).
    goto        ActivaSalida
Configuracion2
    bcf    OE1
    bsf    OE2
    bsf    A21
    bcf    AUX
    movlw         b'01001111'            ; (Configuración 2).
    goto        ActivaSalida
Configuracion3
    bsf    OE1
    bcf    OE2
    bcf    A21
    bsf    AUX
    movlw         b'01100110'            ; (Configuración 3).
ActivaSalida
    movwf        PORTB                ; Visualiza por el puerto de salida.
    goto         Principal

    END
El que quiera el esquem ahecho con Proteus 7.10, se lo paso y hacen pruebas. Incluido asm y hex.

Un cordial saludo.
Imágenes Adjuntas
Tipo de Archivo: png Tabla-de-la-verdad.png (20,6 KB (Kilobytes), 105 visitas)
Tipo de Archivo: png PIC.png (9,3 KB (Kilobytes), 106 visitas)
03/08/2014 #5

Avatar de JoaquinFerrero

Debes hacer un bucle que quede leyendo RA4.

Si el valor es igual a 1, es que el pulsador no está activado, por lo que vuelve a repetir la lectura.

Si el valor es igual a 0, es que está pulsado.

Entonces, iniciamos un nuevo bucle, en donde primero esperamos una cantidad de tiempo (por ejemplo, 100 ms) y a continuación miramos el estado de RA4. Si el pulsador sigue pulsado, repetimos el bucle, y salimos si ya no lo está.

Y luego sigue el resto del programa.

Me parece que el uso de las instrucciones bsf y bcf... sí, son sencillas, pero alargan un poco, el programa. El uso de tablas retlw es lo propio, cuando queremos cambiar unos valores por otros.
03/08/2014 #6

Avatar de Meta

Hola de nuevo:

Hice el código desce cero, me funciona solo el Display de 7 seg. ya que me he metido ahí. Ahora me toca la otra tabla de la verdad, el de los datos.

Les vuelvo a subir la tabla de la verdad modificado algunos valores ya que la anterior tenía errores de configuración, ahora todo funciona bien del 1 al 4 y vuelve a contar de nuevo.



Nuevo código más sencillo.
Código:
; Cada vez que presione el pulsador conectado al pin RA4 incrementa un contador visualizado
; en el display.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    Contador                        ; El contador a visualizar.
    ENDC

#DEFINE    OE1    PORTA,0
#DEFINE    OE2    PORTA,1
#DEFINE    A21    PORTA,2
#DEFINE    AUX    PORTA,3    
#DEFINE     Pulsador    PORTA,4            ; Pulsador conectado a RA4.
#DEFINE     Display    PORTB            ; El display está conectado al Puerto B.

; ZONA DE CÓDIGOS ********************************************************************

    ORG    0                            ; El programa comienza en la dirección 0.
Inicio
      bsf    STATUS,RP0            ; Acceso al Banco 1.
    clrf    Display            ; Estas líneas configuradas como salidas.
    bcf    OE1
    bcf    OE2
    bcf    A21
    bcf    AUX
    bsf    Pulsador            ; Línea del pulsador configurada como entrada.
    bcf    STATUS,RP0            ; Acceso al Banco 0.
    call    InicializaContador        ; Inicializa el Contador y lo visualiza.
Principal
    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.
    call    IncrementaVisualiza        ; Incrementa el contador y lo visualiza.
EsperaDejePulsar
    btfss    Pulsador            ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar        ; No. Espera que deje de pulsar.
Fin    goto    Principal

; Subrutina "IncrementaVisualiza" ---------------------------------------------------------

IncrementaVisualiza
    incf    Contador,F            ; Incrementa el contador y comprueba si ha
    movlw     d'4'            ; llegado a su valor máximo mediante una
    subwf    Contador,W            ; resta. (W)=(Contador)-4.
    btfsc    STATUS,C            ; ¿C=0?, ¿(W) negativo?, ¿(Contador)<4?
InicializaContador
    clrf    Contador            ; No, era igual o mayor. Por tanto, resetea.
Visualiza
    movf    Contador,W
;    call    Numero_a_7Segmentos        ; Lo pasa a siete segmento para poder ser
    call    Tabla
    movwf    Display            ; visualizado en el display.
    return
Tabla
    addwf    PCL,F
    DT    06h, 5Bh, 4Fh, 66h        ; Números 1, 2, 3 y 4.


    INCLUDE <RETARDOS.INC>            ; Subrutinas de retardo.
    END                ; Fin del programa.
Ya que el código justo arriba funciona de maravilla, solo el display de 7 segmento del 1 al 4 y si sigues pulsando, vuelve al 1, como debe ser.

Falta la tabla de la verdad de datos de color verde como indica la imagen de arriba.

El problema es.

¿Cómo lo implemento como salidas y acorde al Display?

Saludo.
03/08/2014 #7

Avatar de JoaquinFerrero

Se pueden tener tantas tablas como quieras.

Esta es mi versión de tu programa. Por favor, fíjate en cómo hago para tener más de una tabla, y verás la cantidad de código que se puede ahorrar.
Código PHP:
;
Un pulsador en RA4 va incrementando un contadorentre [1-4].
La salida se envía a un display de 7 segen PORTBy hacia salidas en PORTA.
;
; (
Contador)  |RB 76543210 |RA 76543210
; ------------|------------------------
;       
1     |   00000110 |   00000010
;       2     |   01011011 |   00000101
;       3     |   01001111 |   00000110
;       4     |   01100110 |   00001001
;
PORTA:
;  
RA0 OE1
;  RA1 OE2
;  RA2 A21
;  RA3 AUX
;  RA4 Pulsador
PORTB display de 7 segmentosRB0
;

ZONA DE DATOS ****************************************************************

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

                    processor   16F84A          
4 Mhz
                    radix       dec
                    errorlevel  
-302            Turn off banking message

;*******************************************************************************
Bibliotecas

                    
include p16f84a.inc

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

                    __CONFIG _CP_OFF 
&  _WDT_OFF _PWRTE_ON _XT_OSC


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

Máscaras de E/S de los puertos
salidaentrada
;                    |76543210|
#define PORTA_ES    b'00010000'
#define PORTB_ES    b'00000000'

;*******************************************************************************
Variables
area_compartida
:    udata_shr

contador            res 1                       
Contador [1-4]


ZONA DE CÓDIGOS **************************************************************

programa:           code

                    ORG     000h

Inicio
:
                    
banksel TRISA           bank 1

                    movlw   PORTA_ES        
definir E/S puerto A
                    movwf   TRISA
                    movlw   PORTB_ES        
definir E/S puerto B
                    movwf   TRISB
;
                    
movlw   0               inicializamos contador
                    movwf   contador

                    banksel PORTA           
bank 0siempre
                    
goto    Bucle

Bucle principal
Principal
:
                    
movf    PORTAw        leer puerto A
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante

                    btfss   STATUS
Z       ¿Se ha pulsadoLo está si RA4 == 0
                    
goto    Principal       Noesperar
;
Aquí llegamos con el botón pulsado
Bucle
:
                    
call    incrementa_contador
                    call    visualiza_contador
                    call    salida_hacia_A

Esperamos que levante el botón
Espera_levantar
:
                    
call    Retardo_100ms   Esperar la suelta del pulsador
                    movf    PORTA
w        leer puerto A
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante
                    btfsc   STATUS
Z       ¿Sigue pulsadoLo está si RA4 == 0
                    
goto    Espera_levantar Noesperar
;
                    goto    
Principal


; ******************************************************************************
;; 
salida_hacia_A
;
Según el valor del contador ([1-4]), lo transforma en otrobasado 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 contadorentre 1 y 4inclusives.
;

incrementa_contador:
                    
bcf     contador2     Si el contador valía 4ahora vale 0
                    incf    contador
                    
return

; ******************************************************************************
;; 
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   PCLf          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_par:        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1


Retardo_code
:       code

Retardo_100ms
:
                                    ;
99993 ciclos
                    movlw   0x1E
                    movwf   Retardo_100ms_d1
                    movlw   0x4F
                    movwf   Retardo_100ms_d2

Retardo_100ms_loop
:
                    
decfsz  Retardo_100ms_d1f
                    
goto    $+2
                    decfsz  Retardo_100ms_d2
f
                    
goto    Retardo_100ms_loop

                                    
;3 ciclos
                    
goto    $+1
                    nop

                                    
;4 ciclos (incluyendo la llamada)
                    return

Generado por delay_pic.pl (Joaquín Ferrero2014.07.22)
; ./
delay_pic.pl -s Retardo_100ms 4Mhz 100ms
mar 22 jul 2014 19:22:23 CEST
http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------

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

                
END 
03/08/2014 #8

Avatar de Meta

JoaquinFerrero dijo: Ver Mensaje
Se pueden tener tantas tablas como quieras.

Esta es mi versión de tu programa. Por favor, fíjate en cómo hago para tener más de una tabla, y verás la cantidad de código que se puede ahorrar.
Código PHP:
;
Un pulsador en RA4 va incrementando un contadorentre [1-4].
La salida se envía a un display de 7 segen PORTBy hacia salidas en PORTA.
;
; (
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 segmentosRB0
;

ZONA DE DATOS ****************************************************************

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

                    processor   16F84A          
4 Mhz
                    radix       dec
                    errorlevel  
-302            Turn off banking message

;*******************************************************************************
Bibliotecas

                    
include p16f84a.inc

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

                    __CONFIG _CP_OFF 
&  _WDT_OFF _PWRTE_ON _XT_OSC


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

Máscaras de E/S de los puertos
salidaentrada
;                    |76543210|
#define PORTA_ES    b'00010000'
#define PORTB_ES    b'00000000'

;*******************************************************************************
Variables
area_compartida
:    udata_shr

contador            res 1                       
Contador [1-4]


ZONA DE CÓDIGOS **************************************************************

programa:           code

                    ORG     000h

Inicio
:
                    
banksel TRISA           bank 1

                    movlw   PORTA_ES        
definir E/S puerto A
                    movwf   TRISA
                    movlw   PORTB_ES        
definir E/S puerto B
                    movwf   TRISB
;
                    
movlw   0               inicializamos contador
                    movwf   contador

Bucle principal
                    banksel PORTA           
bank 0siempre
Principal
:
                    
movf    PORTAw        leer puerto A
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante

                    btfss   STATUS
Z       ¿Se ha pulsadoLo está si RA4 == 0
                    
goto    Principal       Noesperar
;
Aquí llegamos con el botón pulsado
                    call    incrementa_contador
                    call    visualiza_contador
                    call    salida_hacia_A

Esperamos que levante el botón
Espera_levantar
:
                    
call    Retardo_100ms   Esperar la suelta del pulsador
                    movf    PORTA
w        leer puerto A
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante
                    btfsc   STATUS
Z       ¿Sigue pulsadoLo está si RA4 == 0
                    
goto    Espera_levantar Noesperar
;
                    goto    
Principal


; ******************************************************************************
;; 
salida_hacia_A
;
Según el valor del contador ([1-4]), lo transforma en otrobasado 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 contadorentre 1 y 4inclusives.
;

incrementa_contador:
                    
incf    contador
                    decf    contador
,w      leemos el contadory le restamos 1

                    andlw   0x03            
nos quedamos con los bits más bajos
                    btfss   STATUS
Z       ¿es cero?
                    return                  ; 
aún nosalimos

                    movlw   1               
sí es cerohemos pasado de 4
                    movwf   contador        
lo pasamos a 1
                    
return

; ******************************************************************************
;; 
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   PCLf          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_par:        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1


Retardo_code
:       code

Retardo_100ms
:
                                    ;
99993 ciclos
                    movlw   0x1E
                    movwf   Retardo_100ms_d1
                    movlw   0x4F
                    movwf   Retardo_100ms_d2

Retardo_100ms_loop
:
                    
decfsz  Retardo_100ms_d1f
                    
goto    $+2
                    decfsz  Retardo_100ms_d2
f
                    
goto    Retardo_100ms_loop

                                    
;3 ciclos
                    
goto    $+1
                    nop

                                    
;4 ciclos (incluyendo la llamada)
                    return

Generado por delay_pic.pl (Joaquín Ferrero2014.07.22)
; ./
delay_pic.pl -s Retardo_100ms 4Mhz 100ms
mar 22 jul 2014 19:22:23 CEST
http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------

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

                
END 
Buenísimo, me funciona a la primera. No sabía que se puediera hacer tantas tablas como quieras.

Hay un problema. Nada más encenderlo el simulador, me aparece un 7. Luego si pulso pulso el pulsador, nohay ningún problema. Solo al volver a encenderlo.



Cuando al encender aparece un 7, al pulsar aparece un 1 hasta el 4, luego nada de fallos, solo al encender o resetear el PIC.

Voy analizar como hiciste las mezclas de tablas para aprenderlo.

Muchísimas gracias campeón.

Edito.

Para calcular retardos.
http://www.golovchenko.org/cgi-bin/delay

Saludo.
Imágenes Adjuntas
Tipo de Archivo: png picd.png (6,8 KB (Kilobytes), 95 visitas)
03/08/2014 #9

Avatar de palurdo

Sin desmerecer tu código Joaquin, yo el incremento del contador lo haría de otra forma más corta...

Código PHP:
incrementa_contador:
                
bcf    contador2   Si el contador valia 4ahora vale 0
                incf    contador     
Incrementa el contador
                
return                 ; Hasta luego lucas!! 
Meta, prueba a ver con alguna ligera modificación a ver si te va bien?

Código PHP:
;
Un pulsador en RA4 va incrementando un contadorentre [1-4].
La salida se envía a un display de 7 segen PORTBy hacia salidas en PORTA.
;
; (
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 segmentosRB0
;

ZONA DE DATOS ****************************************************************

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

                    processor   16F84A          
4 Mhz
                    radix       dec
                    errorlevel  
-302            Turn off banking message

;*******************************************************************************
Bibliotecas

                    
include p16f84a.inc

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

                    __CONFIG _CP_OFF 
&  _WDT_OFF _PWRTE_ON _XT_OSC


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

Máscaras de E/S de los puertos
salidaentrada
;                    |76543210|
#define PORTA_ES    b'00010000'
#define PORTB_ES    b'00000000'

;*******************************************************************************
Variables
area_compartida
:    udata_shr

contador            res 1                       
Contador [1-4]


ZONA DE CÓDIGOS **************************************************************

programa:           code

                    ORG     000h

Inicio
:
                    
banksel TRISA           bank 1

                    movlw   PORTA_ES        
definir E/S puerto A
                    movwf   TRISA
                    movlw   PORTB_ES        
definir E/S puerto B
                    movwf   TRISB
;
                    
movlw   0               inicializamos contador
                    movwf   contador

Bucle principal
                    banksel PORTA           
bank 0siempre
                    
goto Inicializado
Principal
:
                    
movf    PORTAw        leer puerto A
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante

                    btfss   STATUS
Z       ¿Se ha pulsadoLo está si RA4 == 0
                    
goto    Principal       Noesperar
;
Aquí llegamos con el botón pulsado
                    call    incrementa_contador
Inicializado
:
                    
call    visualiza_contador
                    call    salida_hacia_A

Esperamos que levante el botón
Espera_levantar
:
                    
call    Retardo_100ms   Esperar la suelta del pulsador
                    movf    PORTA
w        leer puerto A
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante
                    btfsc   STATUS
Z       ¿Sigue pulsadoLo está si RA4 == 0
                    
goto    Espera_levantar Noesperar
;
                    goto    
Principal


; ******************************************************************************
;; 
salida_hacia_A
;
Según el valor del contador ([1-4]), lo transforma en otrobasado 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 contadorentre 1 y 4inclusives.
;

incrementa_contador:
                    
bcf     contador,2
                    incf    contador
                    
return

; ******************************************************************************
;; 
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   PCLf          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_par:        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1


Retardo_code
:       code

Retardo_100ms
:
                                    ;
99993 ciclos
                    movlw   0x1E
                    movwf   Retardo_100ms_d1
                    movlw   0x4F
                    movwf   Retardo_100ms_d2

Retardo_100ms_loop
:
                    
decfsz  Retardo_100ms_d1f
                    
goto    $+2
                    decfsz  Retardo_100ms_d2
f
                    
goto    Retardo_100ms_loop

                                    
;3 ciclos
                    
goto    $+1
                    nop

                                    
;4 ciclos (incluyendo la llamada)
                    return

Generado por delay_pic.pl (Joaquín Ferrero2014.07.22)
; ./
delay_pic.pl -s Retardo_100ms 4Mhz 100ms
mar 22 jul 2014 19:22:23 CEST
http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------

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

                
END 
03/08/2014 #10

Avatar de Meta

Hola:

Se muestra un 0 en el Display y se queda ahí, el pulsador no hace caso. En resumen, no funciona. Se agradece resumir códigos.

Cuando esto funcione de maravilla. Quiero pasarlo al PIC16F88 real, ya que es el PIC que tengo ahora mismo. Les mostraré hasta un vídeo.

Gracias por sus tiempo.
03/08/2014 #11

Avatar de palurdo

Cambia la etiqueta de inicializacion y ponla una instruccion antes, de esa forma al encender debe aparecer un 1. Si no es asi algo falla en la rutina de incremento. De todas formas es muy raro que falle solo he hexho un goto para una primera impresion en display y sustituir el incremento por las dos instrucciones. Es posible que se haya vuelto loca la tabla de porta al estar el.contador a cero.
03/08/2014 #12

Avatar de Meta

Ahora mismo pezco, no comprendo.
03/08/2014 #13

Avatar de palurdo

En un rato te contesto con el codigo. Estoy desde el telefono movil.

OK mira a ver si asi funciona:

Código PHP:

Un pulsador en RA4 va incrementando un contadorentre [1-4]. 
La salida se envía a un display de 7 segen PORTBy hacia salidas en PORTA

; (
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 segmentosRB0 


ZONA DE DATOS **************************************************************** 

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

                    processor   16F84A          
4 Mhz 
                    radix       dec 
                    errorlevel  
-302            Turn off banking message 

;******************************************************************************* 
Bibliotecas 

                    
include p16f84a.inc 

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

                    __CONFIG _CP_OFF 
&  _WDT_OFF _PWRTE_ON _XT_OSC 


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

Máscaras de E/S de los puertos 
salidaentrada 
;                    |76543210
#define PORTA_ES    b'00010000' 
#define PORTB_ES    b'00000000' 

;******************************************************************************* 
Variables 
area_compartida
:    udata_shr 

contador            res 1                       
Contador [1-4


ZONA DE CÓDIGOS ************************************************************** 

programa:           code 

                    ORG     000h 

Inicio

                    
banksel TRISA           bank 1 

                    movlw   PORTA_ES        
definir E/S puerto A 
                    movwf   TRISA 
                    movlw   PORTB_ES        
definir E/S puerto B 
                    movwf   TRISB 

                    
movlw   0               inicializamos contador 
                    movwf   contador 

Bucle principal 
                    banksel PORTA           
bank 0siempre 
                    
goto Inicializado 
Principal

                    
movf    PORTAw        leer puerto A 
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante 

                    btfss   STATUS
Z       ¿Se ha pulsadoLo está si RA4 == 
                    
goto    Principal       Noesperar 

Aquí llegamos con el botón pulsado 
Inicializado

                    
call    incrementa_contador 
                    call    visualiza_contador 
                    call    salida_hacia_A 

Esperamos que levante el botón 
Espera_levantar

                    
call    Retardo_100ms   Esperar la suelta del pulsador 
                    movf    PORTA
w        leer puerto A 
                    andlw   PORTA_ES        
nos quedamos sólo con lo interesante 
                    btfsc   STATUS
Z       ¿Sigue pulsadoLo está si RA4 == 
                    
goto    Espera_levantar Noesperar 

                    goto    
Principal 


; ****************************************************************************** 
;; 
salida_hacia_A 

Según el valor del contador ([1-4]), lo transforma en otrobasado 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 contadorentre 1 y 4inclusives


incrementa_contador
                    
bcf     contador,
                    incf    contador 
                    
return 

; ****************************************************************************** 
;; 
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   PCLf          salta al dígito indexado por w 

;                            |76543210
                    
retlw   b'00111111'     
                    retlw   
b'00000110'     
                    retlw   
b'01011011'     
                    retlw   
b'01001111'     
                    retlw   
b'01100110'     
                    retlw   
b'01101101'     
                    retlw   
b'01111101'     
                    retlw   
b'00000111'     
                    retlw   
b'01111111'     
                    retlw   
b'01101111'     

; ---------------------------------------------------------------------------------------------------- 
Espera 100ms 
Frecuencia de reloj 4Mhz 

Espera real 0.1 segundos 100000 ciclos 
Error 0.00 

Retardo_par:        udata_shr 

Retardo_100ms_d1    res 1 
Retardo_100ms_d2    res 1 


Retardo_code
:       code 

Retardo_100ms

                                    ;
99993 ciclos 
                    movlw   0x1E 
                    movwf   Retardo_100ms_d1 
                    movlw   0x4F 
                    movwf   Retardo_100ms_d2 

Retardo_100ms_loop

                    
decfsz  Retardo_100ms_d1
                    
goto    $+
                    decfsz  Retardo_100ms_d2

                    
goto    Retardo_100ms_loop 

                                    
;3 ciclos 
                    
goto    $+
                    nop 

                                    
;4 ciclos (incluyendo la llamada
                    return 

Generado por delay_pic.pl (Joaquín Ferrero2014.07.22
; ./
delay_pic.pl -s Retardo_100ms 4Mhz 100ms 
mar 22 jul 2014 19:22:23 CEST 
http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html 
; ---------------------------------------------------------------------------------------------------- 

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

                
END 
03/08/2014 #14

Avatar de Meta

Hola:

Funciona a la primera. Ahora voy a hacer el cambio hacia el PIC16F88.

Un saludo.
03/08/2014 #15

Avatar de Meta

Hola de nuevo.

Usando el MPLAb X 2.15 ahora mismo, antes usaba el MPLAB v8.92 (El fabricante ya no actualiza desde hace tiempo).

Código:
;
; 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.
;
; (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
;

; ZONA DE DATOS ****************************************************************

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

    LIST   P=16F88          ; 4 Mhz
    radix       dec
    errorlevel  -302            ; Turn off banking message

;*******************************************************************************
; Bibliotecas

    INCLUDE <P16f88.INC>

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

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

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

    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

; _IESO_OFF: Modo de intercambio de externo a interno DESACTIVADO.
; _FCMEN_OFF: Monitor de CLK DESACTIVADO.


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

; Máscaras de E/S de los puertos
; 0 = salida, 1 = entrada
;                    |76543210|
#define PORTA_ES    b'00010000'
#define PORTB_ES    b'00000000'

;*******************************************************************************
; Variables
area_compartida:    udata_shr

contador            res 1                       ; Contador [1-4]


; ZONA DE CÓDIGOS **************************************************************

programa:           code

                    ORG     000h

Inicio:
                    banksel ANSEL           ; bank 1
                    clrf    ANSEL           ; Puerto analógico a digital.
                    movlw   PORTA_ES        ; definir E/S puerto A
                    movwf   TRISA
                    movlw   PORTB_ES        ; definir E/S puerto B
                    movwf   TRISB
;
                    movlw   0               ; inicializamos contador
                    movwf   contador

; Bucle principal
                    BANKSEL OSCCON
                    movlw   b'01100000'     ; 4 MHz
                    movwf   OSCCON
                    banksel PORTA           ; bank 0, siempre
                    goto Inicializado
Principal:
                    movf    PORTA, w        ; leer puerto A
                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante

                    btfss   STATUS, Z       ; ¿Se ha pulsado? Lo está si RA4 == 0
                    goto    Principal       ; No, esperar
;
; Aquí llegamos con el botón pulsado
Inicializado:
                    call    incrementa_contador
                    call    visualiza_contador
                    call    salida_hacia_A

; Esperamos que levante el botón
Espera_levantar:
                    call    Retardo_100ms   ; Esperar la suelta del pulsador
                    movf    PORTA, w        ; leer puerto A
                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
                    btfsc   STATUS, Z       ; ¿Sigue pulsado? Lo está si RA4 == 0
                    goto    Espera_levantar ; No, esperar
;
                    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
                    incf    contador
                    return

; ******************************************************************************
;; 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_par:        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1


Retardo_code:       code

Retardo_100ms:
                                    ;99993 ciclos
                    movlw   0x1E
                    movwf   Retardo_100ms_d1
                    movlw   0x4F
                    movwf   Retardo_100ms_d2

Retardo_100ms_loop:
                    decfsz  Retardo_100ms_d1, f
                    goto    $+2
                    decfsz  Retardo_100ms_d2, f
                    goto    Retardo_100ms_loop

                                    ;3 ciclos
                    goto    $+1
                    nop

                                    ;4 ciclos (incluyendo la llamada)
                    return

; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
; ./delay_pic.pl -s Retardo_100ms 4Mhz 100ms
; mar 22 jul 2014 19:22:23 CEST
; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------

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

                END
Lo he adaptado al PIC16F88 y me funciona con el oscilador externo. Quiero usar el oscilador interno a 4 MHz si es posible. Así me libro de componentes externos.



PD: Por cierto. No sabía que has hecho tu propio generador de retardos, es muy de agradecer. Si lo deseas, lo puedo poner como utilidad en la sección Utilidad de mi Blog.
Imágenes Adjuntas
Tipo de Archivo: png Sin-título-1.png (11,4 KB (Kilobytes), 91 visitas)
03/08/2014 #16

Avatar de JoaquinFerrero

palurdo: gracias por encontrar una mejor solución para el incremento. Es cierto que había escrito demasiadas instrucciones para algo tan simple.

Meta: le hice ingeniería inversa al generador de retardos de Goglovchenko, porque había algunos comportamientos extraños con algunas combinaciones y, sobre todo, porque no querían compartir su código Aunque en su página dan muchas pistas, no estaba disponible. Así que, aprovechando que estaba aprendiendo a programar los temporizadores, de forma transversal salió el tema de los retardos por medio de bucles enlazados. Y de ahí luego la idea de crear un programa que reuniera el conocimiento aprendido, teniendo además la ventaja de que se podía personalizar la salida de forma más sencilla, editando unas pocas líneas del código. Y el resultado, en algunos casos muy puntuales, es mejor que el de Golovchenko

Aún no he terminado con él, ya que mis planes son las de crear una biblioteca Perl con él, y publicarlo en el CPAN, para que otras personas lo puedan usar de forma aún más sencilla.
03/08/2014 #17

Avatar de Meta

Buenas:



A pesar de asegurarme una y otra vez los Led del display rojo cátodo común con el PIC. Da resultados no esperado. En cuanto a los 4 Led azules, funciona muy bien.

¿Qué puede ser?

El código es este y juraría que la tabla de la verdad está bien.
Código:
;
; 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.
;
; (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
;

; ZONA DE DATOS ****************************************************************

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

    LIST   P=16F88          ; 4 Mhz
    radix       dec
    errorlevel  -302            ; Turn off banking message

;*******************************************************************************
; Bibliotecas

    INCLUDE <P16f88.INC>

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

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

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

    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

; _IESO_OFF: Modo de intercambio de externo a interno DESACTIVADO.
; _FCMEN_OFF: Monitor de CLK DESACTIVADO.


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

; Máscaras de E/S de los puertos
; 0 = salida, 1 = entrada
;                    |76543210|
#define PORTA_ES    b'00010000'
#define PORTB_ES    b'00000000'

;*******************************************************************************
; Variables
area_compartida:    udata_shr

contador            res 1                       ; Contador [1-4]


; ZONA DE CÓDIGOS **************************************************************

programa:           code

                    ORG     000h

Inicio:
                    banksel ANSEL           ; bank 1
                    clrf    ANSEL           ; Puerto analógico a digital.
                    movlw   PORTA_ES        ; definir E/S puerto A
                    movwf   TRISA
                    movlw   PORTB_ES        ; definir E/S puerto B
                    movwf   TRISB
;
                    movlw   0               ; inicializamos contador
                    movwf   contador

; Bucle principal
                    BANKSEL OSCCON
                    movlw   b'01100000'     ; 4 MHz
                    movwf   OSCCON
                    banksel PORTA           ; bank 0, siempre
                    goto Inicializado
Principal:
                    movf    PORTA, w        ; leer puerto A
                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante

                    btfss   STATUS, Z       ; ¿Se ha pulsado? Lo está si RA4 == 0
                    goto    Principal       ; No, esperar
;
; Aquí llegamos con el botón pulsado
Inicializado:
                    call    incrementa_contador
                    call    visualiza_contador
                    call    salida_hacia_A

; Esperamos que levante el botón
Espera_levantar:
                    call    Retardo_100ms   ; Esperar la suelta del pulsador
                    movf    PORTA, w        ; leer puerto A
                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
                    btfsc   STATUS, Z       ; ¿Sigue pulsado? Lo está si RA4 == 0
                    goto    Espera_levantar ; No, esperar
;
                    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
                    incf    contador
                    return

; ******************************************************************************
;; 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_par:        udata_shr

Retardo_100ms_d1    res 1
Retardo_100ms_d2    res 1


Retardo_code:       code

Retardo_100ms:
                                    ;99993 ciclos
                    movlw   0x1E
                    movwf   Retardo_100ms_d1
                    movlw   0x4F
                    movwf   Retardo_100ms_d2

Retardo_100ms_loop:
                    decfsz  Retardo_100ms_d1, f
                    goto    $+2
                    decfsz  Retardo_100ms_d2, f
                    goto    Retardo_100ms_loop

                                    ;3 ciclos
                    goto    $+1
                    nop

                                    ;4 ciclos (incluyendo la llamada)
                    return

; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
; ./delay_pic.pl -s Retardo_100ms 4Mhz 100ms
; mar 22 jul 2014 19:22:23 CEST
; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------

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

                END
Espero que el oscilador interno a 4 Mhz esté bien puestos del PIC16F88.

Saludo.

PD: Es de agradece recortar código. En cuanto a los retardos, buen trabajo.
03/08/2014 #18

Avatar de JoaquinFerrero

El número de segmentos que se encienden son correctos, y además son consistentes entre sí (siguen la secuencia 1-4), pero... las conexiones están mal.

En el caso del '1', se deben encender RB0 y RB1, correspondientes a los segmentos 'b' y 'c', pero en realidad se están iluminando el 'c' y el 'd'. Así que... o el 'b' está cambiado o los dos están mal.

Por otra parte, me he dado cuenta de que la secuencia de bits de PORTB que hay en el comentario inicial en el programa, no es correcto, no sirve para el 7 segmentos. No afecta al código (es un comentario) pero queda feo. Y el foro ya no me deja cambiarlo :(
03/08/2014 #19

Avatar de Meta

Si no te deja cambiarlo, puedes poner el nuevo código aquí.

A parte de ello, parece que se puede mejorar o reducir a la hora de hacer varias tablas.
Por ejemplo.

Código:
  1. IncrementaVisualiza
  2. incf Contador,F ; Incrementa el contador y comprueba si ha
  3. movlw d'4' ; llegado a su valor máximo mediante una
  4. subwf Contador,W ; resta. (W)=(Contador)-4.
  5. btfsc STATUS,C ; ¿C=0?, ¿(W) negativo?, ¿(Contador)<4?
  6. InicializaContador
  7. clrf Contador ; No, era igual o mayor. Por tanto, resetea.
  8. Visualiza
  9. movf Contador,W
  10. ; call Numero_a_7Segmentos ; Lo pasa a siete segmento para poder ser
  11. call Tabla
  12. movwf Display ; visualizado en el display.
  13. movf Contador,W
  14. call Tabla2
  15. movwf PORTA
  16. return
  17. Tabla
  18. addwf PCL,F
  19. DT 06h, 5Bh, 4Fh, 66h ; Números 1, 2, 3 y 4.
  20. Tabla2
  21. addwf PCL,F
  22. DT 02h, 05h, 06h, 0Ah
En cuanto a las conexiones, lo estoy revisando palmo a palmo.

Gracias.

Edito:

Efectivamente. Son las conexiones. Ahora funciona muy bien.
Imágenes Adjuntas
Tipo de Archivo: gif Sin-título-1.gif (92,4 KB (Kilobytes), 79 visitas)
03/08/2014 #20

Avatar de JoaquinFerrero

Al final, sí que me dejó. He reeditado el mensaje #7, arreglando el comentario inicial y agregando los cambios de palurdo.

En cuanto a usar dt... me parece que justo este problema es un buen ejemplo en que los dt no son lo recomendable. Es cierto que generan el mismo código que los retlw (generan el mismo código binario), pero en un asunto en que tenemos que lidiar con líneas de bits, prefiero verlos (los bits); por eso habrás visto en mi código líneas así:

|76543210|

que ayudan en la des/activación de bits individuales.

Yo prefiero no andar calculando el valor decimal o hexadecimal de los bytes y ponerlos en los dt... el mantenimiento posterior es mucho más difícil.

Los dt vienen bien, por ejemplo, para poner tablas de multiplicadores/divisores:

dt 100,10,1
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.