Foro de elhacker.net

Informática => Electrónica => Mensaje iniciado por: Meta en 3 Agosto 2014, 05:47 am



Título: Modificar este código a algo más complejo
Publicado por: Meta en 3 Agosto 2014, 05:47 am
Hola:

Siendo este código en asm para PIC16F84A (http://"http://ww1.microchip.com/downloads/en/DeviceDoc/35007C.pdf"), ya lo pasaré a PIC16F88 (http://"http://ww1.microchip.com/downloads/en/DeviceDoc/30487D.pdf").

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.


Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 3 Agosto 2014, 19:50 pm
Buenas:

He modificado un poco el código. El esquema es este circuito.
(http://www.subeimagenes.com/img/pic-1043767.png)

Nueva tabla de la verdad corregida.
(http://www.subeimagenes.com/img/tabla-de-la-verdad-1043760.png)

La zona gris funciona de maravilla. El Display de 7 segmentos cuanta del 1 al 4 desde que pulse el pulsador. Si llega al 4, al pulsar una vez, llega al 1 así sucesivamente.

Fíjate ahora en la zona verde, es otra tabla de la verdad de datos, que se encienden los Led amarillos. Siempre es acorde al del display, por ejemplo.

Si en la tabla de la verdad zona gris del display es el número 2, tiene que estar acorde al mismo tiempo con el 2 de la zona verdad de datos.

(http://www.subeimagenes.com/img/sin-titulo-1-1043781.png)

El código lo hice más simple, solo funciona el Display del 1 al 4, pero no se que hacer para funcionar la zona verde de datos.
Código
  1. ; Cada vez que presione el pulsador conectado al pin RA4 incrementa un contador visualizado
  2. ; en el display.
  3. ;
  4. ; ZONA DE DATOS **********************************************************************
  5.  
  6. LIST P=16F84A
  7. INCLUDE <P16F84A.INC>
  8. __CONFIG _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC
  9.  
  10. CBLOCK  0x0C
  11. Contador ; El contador a visualizar.
  12. ENDC
  13.  
  14. #DEFINE OE1 PORTA,0
  15. #DEFINE OE2 PORTA,1
  16. #DEFINE A21 PORTA,2
  17. #DEFINE AUX PORTA,3
  18. #DEFINE Pulsador PORTA,4 ; Pulsador conectado a RA4.
  19. #DEFINE Display PORTB ; El display está conectado al Puerto B.
  20.  
  21. ; ZONA DE CÓDIGOS ********************************************************************
  22.  
  23. ORG 0 ; El programa comienza en la dirección 0.
  24. Inicio
  25.   bsf STATUS,RP0 ; Acceso al Banco 1.
  26. clrf Display ; Estas líneas configuradas como salidas.
  27. bcf OE1
  28. bcf OE2
  29. bcf A21
  30. bcf AUX
  31. bsf Pulsador ; Línea del pulsador configurada como entrada.
  32. bcf STATUS,RP0 ; Acceso al Banco 0.
  33. call InicializaContador ; Inicializa el Contador y lo visualiza.
  34. Principal
  35. btfsc Pulsador ; ¿Pulsador presionado?, ¿(Pulsador)=0?
  36. goto Fin ; No. Vuelve a leerlo.
  37. ; call Retardo_20ms ; Espera que se estabilicen los niveles de tensión.
  38. btfsc Pulsador ; Comprueba si es un rebote.
  39. goto Fin ; Era un rebote y sale fuera.
  40. call IncrementaVisualiza ; Incrementa el contador y lo visualiza.
  41. EsperaDejePulsar
  42. btfss Pulsador ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
  43. goto EsperaDejePulsar ; No. Espera que deje de pulsar.
  44. Fin goto Principal
  45.  
  46. ; Subrutina "IncrementaVisualiza" ---------------------------------------------------------
  47.  
  48. IncrementaVisualiza
  49. incf Contador,F ; Incrementa el contador y comprueba si ha
  50. movlw d'4' ; llegado a su valor máximo mediante una
  51. subwf Contador,W ; resta. (W)=(Contador)-4.
  52. btfsc STATUS,C ; ¿C=0?, ¿(W) negativo?, ¿(Contador)<4?
  53. InicializaContador
  54. clrf Contador ; No, era igual o mayor. Por tanto, resetea.
  55. Visualiza
  56. movf Contador,W
  57. ; call Numero_a_7Segmentos ; Lo pasa a siete segmento para poder ser
  58. call Tabla
  59. movwf Display ; visualizado en el display.
  60. return
  61. Tabla
  62. addwf PCL,F
  63. DT 06h, 5Bh, 4Fh, 66h ; Números 1, 2, 3 y 4.
  64.  
  65.  
  66. INCLUDE <RETARDOS.INC> ; Subrutinas de retardo.
  67. END ; Fin del programa.

¿Hay alguna idea?

Saludo.


Título: Re: Modificar este código a algo más complejo
Publicado por: MinusFour en 3 Agosto 2014, 21:49 pm
Uhh hace mucho que no toco ASM pero ¿Porque no simplemente haces otra tabla?

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



Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 4 Agosto 2014, 03:30 am
Gracias.

Una tabla es para el display, la otra para datos, control para otros dispositivos.

Me pasé al PIC16F88 porque usa oscilador interno, lo he configurado a 4 MHz y no estoy seguro si realmente lo he hecho bien. A pesar que en el simulador Proteus 7.10 funciona muy bien, la realidad es muy distinta.

(http://www.subeimagenes.com/img/sin-titulo-1-1044438.png)

A la hora de montarlo en una demoboard para probarlo, me da en el display carácteres raros en vez del 1 al 4. Los Led azules que ven son los amarillos del esquema de arriba que si funciona a la perfección.

(http://www.subeimagenes.com/img/p1180900-1044429.gif)

Los cables están bien. Lo que no se si este nuevo código está bien. En el proteus funciona, la realidad no.

Código
  1. ;
  2. ; Un pulsador en RA4 va incrementando un contador, entre [1-4].
  3. ; La salida se envía a un display de 7 seg. en PORTB, y hacia salidas en PORTA.
  4. ;
  5. ; (Contador)  |RB 76543210 |RA 76543210
  6. ; ------------|------------------------
  7. ;       1     |   00000011 |   00000010
  8. ;       2     |   00100100 |   00000101
  9. ;       3     |   00001100 |   00000110
  10. ;       4     |   00111100 |   00001001
  11. ;
  12. ; PORTA:
  13. ;  RA0 : OE1
  14. ;  RA1 : OE2
  15. ;  RA2 : A21
  16. ;  RA3 : AUX
  17. ;  RA4 : Pulsador
  18. ; PORTB : display de 7 segmentos. a = RB0
  19. ;
  20.  
  21. ; ZONA DE DATOS ****************************************************************
  22.  
  23. ;*******************************************************************************
  24. ; Listado y condiciones de ensamblado
  25.  
  26.    LIST   P=16F88          ; 4 Mhz
  27.    radix       dec
  28.    errorlevel  -302            ; Turn off banking message
  29.  
  30. ;*******************************************************************************
  31. ; Bibliotecas
  32.  
  33.    INCLUDE <P16f88.INC>
  34.  
  35. ;*******************************************************************************
  36. ; Fusibles
  37.  
  38.    __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
  39. ;_XT_OSC
  40.  
  41. ; _CP_OFF: Protección de código DESACTIVADO.
  42. ; _DEBUG_OFF: Debug en circuito DESACTIVADO.
  43. ; _WRT_PROTECT_OFF: Protección a escritura en memoria de programa DESACTIVADO.
  44. ; _CPD_OFF: Protección de código de datos DESACTIVADO.
  45. ; _LVP_OFF: Programación en baja tensión DESACTIVADO.
  46. ; _BODEN_OFF: Reset por Brown-out DESACTIVADO.
  47. ; _MCLRE_ON: Reset por pin externo ACTIVADO.
  48. ; _PWRTE_ON: Retraso al reset ACTIVADO.
  49. ; _WDT_OFF: Watchdog DESACTIVADO.
  50. ; _XT_OSC: Oscilador externo del tipo XT.
  51.  
  52.    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
  53.  
  54. ; _IESO_OFF: Modo de intercambio de externo a interno DESACTIVADO.
  55. ; _FCMEN_OFF: Monitor de CLK DESACTIVADO.
  56.  
  57.  
  58. ;*******************************************************************************
  59. ; Definiciones
  60.  
  61. ; Máscaras de E/S de los puertos
  62. ; 0 = salida, 1 = entrada
  63. ;                    |76543210|
  64. #define PORTA_ES    b'00010000'
  65. #define PORTB_ES    b'00000000'
  66.  
  67. ;*******************************************************************************
  68. ; Variables
  69. area_compartida:    udata_shr
  70.  
  71. contador            res 1                       ; Contador [1-4]
  72.  
  73.  
  74. ; ZONA DE CÓDIGOS **************************************************************
  75.  
  76. programa:           code
  77.  
  78.                    ORG     000h
  79.  
  80. Inicio:
  81.                    banksel ANSEL           ; bank 1
  82.                    clrf    ANSEL           ; Puerto analógico a digital.
  83.                    movlw   PORTA_ES        ; definir E/S puerto A
  84.                    movwf   TRISA
  85.                    movlw   PORTB_ES        ; definir E/S puerto B
  86.                    movwf   TRISB
  87. ;
  88.                    movlw   0               ; inicializamos contador
  89.                    movwf   contador
  90.  
  91. ; Bucle principal
  92.                    BANKSEL OSCCON
  93.                    movlw   b'01100000'     ; 4 MHz
  94.                    movwf   OSCCON
  95.                    banksel PORTA           ; bank 0, siempre
  96.                    goto Inicializado
  97. Principal:
  98.                    movf    PORTA, w        ; leer puerto A
  99.                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
  100.  
  101.                    btfss   STATUS, Z       ; ¿Se ha pulsado? Lo está si RA4 == 0
  102.                    goto    Principal       ; No, esperar
  103. ;
  104. ; Aquí llegamos con el botón pulsado
  105. Inicializado:
  106.                    call    incrementa_contador
  107.                    call    visualiza_contador
  108.                    call    salida_hacia_A
  109.  
  110. ; Esperamos que levante el botón
  111. Espera_levantar:
  112.                    call    Retardo_100ms   ; Esperar la suelta del pulsador
  113.                    movf    PORTA, w        ; leer puerto A
  114.                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
  115.                    btfsc   STATUS, Z       ; ¿Sigue pulsado? Lo está si RA4 == 0
  116.                    goto    Espera_levantar ; No, esperar
  117. ;
  118.                    goto    Principal
  119.  
  120.  
  121. ; ******************************************************************************
  122. ;; salida_hacia_A
  123. ;
  124. ; Según el valor del contador ([1-4]), lo transforma en otro, basado en una
  125. ; tabla y lo saca por el puerto A
  126. ;
  127.  
  128. salida_hacia_A:     call    transforma_contador
  129.                    movwf   PORTA           ; visualiza en puerto A
  130.                    return
  131.  
  132. transforma_contador:
  133.                    decf    contador,w      ; leemos el contador y le restamos 1
  134.                    addwf   PCL, f          ; saltamos dentro de la tabla
  135.  
  136. ;                            |76543210|
  137.                    retlw   b'00000010'
  138.                    retlw   b'00000101'
  139.                    retlw   b'00000110'
  140.                    retlw   b'00001001'
  141.  
  142. ; ******************************************************************************
  143. ;; incrementa_contador
  144. ;
  145. ; Incrementa el valor de la variable contador, entre 1 y 4, inclusives.
  146. ;
  147.  
  148. incrementa_contador:
  149.                    bcf     contador,2
  150.                    incf    contador
  151.                    return
  152.  
  153. ; ******************************************************************************
  154. ;; visualiza_contador
  155. ;
  156. ; Muestra el valor del contador en el display de 7 segmentos
  157. ;
  158.  
  159. visualiza_contador:
  160.                    movfw   contador        ; leemos contador
  161.                    call    w_a_digito      ; transformación a dígito 7 segmentos
  162.                    movwf   PORTB           ; visualiza en puerto B
  163.                    return
  164.  
  165. w_a_digito:         addwf   PCL, f          ; salta al dígito indexado por w
  166.  
  167. ;                            |76543210|
  168.                    retlw   b'00111111'     ; 0
  169.                    retlw   b'00000110'     ; 1
  170.                    retlw   b'01011011'     ; 2
  171.                    retlw   b'01001111'     ; 3
  172.                    retlw   b'01100110'     ; 4
  173.                    retlw   b'01101101'     ; 5
  174.                    retlw   b'01111101'     ; 6
  175.                    retlw   b'00000111'     ; 7
  176.                    retlw   b'01111111'     ; 8
  177.                    retlw   b'01101111'     ; 9
  178.  
  179. ; ----------------------------------------------------------------------------------------------------
  180. ; Espera = 100ms
  181. ; Frecuencia de reloj = 4Mhz
  182. ;
  183. ; Espera real = 0.1 segundos = 100000 ciclos
  184. ; Error = 0.00 %
  185.  
  186. Retardo_par:        udata_shr
  187.  
  188. Retardo_100ms_d1    res 1
  189. Retardo_100ms_d2    res 1
  190.  
  191.  
  192. Retardo_code:       code
  193.  
  194. Retardo_100ms:
  195.                                    ;99993 ciclos
  196.                    movlw   0x1E
  197.                    movwf   Retardo_100ms_d1
  198.                    movlw   0x4F
  199.                    movwf   Retardo_100ms_d2
  200.  
  201. Retardo_100ms_loop:
  202.                    decfsz  Retardo_100ms_d1, f
  203.                    goto    $+2
  204.                    decfsz  Retardo_100ms_d2, f
  205.                    goto    Retardo_100ms_loop
  206.  
  207.                                    ;3 ciclos
  208.                    goto    $+1
  209.                    nop
  210.  
  211.                                    ;4 ciclos (incluyendo la llamada)
  212.                    return
  213.  
  214. ; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
  215. ; ./delay_pic.pl -s Retardo_100ms 4Mhz 100ms
  216. ; mar 22 jul 2014 19:22:23 CEST
  217. ; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
  218. ; ----------------------------------------------------------------------------------------------------
  219.  
  220. ; ******************************************************************************
  221.  
  222.                END  

Saludo.


Título: Re: Modificar este código a algo más complejo
Publicado por: MinusFour en 4 Agosto 2014, 07:12 am
¡Lo probe en MPLAB y no tuve ningún problema! Al menos no con tu código... que tuve problemas para configurar el compilador xD.

(http://i.imgur.com/yp1AMw8.jpg)


Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 4 Agosto 2014, 12:26 pm
Buenas:

Tenía los conectores no muy bien colocados. Gracias por la ayuda e ideas. Ahora me funciona de maravilla.

(http://www.subeimagenes.com/img/p1180908-1044977.jpg)


El siguiente y último reto que nunca he usado la EEPROM interna del PIC16F88 (http://ww1.microchip.com/downloads/en/DeviceDoc/30487D.pdf), no me sale a pesar de leer bien su hoja de datos. En la página 29 del datasheet te dice códigos pero a mi no me funciona o no se hacerlo.

Lo que quiero hacer es guardar los últimos datos seleccionados por el pulsador de las dos tablas de la verdad. Por ejemplo, si estamos en el número 2 del Display, al apagarlo y encenderlo otra vez el PIC, aparezca precisamente el 2, que es el último número que se mostró. Se incluye también el guardado de la tabla de la verdad de datos.


(http://www.subeimagenes.com/img/tabla-de-la-verdad-1043760.png)

Los que sepan, una ayudita. Por lo que veo, no se me da para nada bien guardar y recuperar datos en la EEPROM interna del PIC. Fijándome bien, se necesita una celda para guardar los 8 bits o un byte de la Tabla de la verdad gris del Display, y otra celda o posición de memoria también de 8 bits o un byte en la Tabla de la verdad verde de datos.

(http://www.subeimagenes.com/img/sin-titulo-1-1044982.gif)

De todas formas, voy a intentarlo por si acaso.

Desde que funcione todo, subo un vídeo.

Saludo.


Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 4 Agosto 2014, 18:08 pm
Algo he hecho que no se guarda los datos en la EEPROM.

Código
  1. ;
  2. ; Un pulsador en RA4 va incrementando un contador, entre [1-4].
  3. ; La salida se envía a un display de 7 seg. en PORTB, y hacia salidas en PORTA.
  4. ;
  5. ; (Contador)  |RB 76543210 |RA 76543210
  6. ; ------------|------------------------
  7. ;       1     |   00000011 |   00000010
  8. ;       2     |   00100100 |   00000101
  9. ;       3     |   00001100 |   00000110
  10. ;       4     |   00111100 |   00001001
  11. ;
  12. ; PORTA:
  13. ;  RA0 : OE1
  14. ;  RA1 : OE2
  15. ;  RA2 : A21
  16. ;  RA3 : AUX
  17. ;  RA4 : Pulsador
  18. ; PORTB : display de 7 segmentos. a = RB0
  19. ;
  20.  
  21. ; ZONA DE DATOS ****************************************************************
  22.  
  23. ;*******************************************************************************
  24. ; Listado y condiciones de ensamblado
  25.  
  26.    LIST   P=16F88          ; 4 Mhz
  27.    radix       dec
  28.    errorlevel  -302            ; Turn off banking message
  29.  
  30. ;*******************************************************************************
  31. ; Bibliotecas
  32.  
  33.    INCLUDE <P16f88.INC>
  34.  
  35. ;*******************************************************************************
  36. ; Fusibles
  37.  
  38.    __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
  39. ;_XT_OSC
  40.  
  41. ; _CP_OFF: Protección de código DESACTIVADO.
  42. ; _DEBUG_OFF: Debug en circuito DESACTIVADO.
  43. ; _WRT_PROTECT_OFF: Protección a escritura en memoria de programa DESACTIVADO.
  44. ; _CPD_OFF: Protección de código de datos DESACTIVADO.
  45. ; _LVP_OFF: Programación en baja tensión DESACTIVADO.
  46. ; _BODEN_OFF: Reset por Brown-out DESACTIVADO.
  47. ; _MCLRE_ON: Reset por pin externo ACTIVADO.
  48. ; _PWRTE_ON: Retraso al reset ACTIVADO.
  49. ; _WDT_OFF: Watchdog DESACTIVADO.
  50. ; _XT_OSC: Oscilador externo del tipo XT.
  51.  
  52.    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
  53.  
  54. ; _IESO_OFF: Modo de intercambio de externo a interno DESACTIVADO.
  55. ; _FCMEN_OFF: Monitor de CLK DESACTIVADO.
  56.  
  57.  
  58. ;*******************************************************************************
  59. ; Definiciones
  60.  
  61. ; Máscaras de E/S de los puertos
  62. ; 0 = salida, 1 = entrada
  63. ;                    |76543210|
  64. #define PORTA_ES    b'00010000'
  65. #define PORTB_ES    b'00000000'
  66.  
  67. ;*******************************************************************************
  68. ; Variables
  69. area_compartida:    udata_shr
  70.  
  71. contador            res 1                       ; Contador [1-4]
  72.  
  73.  
  74. ; ZONA DE CÓDIGOS **************************************************************
  75.  
  76. programa:           code
  77.  
  78.                    ORG     000h
  79.  
  80. Inicio:
  81.                    banksel ANSEL           ; bank 1
  82.                    clrf    ANSEL           ; Puerto analógico a digital.
  83.                    movlw   PORTA_ES        ; definir E/S puerto A
  84.                    movwf   TRISA
  85.                    movlw   PORTB_ES        ; definir E/S puerto B
  86.                    movwf   TRISB
  87. ;
  88.                    movlw   0               ; inicializamos contador
  89.                    movwf   contador
  90.                    call    Leer_EEPROM     ; Lectura de la EEPROM.
  91.  
  92. ; Bucle principal
  93.                    BANKSEL OSCCON
  94.                    movlw   b'01100000'     ; 4 MHz
  95.                    movwf   OSCCON
  96.                    banksel PORTA           ; bank 0, siempre
  97.                    goto Inicializado
  98. Principal:
  99.                    movf    PORTA, w        ; leer puerto A
  100.                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
  101.  
  102.                    btfss   STATUS, Z       ; ¿Se ha pulsado? Lo está si RA4 == 0
  103.                    goto    Principal       ; No, esperar
  104. ;
  105. ; Aquí llegamos con el botón pulsado
  106. Inicializado:
  107.                    call    incrementa_contador
  108.                    call    visualiza_contador
  109.                    call    salida_hacia_A
  110.  
  111. ; Esperamos que levante el botón
  112. Espera_levantar:
  113.                    call    Retardo_100ms   ; Esperar la suelta del pulsador
  114.                    movf    PORTA, w        ; leer puerto A
  115.                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
  116.                    btfsc   STATUS, Z       ; ¿Sigue pulsado? Lo está si RA4 == 0
  117.                    goto    Espera_levantar ; No, esperar
  118. ;
  119.                    goto    Principal
  120.  
  121.  
  122. ; ******************************************************************************
  123. ;; salida_hacia_A
  124. ;
  125. ; Según el valor del contador ([1-4]), lo transforma en otro, basado en una
  126. ; tabla y lo saca por el puerto A
  127. ;
  128.  
  129. salida_hacia_A:     call    transforma_contador
  130.                    movwf   PORTA           ; visualiza en puerto A
  131.                    return
  132.  
  133. transforma_contador:
  134.                    decf    contador,w      ; leemos el contador y le restamos 1
  135.                    addwf   PCL, f          ; saltamos dentro de la tabla
  136.  
  137. ;                            |76543210|
  138.                    retlw   b'00000010'
  139.                    retlw   b'00000101'
  140.                    retlw   b'00000110'
  141.                    retlw   b'00001001'
  142.  
  143. ; ******************************************************************************
  144. ;; incrementa_contador
  145. ;
  146. ; Incrementa el valor de la variable contador, entre 1 y 4, inclusives.
  147. ;
  148.  
  149. incrementa_contador:
  150.                    bcf     contador,2
  151.                    incf    contador
  152.                    return
  153.  
  154. ; ******************************************************************************
  155. ;; visualiza_contador
  156. ;
  157. ; Muestra el valor del contador en el display de 7 segmentos
  158. ;
  159.  
  160. visualiza_contador:
  161.                    movfw   contador        ; leemos contador
  162.                    call    w_a_digito      ; transformación a dígito 7 segmentos
  163.                    movwf   PORTB           ; visualiza en puerto B
  164.                    return
  165.  
  166. w_a_digito:         addwf   PCL, f          ; salta al dígito indexado por w
  167.  
  168. ;                            |76543210|
  169.                    retlw   b'00111111'     ; 0
  170.                    retlw   b'00000110'     ; 1
  171.                    retlw   b'01011011'     ; 2
  172.                    retlw   b'01001111'     ; 3
  173.                    retlw   b'01100110'     ; 4
  174.                    retlw   b'01101101'     ; 5
  175.                    retlw   b'01111101'     ; 6
  176.                    retlw   b'00000111'     ; 7
  177.                    retlw   b'01111111'     ; 8
  178.                    retlw   b'01101111'     ; 9
  179.  
  180. ; ----------------------------------------------------------------------------------------------------
  181. ; Espera = 100ms
  182. ; Frecuencia de reloj = 4Mhz
  183. ;
  184. ; Espera real = 0.1 segundos = 100000 ciclos
  185. ; Error = 0.00 %
  186.  
  187. Retardo_par:        udata_shr
  188.  
  189. Retardo_100ms_d1    res 1
  190. Retardo_100ms_d2    res 1
  191.  
  192.  
  193. Retardo_code:       code
  194.  
  195. Retardo_100ms:
  196.                                    ;99993 ciclos
  197.                    movlw   0x1E
  198.                    movwf   Retardo_100ms_d1
  199.                    movlw   0x4F
  200.                    movwf   Retardo_100ms_d2
  201.  
  202. Retardo_100ms_loop:
  203.                    decfsz  Retardo_100ms_d1, f
  204.                    goto    $+2
  205.                    decfsz  Retardo_100ms_d2, f
  206.                    goto    Retardo_100ms_loop
  207.  
  208.                                    ;3 ciclos
  209.                    goto    $+1
  210.                    nop
  211.  
  212.                                    ;4 ciclos (incluyendo la llamada)
  213.                    return
  214.  
  215.                    call    Escribir_EEPROM
  216.  
  217. ; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
  218. ; ./delay_pic.pl -s Retardo_100ms 4Mhz 100ms
  219. ; mar 22 jul 2014 19:22:23 CEST
  220. ; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
  221. ; ----------------------------------------------------------------------------------------------------
  222.  
  223. ; ******************************************************************************
  224.  
  225. ;Subrutinas EEPROM -----------------------------------------------------------
  226.  
  227. Leer_EEPROM
  228.    BANKSEL EEADR           ; Selecciona el registro EEADR.
  229.    movf    contador, W
  230.    movwf   EEADR           ; Dato dirección de momoria a leer.
  231.    BANKSEL EECON1          ; Selecciona el banco EECON1.
  232.    bcf     EECON1, EEPGD    ; Punto a memoria de datos
  233.    bsf     EECON1, RD      ; a Leer.
  234.    BANKSEL EEDATA          ; Seleccionar banco de EEDATA.
  235.    movf    EEDATA, W       ; W = EEDATA.
  236.    return
  237.  
  238. Escribir_EEPROM
  239.    BANKSEL EECON1          ; Selecciona banco de EECON1.
  240.    btfsc   EECON1, WR      ; Espera para escribir
  241.    goto    $-1             ; a completar.
  242.    BANKSEL EEADR           ; Selecciona el banco EEADR.
  243.    movf    contador, W
  244.    movwf   EEADR           ; Dirección dato de memoria a escribir.
  245.    BANKSEL EECON1          ; Selecciona el banco EECOn1.
  246.    bcf     EECON1, EEPGD   ; Punto a dato de memoria.
  247.    bsf     EECON1, WREN    ; Activar escritura.
  248.    bcf     INTCON, GIE     ; Desactiva interrupciones.
  249.  
  250. ; El fabricante especifica que hay que seguir esta secuencia para escritura en EEPROm.
  251.  
  252.    movlw   0x55
  253.    movwf   EECON2          ; Escribe 55h.
  254.    movlw   0xAA
  255.    movwf   EECON2          ; Escribe AAh.
  256.    bsf     EECON1, WR
  257.  
  258.    bsf     INTCON, GIE     ; Activa interrupciones.
  259.    bcf     EECON1, WREN    ; Desactiva escrituras.
  260.  
  261.  
  262.                END  

(http://www.subeimagenes.com/img/gif-1045078.gif)

El circuito funciona de maravilla, pero no guarda los datos.

Saludo.


Título: Re: Modificar este código a algo más complejo
Publicado por: MinusFour en 4 Agosto 2014, 18:16 pm
Hay una forma muy sencilla de asociar los datos de las tablas.

La EEPROM es así:

(http://i.imgur.com/ERXMeHM.png)

Viendo la memoria así, lo primero que me vino a la mente fue:

(http://i.imgur.com/EDagTQ2.jpg)

Es decir en 0xh puedes guardar todo lo asociado a una tabla y en 1xh puedes guardar todo lo de otra tabla.

Si lo quieres ver en binario

00000000 <-Primera dirección, tabla 1.

00010000 <-Primera dirección, tabla 2.

Y esto es una manera muy sencilla de guardar/leer datos.

Y ahora para asociarlos con el contador lo puedes hacer muy sencillamente así:

Código
  1. movf contador, w ;Direccion 1 Tabla 1
  2. xorlw b'00010000' ;Direccion1 Tabla 2

Puedes inclusive simplemente guardar los metodos de la datasheet y están listos para usarse.

Código
  1. LeerEEPROM:
  2. BANKSEL EEADR ; Select Bank of EEADR
  3. MOVF ADDR, W ;
  4. MOVWF EEADR ; Data Memory Address
  5. ; to read
  6. BANKSEL EECON1 ; Select Bank of EECON1
  7. BCF EECON1, EEPGD; Point to Data memory
  8. BSF EECON1, RD ; EE Read
  9. BANKSEL EEDATA ; Select Bank of EEDATA
  10. MOVF EEDATA, W ; W = EEDATA
  11.        ;Seleciona el banco donde estabas antes de regresar
  12.        BANKSEL PORTA
  13. return

Y lo usas así.

Para sacar el dato de la primera Tabla:

Código
  1. movf contador, w
  2. movwf ADDR ;De preferencia cambia el nombre de la variable
  3. call LeerEEPROM
  4. movwf PORTB

Código
  1. movf contador, w
  2. xorlw b'00010000'
  3. movwf ADDR;
  4. call LeerEEPROM
  5. movwf PORTA

Y para guardar lo mismo, de lo que no me acuerdo es si la escritura a la EEPROM es solo de 1 byte a la vez.

Código
  1. EscribirEEPROM:
  2. BANKSEL EECON1 ; Select Bank of
  3. ; EECON1
  4. BTFSC EECON1, WR ; Wait for write
  5. GOTO $-1 ; to complete
  6. BANKSEL EEADR ; Select Bank of
  7. ; EEADR
  8. MOVF ADDR, W ;
  9. MOVWF EEADR ; Data Memory
  10. ; Address to write
  11. MOVF VALUE, W ;
  12. MOVWF EEDATA ; Data Memory Value
  13. ; to write
  14. BANKSEL EECON1 ; Select Bank of
  15. ; EECON1
  16. BCF EECON1, EEPGD ; Point to DATA
  17. ; memory
  18. BSF EECON1, WREN ; Enable writes
  19.  
  20. BCF INTCON, GIE ; Disable INTs.
  21. MOVLW 55h ;
  22. MOVWF EECON2 ; Write 55h
  23. MOVLW AAh ;
  24. MOVWF EECON2 ; Write AAh
  25. BSF EECON1, WR ; Set WR bit to
  26. ; begin write
  27. BSF INTCON, GIE ; Enable INTs.
  28. BCF EECON1, WREN ; Disable writes
  29. return

Código
  1. GuardaDatos:
  2.        ;Rutina para escribir los 8 bytes.
  3.        ;1 Tabla 1 Direccion
  4.        movlw 00h
  5.        movwf ADDR
  6.        movlw 06h
  7.        movwf VALUE
  8. call EscribirEEPROM
  9.  
  10.        ;2 Tabla 1 Direccion
  11.        movlw 10h
  12.        movwf ADDR
  13.        movlw b'00000010'
  14.        movwf VALUE
  15. call EscribirEEPROM
  16.  
  17. ;Y asi sigues agregando a la EEPROM
  18. return ; o goto, dependiendo de lo que quieras hacer
  19.  


Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 4 Agosto 2014, 21:49 pm
Hola:

Por lo que cuentas, falta vovler en Escribir_EEPROM volver al banco 00, justo antes del return.

Por ahora lo he hecho así. Creo, solo creo, que no hace falta usar dos direcciones, solo uno, el del contador.

Código
  1. ;
  2. ; Un pulsador en RA4 va incrementando un contador, entre [1-4].
  3. ; La salida se envía a un display de 7 seg. en PORTB, y hacia salidas en PORTA.
  4. ;
  5. ; (Contador)  |RB 76543210 |RA 76543210
  6. ; ------------|------------------------
  7. ;       1     |   00000011 |   00000010
  8. ;       2     |   00100100 |   00000101
  9. ;       3     |   00001100 |   00000110
  10. ;       4     |   00111100 |   00001001
  11. ;
  12. ; PORTA:
  13. ;  RA0 : OE1
  14. ;  RA1 : OE2
  15. ;  RA2 : A21
  16. ;  RA3 : AUX
  17. ;  RA4 : Pulsador
  18. ; PORTB : display de 7 segmentos. a = RB0
  19. ;
  20.  
  21. ; ZONA DE DATOS ****************************************************************
  22.  
  23. ;*******************************************************************************
  24. ; Listado y condiciones de ensamblado
  25.  
  26.    LIST   P=16F88          ; 4 Mhz
  27.    radix       dec
  28.    errorlevel  -302            ; Turn off banking message
  29.  
  30. ;*******************************************************************************
  31. ; Bibliotecas
  32.  
  33.    INCLUDE <P16f88.INC>
  34.  
  35. ;*******************************************************************************
  36. ; Fusibles
  37.  
  38.    __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
  39. ;_XT_OSC
  40.  
  41. ; _CP_OFF: Protección de código DESACTIVADO.
  42. ; _DEBUG_OFF: Debug en circuito DESACTIVADO.
  43. ; _WRT_PROTECT_OFF: Protección a escritura en memoria de programa DESACTIVADO.
  44. ; _CPD_OFF: Protección de código de datos DESACTIVADO.
  45. ; _LVP_OFF: Programación en baja tensión DESACTIVADO.
  46. ; _BODEN_OFF: Reset por Brown-out DESACTIVADO.
  47. ; _MCLRE_ON: Reset por pin externo ACTIVADO.
  48. ; _PWRTE_ON: Retraso al reset ACTIVADO.
  49. ; _WDT_OFF: Watchdog DESACTIVADO.
  50. ; _XT_OSC: Oscilador externo del tipo XT.
  51.  
  52.    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
  53.  
  54. ; _IESO_OFF: Modo de intercambio de externo a interno DESACTIVADO.
  55. ; _FCMEN_OFF: Monitor de CLK DESACTIVADO.
  56.  
  57.  
  58. ;*******************************************************************************
  59. ; Definiciones
  60.  
  61. ; Máscaras de E/S de los puertos
  62. ; 0 = salida, 1 = entrada
  63. ;                    |76543210|
  64. #define PORTA_ES    b'00010000'
  65. #define PORTB_ES    b'00000000'
  66.  
  67. ;*******************************************************************************
  68. ; Variables
  69. area_compartida:    udata_shr
  70.  
  71. contador            res 1                       ; Contador [1-4]
  72.  
  73.  
  74. ; ZONA DE CÓDIGOS **************************************************************
  75.  
  76. programa:           code
  77.  
  78.                    ORG     000h
  79.  
  80. Inicio:
  81.                    banksel ANSEL           ; bank 1
  82.                    clrf    ANSEL           ; Puerto analógico a digital.
  83.                    movlw   PORTA_ES        ; definir E/S puerto A
  84.                    movwf   TRISA
  85.                    movlw   PORTB_ES        ; definir E/S puerto B
  86.                    movwf   TRISB
  87. ;
  88.                    movlw   0               ; inicializamos contador
  89.                    movwf   contador
  90.                    call    Leer_EEPROM     ; Lectura de la EEPROM.
  91.  
  92. ; Bucle principal
  93.                    BANKSEL OSCCON
  94.                    movlw   b'01100000'     ; 4 MHz
  95.                    movwf   OSCCON
  96.                    banksel PORTA           ; bank 0, siempre
  97.                    goto Inicializado
  98. Principal:
  99.                    movf    PORTA, w        ; leer puerto A
  100.                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
  101.  
  102.                    btfss   STATUS, Z       ; ¿Se ha pulsado? Lo está si RA4 == 0
  103.                    goto    Principal       ; No, esperar
  104. ;
  105. ; Aquí llegamos con el botón pulsado
  106. Inicializado:
  107.                    call    incrementa_contador
  108.                    call    visualiza_contador
  109.                    call    salida_hacia_A
  110.  
  111. ; Esperamos que levante el botón
  112. Espera_levantar:
  113.                    call    Retardo_100ms   ; Esperar la suelta del pulsador
  114.                    movf    PORTA, w        ; leer puerto A
  115.                    andlw   PORTA_ES        ; nos quedamos sólo con lo interesante
  116.                    btfsc   STATUS, Z       ; ¿Sigue pulsado? Lo está si RA4 == 0
  117.                    goto    Espera_levantar ; No, esperar
  118. ;
  119.                    goto    Principal
  120.  
  121.  
  122. ; ******************************************************************************
  123. ;; salida_hacia_A
  124. ;
  125. ; Según el valor del contador ([1-4]), lo transforma en otro, basado en una
  126. ; tabla y lo saca por el puerto A
  127. ;
  128.  
  129. salida_hacia_A:     call    transforma_contador
  130.                    movwf   PORTA           ; visualiza en puerto A
  131.                    return
  132.  
  133. transforma_contador:
  134.                    decf    contador,w      ; leemos el contador y le restamos 1
  135.                    addwf   PCL, f          ; saltamos dentro de la tabla
  136.  
  137. ;                            |76543210|
  138.                    retlw   b'00000010'
  139.                    retlw   b'00000101'
  140.                    retlw   b'00000110'
  141.                    retlw   b'00001001'
  142.  
  143. ; ******************************************************************************
  144. ;; incrementa_contador
  145. ;
  146. ; Incrementa el valor de la variable contador, entre 1 y 4, inclusives.
  147. ;
  148.  
  149. incrementa_contador:
  150.                    bcf     contador,2
  151.                    incf    contador
  152.                    call    Escribir_EEPROM ; Escribir dato en la EEPROM.
  153.                    return
  154.  
  155. ; ******************************************************************************
  156. ;; visualiza_contador
  157. ;
  158. ; Muestra el valor del contador en el display de 7 segmentos
  159. ;
  160.  
  161. visualiza_contador:
  162.                    movfw   contador        ; leemos contador
  163.                    call    w_a_digito      ; transformación a dígito 7 segmentos
  164.                    movwf   PORTB           ; visualiza en puerto B
  165.                    return
  166.  
  167. w_a_digito:         addwf   PCL, f          ; salta al dígito indexado por w
  168.  
  169. ;                            |76543210|
  170.                    retlw   b'00111111'     ; 0
  171.                    retlw   b'00000110'     ; 1
  172.                    retlw   b'01011011'     ; 2
  173.                    retlw   b'01001111'     ; 3
  174.                    retlw   b'01100110'     ; 4
  175.                    retlw   b'01101101'     ; 5
  176.                    retlw   b'01111101'     ; 6
  177.                    retlw   b'00000111'     ; 7
  178.                    retlw   b'01111111'     ; 8
  179.                    retlw   b'01101111'     ; 9
  180.  
  181. ; ----------------------------------------------------------------------------------------------------
  182. ; Espera = 100ms
  183. ; Frecuencia de reloj = 4Mhz
  184. ;
  185. ; Espera real = 0.1 segundos = 100000 ciclos
  186. ; Error = 0.00 %
  187.  
  188. Retardo_par:        udata_shr
  189.  
  190. Retardo_100ms_d1    res 1
  191. Retardo_100ms_d2    res 1
  192.  
  193.  
  194. Retardo_code:       code
  195.  
  196. Retardo_100ms:
  197.                                    ;99993 ciclos
  198.                    movlw   0x1E
  199.                    movwf   Retardo_100ms_d1
  200.                    movlw   0x4F
  201.                    movwf   Retardo_100ms_d2
  202.  
  203. Retardo_100ms_loop:
  204.                    decfsz  Retardo_100ms_d1, f
  205.                    goto    $+2
  206.                    decfsz  Retardo_100ms_d2, f
  207.                    goto    Retardo_100ms_loop
  208.  
  209.                                    ;3 ciclos
  210.                    goto    $+1
  211.                    nop
  212.  
  213.                                    ;4 ciclos (incluyendo la llamada)
  214.                    return
  215.  
  216. ; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
  217. ; ./delay_pic.pl -s Retardo_100ms 4Mhz 100ms
  218. ; mar 22 jul 2014 19:22:23 CEST
  219. ; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
  220. ; ----------------------------------------------------------------------------------------------------
  221.  
  222. ; ******************************************************************************
  223.  
  224. ;Subrutinas EEPROM -----------------------------------------------------------
  225.  
  226. Leer_EEPROM
  227.    BANKSEL EEADR           ; Selecciona el registro EEADR.
  228.    movf    contador, W
  229.    movwf   EEADR           ; Dato dirección de momoria a leer.
  230.    BANKSEL EECON1          ; Selecciona el banco EECON1.
  231.    bcf     EECON1, EEPGD    ; Punto a memoria de datos
  232.    bsf     EECON1, RD      ; a Leer.
  233.    BANKSEL EEDATA          ; Seleccionar banco de EEDATA.
  234.    movf    EEDATA, W       ; W = EEDATA.
  235.    BANKSEL PORTA
  236.    return
  237.  
  238. Escribir_EEPROM
  239.    BANKSEL EECON1          ; Selecciona banco de EECON1.
  240.    btfsc   EECON1, WR      ; Espera para escribir
  241.    goto    $-1             ; a completar.
  242.    BANKSEL EEADR           ; Selecciona el banco EEADR.
  243.    movf    contador, W
  244.    movwf   EEADR           ; Dirección dato de memoria a escribir.
  245.    BANKSEL EECON1          ; Selecciona el banco EECOn1.
  246.    bcf     EECON1, EEPGD   ; Punto a dato de memoria.
  247.    bsf     EECON1, WREN    ; Activar escritura.
  248.    bcf     INTCON, GIE     ; Desactiva interrupciones.
  249.  
  250. ; El fabricante especifica que hay que seguir esta secuencia para escritura en EEPROm.
  251.  
  252.    movlw   0x55
  253.    movwf   EECON2          ; Escribe 55h.
  254.    movlw   0xAA
  255.    movwf   EECON2          ; Escribe AAh.
  256.    bsf     EECON1, WR
  257.  
  258.    bsf     INTCON, GIE     ; Activa interrupciones.
  259.    bcf     EECON1, WREN    ; Desactiva escrituras.
  260.    BANKSEL PORTA
  261.    return
  262.  
  263.                END  

Lo que no me guarda nada.


Título: Re: Modificar este código a algo más complejo
Publicado por: MinusFour en 4 Agosto 2014, 22:36 pm
Hola:

Por lo que cuentas, falta vovler en Escribir_EEPROM volver al banco 00, justo antes del return.

Por ahora lo he hecho así. Creo, solo creo, que no hace falta usar dos direcciones, solo uno, el del contador.

Respecto a lo de seleccionar nuevamente el Banco 00 depende. Yo por lo general escribo a la memoria antes de entrar al loop del programa y al entrar al programa seleciono el banco 00.

No acabo de entender lo que quieres hacer con la EEPROM pero parece que quieres escribir el contador en la EEPROM. Tu rutina de escritura no especifica que informacion volcar en la EEPROM, simplemente la direccion.

Vaya lo que hace el PIC es basicamente escribir lo que haya EEDATA en la direccion EEADR, por eso necesitas usar las dos direcciones, una para especificar la direccion en donde guardar la informacion en la EEPROM y la otra para guardar la informacion en si.


Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 5 Agosto 2014, 04:11 am
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.


Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 8 Agosto 2014, 05:47 am
Hola:

Ahora me funciona todo.

Código
  1. ;
  2. ; Un pulsador en RA4 va incrementando un Contador, entre [1-4].
  3. ; La salida se envía a un display de 7 seg. en PORTB, y hacia salidas en PORTA.
  4. ; El Contador queda guardado en la EEPROM.
  5. ;
  6. ; (Contador)  |RB 76543210 |RA 76543210
  7. ; ------------|------------------------
  8. ;       1     |   00000011 |   00000010
  9. ;       2     |   00100100 |   00000101
  10. ;       3     |   00001100 |   00000110
  11. ;       4     |   00111100 |   00001001
  12. ;
  13. ; PORTA:
  14. ;  RA0 : OE1
  15. ;  RA1 : OE2
  16. ;  RA2 : A21
  17. ;  RA3 : AUX
  18. ;  RA4 : Pulsador
  19. ;
  20. ; PORTB : display de 7 segmentos. a = RB0
  21. ;
  22.  
  23. ;*******************************************************************************
  24. ; Listado y condiciones de ensamblado
  25.  
  26.    LIST    P=16F88           ; 4 Mhz
  27.    INCLUDE <P16F88.INC>
  28.    ;radix       hex
  29.    ERRORLEVEL  -302            ; Turn off banking message
  30.  
  31. ;*******************************************************************************
  32. ; Fusibles
  33.  
  34.    __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
  35.  
  36. ; _CP_OFF           : Protección de código
  37. ; _DEBUG_OFF        : Debug en circuito
  38. ; _WRT_PROTECT_OFF  : Protección a escritura en memoria de programa
  39. ; _CPD_OFF          : Protección de código de datos
  40. ; _LVP_OFF          : Programación en baja tensión
  41. ; _BODEN_OFF        : Reset por Brown-out
  42. ; _MCLRE_ON         : Reset por pin externo
  43. ; _PWRTE_ON         : Retraso al reset
  44. ; _WDT_OFF          : Watchdog
  45. ; _XT_OSC           : Oscilador externo del tipo XT
  46.  
  47.  
  48. ;*******************************************************************************
  49. ; Definiciones
  50.  
  51. ; Máscaras de E/S de los puertos. 0 = salida, 1 = entrada
  52. ;                    |76543210|
  53. #DEFINE PUERTO_A    b'00010000'
  54. #DEFINE PUERTO_B    b'00000000'
  55.  
  56. ; Incorporar sentencias de comprobación de la EEPROM
  57. #DEFINE test_eeprom 0
  58.  
  59. ;*******************************************************************************
  60. ; Variables
  61. Variables   UDATA_SHR
  62. Contador    RES 1                   ; Contador en la SRAM
  63.  
  64. ; ******************************************************************************
  65. ; EEPROM
  66.  
  67. ; Dirección del Contador dentro de la EEPROM
  68. EE_Contador EQU 0x02
  69.  
  70. ; Debemos desplazarnos a la zona de memoria más allá del 0x2100, que corresponde
  71. ; a la zona de la EEPROM en la mayoría de los PIC (ver documentación).
  72. ; Este valor es el que se grabará en la EEPROM en el momento de grabar el programa
  73. ; en el µcontrolador.
  74.    ORG     0x2100 + EE_Contador
  75.    DE      0x01                               ; valor inicial de ee_Contador
  76.  
  77. ;*******************************************************************************
  78.  
  79.    ORG    0x0000
  80.  
  81. Inicio
  82.    banksel ANSEL           ; bank 1
  83.    clrf    ANSEL           ; puerto A digital
  84.    movlw   PUERTO_A        ; definir E/S puerto A
  85.    movwf   TRISA
  86.    movlw   PUERTO_B        ; definir E/S puerto B
  87.    movwf   TRISB
  88.    movlw   b'01100000'     ; 4 MHz
  89.    movwf   OSCCON
  90.    call    EEPROM_LeeDato
  91.  
  92.  
  93. #if test_eeprom
  94. ; Comprobar que el Contador es correcto (esta parte es opcional)
  95.    decf    Contador, w     ; leemos el Contador y le quitamos 1
  96.    andlw   0x3             ; nos quedamos solo con los bits inferiores
  97.    addlw   0x1             ; volvemos a sumarle 1
  98.    movwf   Contador        ; y lo guardamos
  99. #endif
  100.    goto    Visualiza       ; ir a presentar
  101.  
  102. ; Bucle principal
  103. Principal
  104.    btfsc   PORTA, RA4      ; leer pulsador
  105.    goto    Principal       ; No, esperar
  106. ;
  107. ; Se ha pulsado el botón
  108.    call    incrementa_Contador
  109. Visualiza
  110.    call    visualiza_Contador
  111.    call    salida_hacia_A
  112.  
  113. ; Esperar liberación del botón
  114. Espera_levantar
  115.    call    Retardo_100ms   ; Esperar la suelta del botón
  116.  
  117.    btfss   PORTA, RA4      ; leer pulsador
  118.    goto    Espera_levantar ; No, esperar
  119.  
  120. ; Repetir
  121.    goto    Principal
  122.  
  123.  
  124. ; ******************************************************************************
  125. ;; salida_hacia_A
  126. ;
  127. ; Según el valor del Contador ([1-4]), lo transforma en otro, basado en una
  128. ; tabla y lo saca por el puerto A
  129. ;
  130.  
  131. salida_hacia_A
  132.    call    transforma_Contador
  133.    movwf   PORTA           ; visualiza en puerto A
  134.    return
  135.  
  136. transforma_Contador
  137.    decf    Contador, w     ; leemos el Contador y le restamos 1
  138.    addwf   PCL, f          ; saltamos dentro de la tabla
  139.  
  140.    ;                            |76543210|
  141.    retlw   b'00000010'
  142.    retlw   b'00000101'
  143.    retlw   b'00000110'
  144.    retlw   b'00001001'
  145.  
  146. ; ******************************************************************************
  147. ;; incrementa_Contador
  148. ;
  149. ; Incrementa el valor de la variable Contador, entre 1 y 4, inclusives.
  150. ;
  151.  
  152. incrementa_Contador
  153.    bcf     Contador, 2     ; Si el Contador valía 4, ahora vale 0
  154.    incf    Contador, f     ; Incrementa el Contador
  155.    call    EEPROM_EscribeDato
  156.  
  157. ; ******************************************************************************
  158. ;; visualiza_Contador
  159. ;
  160. ; Muestra el valor del Contador en el display de 7 segmentos
  161. ;
  162.  
  163. visualiza_Contador
  164.    movfw   Contador        ; leemos Contador
  165.    call    w_a_digito      ; transformación a dígito 7 segmentos
  166.    movwf   PORTB           ; visualiza en puerto B
  167.    return
  168.  
  169. w_a_digito         addwf   PCL, f          ; salta al dígito indexado por w
  170.  
  171. ;            |76543210|
  172.    retlw   b'00111111'     ; 0
  173.    retlw   b'00000110'     ; 1
  174.    retlw   b'01011011'     ; 2
  175.    retlw   b'01001111'     ; 3
  176.    retlw   b'01100110'     ; 4
  177.    retlw   b'01101101'     ; 5
  178.    retlw   b'01111101'     ; 6
  179.    retlw   b'00000111'     ; 7
  180.    retlw   b'01111111'     ; 8
  181.    retlw   b'01101111'     ; 9
  182.  
  183. ; ----------------------------------------------------------------------------------------------------
  184. ; Espera = 100ms
  185. ; Frecuencia de reloj = 4Mhz
  186. ;
  187. ; Espera real = 0.1 segundos = 100000 ciclos
  188. ; Error = 0.00 %
  189.  
  190. Retardo_var        udata_shr
  191.  
  192. Retardo_100ms_d1    res 1
  193. Retardo_100ms_d2    res 1
  194.  
  195. Retardo_code       code
  196.  
  197. Retardo_100ms
  198. ;99993 cycles
  199. movlw 0x1E
  200. movwf Retardo_100ms_d1
  201. movlw 0x4F
  202. movwf Retardo_100ms_d2
  203. Retardo_100ms_0
  204. decfsz Retardo_100ms_d1, f
  205. goto $+2
  206. decfsz Retardo_100ms_d2, f
  207. goto Retardo_100ms_0
  208.  
  209. ;3 cycles
  210. goto $+1
  211. nop
  212.  
  213. ;4 cycles (including call)
  214. return
  215.  
  216. ; ******************************************************************************
  217.  
  218. ; Leer valor del Contador en la EEPROM
  219. EEPROM_LeeDato
  220.    banksel EEADR           ; bank 2
  221.    movlw   EE_Contador     ; dirección de la EEPROM a leer
  222.    movwf   EEADR
  223.  
  224.    banksel EECON1          ; bank 3
  225.    bcf     EECON1, EEPGD   ; acceso a la memoria de datos
  226.    bsf     EECON1, RD      ; inicia la lectura
  227.  
  228.    banksel EEDATA          ; bank 2
  229.    movf    EEDATA, w       ; dato leído en W
  230.    movwf   Contador        ; guardar en SRAM
  231.    ;
  232.    banksel PORTA           ; bank 0, durante el programa
  233.    return
  234.  
  235. ; Escribe el Contador en la EEPROM
  236. EEPROM_EscribeDato
  237.    banksel EECON1          ; bank 3
  238.    btfsc   EECON1, WR      ; esperar para poder escribir
  239.    goto    $-1
  240.  
  241.    banksel EEADR           ; bank 2
  242.    movlw   EE_Contador     ; dirección donde vamos a escribir
  243.    movwf   EEADR
  244.  
  245.    movf    Contador, w     ; el valor que vamos a escribir
  246.    movwf   EEDATA
  247.  
  248.    banksel EECON1          ; bank 3
  249.    bcf     EECON1, EEPGD   ; acceso a la memoria de datos
  250.    bsf     EECON1, WREN    ; activa la escritura
  251.  
  252.    ;                    bcf     INTCON, GIE     ; desactivar interrupciones
  253.  
  254.    movlw   b'01010101'     ; valores mágicos (requeridos)
  255.    movwf   EECON2
  256.    movlw   b'10101010'
  257.    movwf   EECON2
  258.  
  259.    bsf     EECON1, WR      ; comienza la escritura
  260.  
  261.    ;                    bsf     INTCON, GIE     ; reactiva interrupciones
  262.  
  263.    bcf     EECON1, WREN    ; desactiva escrituras
  264.  
  265.    banksel PORTA           ; volvemos a bank 0
  266.    return
  267.                    END
  268.  
  269.  
  270.  

Gracias por tu tiempo.  :D


Título: Re: Modificar este código a algo más complejo
Publicado por: Meta en 15 Agosto 2014, 09:44 am
Buenas:

Voy hacerles una pregunta. Sobre el código de arriba quiero hacer algo parecido del PIC16F88  (http://"http://ww1.microchip.com/downloads/en/DeviceDoc/30487D.pdf")al PIC16F630 (http://"http://ww1.microchip.com/downloads/en/DeviceDoc/40039F.pdf") para saber si realmente funciona. Hablo de adaptación del código y usando un decodificador 74LS48 (http://"https://www.physics.rutgers.edu/ugrad/327/sn74ls48rev5.pdf").

Transformar este esquema...
(http://www.subeimagenes.com/img/gif-1045078.gif)

Con este otro.
(http://www.subeimagenes.com/img/picd-1045168.png)
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 (http://"http://ww1.microchip.com/downloads/en/DeviceDoc/30487D.pdf") y si el PIC16F630 (http://"http://ww1.microchip.com/downloads/en/DeviceDoc/40039F.pdf") junto con el decodificador de 7 segmentos 74LS48 (http://"https://www.physics.rutgers.edu/ugrad/327/sn74ls48rev5.pdf").

Partiendo del código de abajo del PIC16F88 para analizarlo 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.
; 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
(http://www.subeimagenes.com/img/coor-1058681.png)

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.