Autor Tema: GUARDAR Y LEER MEMORIA EPROM  (Leído 697 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado JOSE YC

  • PIC10
  • *
  • Mensajes: 3
GUARDAR Y LEER MEMORIA EPROM
« en: 19 de Febrero de 2021, 20:12:39 »
Código: QBasic/QuickBASIC
  1.  

Hola lo que pasa es que me dejaron un trabajo donde me piden guardar 16 números de 4 dígitos en el programa de MicroCode Studio con PIC16F84A en un 7-SEG-MPX4-CC logre hacer el siguiente código: 


DEFINE OSC 4
TRISA  = %11111
TRISB  = %00000000
N VAR BYTE [4] : A1 VAR BYTE : AUX1 VAR BYTE : D1 VAR BYTE : V VAR BYTE
C VAR BYTE [4]  : I VAR BYTE : TIEMPO VAR BYTE : A2 VAR BYTE : AUX2 VAR BYTE
A3 VAR BYTE : AUX3 VAR BYTE : A4 VAR BYTE : AUX4 VAR BYTE : X VAR BYTE
PUNT VAR BYTE : POS VAR BYTE : : NUM VAR WORD : A5 VAR BYTE : AUX5 VAR BYTE
C[0]= 0 : C[1]= 1 : C[2]= 2 : C[3]= 3
N[0]= 0 : N[1]= 0 : N[2]= 0 : N[3]= 0
INICIO:
A1= PORTA.0 : A2= PORTA.1
A3 = PORTA.2 : A4 = PORTA.3 : A5 = PORTA.4
TIEMPO= TIEMPO+1
     IF A1=1 and AUX1 =0 THEN
       D1 = D1 +1
       IF D1=10 THEN D1=0
     ENDIF
     
       IF A2=1 AND AUX2 =0 THEN
       IF D1!=0 THEN D1=0
       V = V +1
       PUNT = PUNT +1
       IF V=2 THEN V=1
       IF PUNT=5 THEN PUNT=1
     ENDIF
     
     IF PUNT=1 AND TIEMPO=100 AND V!=0 THEN N[0]= D1
     IF PUNT=2 AND TIEMPO=100 AND V!=0 THEN N[1]= D1
     IF PUNT=3 AND TIEMPO=100 AND V!=0 THEN N[2]= D1
     IF PUNT=4 AND TIEMPO=100 AND V!=0 THEN N[3]= D1
     
     IF A3=1 AND AUX3=0 THEN
         V = V + 1
         IF POS = 16 THEN POS =0
         IF V=2 THEN V=1
         POS = POS +1
     ENDIF
     IF A4=1 AND AUX4=0 THEN
          V = V + 1
          IF V=2 THEN V=1
     ENDIF
     '
     '
     '
     IF V!= 0 AND TIEMPO= 100 THEN
     GOSUB OBTNUM
     WRITE POS,NUM
     ENDIF
     '
     '
     ' 
     IF A5=1 AND AUX5=0 THEN
          V = V + 1
          IF V=2 THEN V=1
     ENDIF
        IF V!= 0 AND TIEMPO= 100 THEN
     READ 0,NUM
          GOSUB OBTNN
     ENDIF
      IF TIEMPO= 100 THEN TIEMPO=0
      PORTB = N + C*16
      I = I +1
      IF I=4 THEN I=0
 AUX31= A1 : AUX2 = A2
 AUX3 = A3 : AUX4 = A4 : AUX5 = A5
GOTO INICIO

 OBTNN:
FOR X =0 TO 3
N[X]= NUM//10
NUM = NUM/10
NEXT X
RETURN
OBTNUM:
  NUM =  N[0] + N[1]*10 + N[2]*100 + N[3]*1000
RETURN




EL BOTON A1 = AUMENTA EN UNO EL DECODER
EL BOTON A2 = LA POS DEL DECODER U,D,C,UM
EL BOTON A3 = INDICA LA POS EN DONDE QUIERES GUARDAR
EL BOTON A4 = GUARDA EL DATO EN LA EEPROM



Me sale un error el siguiente:
Error[113] c:\users\jerson\desktop\unt\cuarto∼1\progra∼1\insyala\pbp\pbppic14.lib 607:symbol not previously defined(WRITE)
Error[113] c:\users\jerson\desktop\unt\cuarto∼1\progra∼1\insyala\pbp\pbppic14.lib 661:symbol not previously defined(WRITE)

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1237
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #1 en: 19 de Febrero de 2021, 21:15:20 »
Que tal JOSE YC,

Antes que nada bienvenido al foro.
La manera en que estás intentando usar el READ y WRITE noes correcto. Si ves el manual del lenguaje PBP, verás que el dato que intentas guardad (NUM) es de tipo word, pero el manual claramente dice que la instrucción funciona solamente con variables tipo BYTE. Por lo que si quieres guardar una variable del tipo WORD necesitas descomponerla en dos(parte alta y parte baja). Como lo indica el manual:

To write a word, each of the 2 bytes that make up the word must be written separately:

w Var Word
WRITE 0,w.BYTE0
WRITE 1,w.BYTE1

Espero esto te sirva para resolver tu problema.

elreypic.

P.D Si pudieras colocar tu esquemático para entender mejor lo que intentas hacer.

Desconectado JOSE YC

  • PIC10
  • *
  • Mensajes: 3
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #2 en: 19 de Febrero de 2021, 21:35:07 »
Como seria entonces dividir ese numero :'v
acá esta mi esquema

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1237
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #3 en: 20 de Febrero de 2021, 12:02:50 »
Que tal JOSE YC,

Analizando tu código este es completamente disfuncional. Es decir no hace lo que tú supones debiera hacer.
Puedo ver definitivamente que estás iniciando con los microcontroladores PIC y el lenguaje Basic de PBP.
Tienes que hacer parte por parte.
Primero realiza un programa que muestre en tu display de 4 dígitos y 7 segementos un número de 4 dígitos cualquiera, digamos: 1234.
Una vez que tengas eso graba ese dato en la eeprom, puedes manejar el dato de tres formas diferentes:
1) En su forma hexadecimal. Esto implica tener una variable de tipo WORD (16-bits). Si usas el como ejemplo el número 1234 (decimal) usa la instrucción:

DATA @0,$D2,$04   'Guarda desde la dirección 0x00 de la eeprom el número 1234 en su valor hexadecimal (parte baja en 0x00)

2) Usar codificación BCD, lo que significa que si grabas el número 1234, en su BCD sería $1234, por lo tanto lo guardaría en la eeprom de la siguiente manera:

DATA @0,$34,$12

3) Usar codificación BCD y grabar cada dígito en una dirección individual, esto es, si el numero es 1234, entonces lo guardarías de la siguiente manera:

DATA @0,$04,$03,$02,$01

Ya que te inicias en esto, yo te recomiendo usar la tercera forma, ya que prácticamente no necesitas procesar el número solamente leerlo y mostrarlo.
Las opciones 1 y 2 necesitas procesar el numero grabado en la eeprom y después mostrarlo.

Resumiendo:

1) Realiza tu primer código en el que despliegas en el display el número 1234 (o cualquier otro número de 4 digitos que elijas)
2) Realiza un segundo código en que guardas en la eeprom un número, lo lees y lo muestras en el display.

Estos serían nuestros primeros pasos. Una vez que tengas esto, entonces seguimos con la siguiente parte.

elreypic.

P.S Como recomendación es muy importante que comentes tu código para hacerlo más legible.

Desconectado JOSE YC

  • PIC10
  • *
  • Mensajes: 3
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #4 en: 20 de Febrero de 2021, 14:57:00 »
Muchas gracias por la ayuda, logre hacer que se guarde dividiendo el numero en 2 por ejemplo si el numero 1234 entonces lo separo en 12 y 34 y luego lo vuelvo a unir multiplicando al 12 por 100 y sumándole el 34 y lo paso a un arreglo para mostrarlo con el siguiente código

define OSC 4
TRISA  = %11111
TRISB  = %00000000
N VAR BYTE [4] : A1 VAR BYTE : AUX1 VAR BYTE : D1 VAR BYTE
C VAR BYTE [4]  : I VAR BYTE : TIEMPO VAR BYTE : A2 VAR BYTE : AUX2 VAR BYTE
A3 VAR BYTE : AUX3 VAR BYTE : A4 VAR BYTE : AUX4 VAR BYTE : X VAR BYTE : V2 VAR BYTE
PUNT VAR BYTE : POS VAR BYTE : V3 VAR BYTE : V4 VAR BYTE
NUM2 VAR word : VA VAR BYTE : VA2 VAR BYTE  : VA3 VAR BYTE : VA4 VAR BYTE
 A5 VAR BYTE : AUX5 VAR BYTE
C[0]= 0 : C[1]= 1 : C[2]= 2 : C[3]= 3
N[0]= 0 : N[1]= 0 : N[2]= 0 : N[3]= 0
POS =-2
INICIO:
a1 = PORTA.0 : a2 = PORTA.1
A3 = PORTA.2 : A4 = PORTA.3 : A5 = PORTA.4
tiempo = tiempo +1
IF a1=1 and aux1=0 then
       D1 = D1 +1
       IF D1=10 THEN D1=0
     endif
     
      IF a2=1 and aux2=0 then
       IF D1!=0 THEN D1=0
       PUNT = PUNT +1
       IF PUNT=5 THEN PUNT=1
     endif
      IF A3=1 and AUX3=0 then
         V2 = V2 + 1
         if POS = 32 then POS =-2
         IF V2=2 THEN V2=1
         POS = POS + 2
     endif
     IF A4=1 and AUX4=0 then
          V3 = V3 + 1
          IF V3=2 THEN V3=1
     endif   
      IF A5=1 and AUX5=0 then
          V4 = V4 + 1
          IF V4=2 THEN V4=1
     endif
     IF PUNT=1 aND TIEMPO=100 THEN N[0]= D1
     IF PUNT=2 aND TIEMPO=100 THEN N[1]= D1
     IF PUNT=3 aND TIEMPO=100 THEN N[2]= D1
     IF PUNT=4 aND TIEMPO=100 THEN N[3]= D1
     
      if v3!= 0 and tiempo = 100 then
     GOSUB OBTNUM
     VA3 = NUM2/100
     VA4 = NUM2//100
     WRITE POS,VA3
     WRITE POS+1,VA4
     endif
     
     if v4!= 0 and tiempo = 100 then
          READ POS,va
          read POS+1,va2
          num2 = VA*100 + VA2
     endif
     
      if tiempo = 100 then tiempo =0
      PORTB = N + C*16
      i = I +1
      IF I=4 THEN I=0
aux1 = A1 : AUX2 = A2
 AUX3 = A3 : AUX4 = A4 : AUX5 = A5
GOTO INICIO

 OBTNN:
 FOR X =0 TO 3
N[X]= NUM2//10
NUM2 = NUM2/10
NEXT X
return
OBTNUM:
  NUM2 =  N[0] + N[1]*10 + N[2]*100 + N[3]*1000
RETURN


pero cada ves que le digo que me muestre una posición en donde no he guardado nada me sale el numero 5755 y no se por que y quisiera que no salga ese numero si no el 0000, pienso que debería inicializar las 32 posiciones que utilizo en 0 pero no se como

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1237
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #5 en: 20 de Febrero de 2021, 17:04:32 »
Que tal JOSE YC,

Podrías indicarme paso a paso el funcionamiento de tu circuito, no logro entender cómo es que funciona.
Es decir, supongamos que quieres comenzar a grabar un número de 4 dígitos, ¿cuál es el procedimiento que sigues?
Y si lo quieres mostrar, ¿cuál es el procedimiento?

elreypic

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 552
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #6 en: 20 de Febrero de 2021, 17:15:59 »
La manera más eficiente de manejar una cifra de 16 bits en la eeprom es:


Grabar:
 
Posición de eeprom 1 = valor16bits / 256.   ( byte alto)
Posición de eeprom 2 = valor16bits % 256   ( byte bajo).

Leer:

 Valor16bits = (posición de eeprom 1 * 256 ) + posición de eeprom 2


La opción del BCD es válida también, en mi opinión lo suyo es 2 dígitos por byte (1 nibble por dígito).

 Así 2 bytes = 4 dígitos. 

  Ambos casos requieren procesamiento. Creo que lo más eficiente es lo primero.  Es más lento pero como no vas a estar grabando y leyendo constanmemte (por que eso no se puede hacer con la eeprom si no quieres que te dure 1/4 de hora) pues no te importa que sea más lento.
 

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1237
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #7 en: 24 de Febrero de 2021, 23:00:33 »
Que tal JOSE YC,

No sé si todavía estés trabajando en este proyecto, pero quiero compartirte un pequeño código en el que predefino los 16 valores de cuatro dígitos en la memoria EEPROM del microcontrolador y que cada vez que presiono el pulsador conectado a RA4, muestra cada uno de eso valores en el display (los cuatros dígitos en forma multiplexada, por loque vez el número completo en tu display, no como en tu caso que solo vez un dígito a la vez).
Le he agregado los comentarios par que te sea muy legible y a la vez para que tengas la idea de cómo es que esta es un práctica extremadamente recomendada a la hora realizar nuestro códigi fuente (eso aplica a caulquier lenguaje de programación).

El ejemplo solo realiza la lectura, NUNCA la escritura de los datos.

Código: [Seleccionar]
'****************************************************************
'*  Name    : MYNUM.PBP                                         *
'*  Author  : "elreypic"                                        *
'*  Notice  : Copyright (c) 2021                                *
'*          : All Rights Reserved                               *
'*  Date    : 2/24/2021                                         *
'*  Version : 1.0                                               *
'*  Notes   : Microcontroller: PIC16F84A                        *
'*          : Crystal: 4MHz                                     *
'****************************************************************
define OSC 4            'Define el valor del cristal u oscilador a utilizar (4MHz)

'******************************************************************************
'               Predefinición de datos en la EEPROM
'******************************************************************************
DATA    @0,$12,$34      'Predefine en la EEPROM el primer valor a desplegar
DATA    @2,$56,$78      'Predefine en la EEPROM el segundo valor a desplegar
DATA    @4,$90,$12      'Predefine en la EEPROM el tercer valor a desplegar
DATA    @6,$34,$56      'Predefine en la EEPROM el cuarto valor a desplegar
DATA    @8,$78,$90      'Predefine en la EEPROM el quinto valor a desplegar
DATA    @10,$00,$00     'Predefine en la EEPROM el sexto valor a desplegar
DATA    @12,$98,$76     'Predefine en la EEPROM el séptimo valor a desplegar
DATA    @14,$54,$32     'Predefine en la EEPROM el octavo valor a desplegar
DATA    @16,$10,$01     'Predefine en la EEPROM el noveno valor a desplegar
DATA    @18,$23,$45     'Predefine en la EEPROM el décimo valor a desplegar
DATA    @20,$67,$89     'Predefine en la EEPROM el undécimo valor a desplegar
DATA    @22,$01,$23     'Predefine en la EEPROM el duodécimo valor a desplegar
DATA    @24,$45,$67     'Predefine en la EEPROM el décimo tercer valor a deplegar
DATA    @26,$89,$00     'Predefine en la EEPROM el décimo cuarto valor a desplegar
DATA    @28,$11,$11     'Predefine en la EEPROM el décimo quinto valor a desplegar
DATA    @30,$22,$22     'Predefine en la EEPROM el décimo sexto valor a desplegar

'****************************************************************************************
'               DEFINICION DE PUERTOS Y BITS DE REGISTROS
'****************************************************************************************
READ_SW     VAR PORTA.4

'********************************************************************
'                   Definición de variables
'********************************************************************
NUMERO  VAR BYTE[4]    'Array para mostrar el valor en el display
UNIDAD  VAR BYTE    'Variable que contiene le valor de las unidades
DECENA  VAR BYTE    'Variable que contiene el valor de las decenas
CENTENA VAR BYTE    'Variable que contiene el valor de las centenas
MILLAR  VAR BYTE    'Variable que contiene el valor de los millares
DIGITO  VAR BYTE    'Variable auxiliar para desplegar uno de los dígitos
BYTE_ALTO   VAR BYTE    'Variable que contiene la parte alta del dato leido de la EEPROM
BYTE_BAJO   VAR BYTE    'Variable que contiene la parte baja del dato leido de la EEPROM
I       VAR BYTE    'Variable auxiliar para el ciclo FOR
EE_ADDRESS   VAR BYTE    'Variable que contiene la dirección a leer de la EEPROM
FLAG_READ   VAR bit 'Bandera para indicar que se ha presionado el botón de lectura

'****************************************************************************************
'               DEFINICION DE CONSTANTES
'****************************************************************************************
MAX_EE_ADDRESS  CON 32

'******************************************************************************
'                       INICIO DE PROGRAMA PRINCIPAL
'******************************************************************************
INI:
    TRISA  = %11111     'Define el puerto A como entrada
    TRISB  = %00000000  'Define el Puerto B como salida
    DIGITO = 16         'Valor para el primer dígito (Unidades)
    EE_ADDRESS = 0      'Inicializa la dirección 0x00 de la EEPROM
    FLAG_READ = 0       'Inicializa la bandera del botón de lectura
INICIO:
    IF  READ_SW = 1 AND FLAG_READ = 0 then    'Se ha presionado el boton de leer la EEPROM?
        FLAG_READ = 1       'Levanta la bandera de botón de lectura
        EE_ADDRESS = EE_ADDRESS + 2    'Incrementa el valor de la dirección
        IF EE_ADDRESS = MAX_EE_ADDRESS then   'Se ha alcanzado la dirección máxima disponible?
            EE_ADDRESS = 0      'Sí, entonces regresa a leer la dirección 0x00
        ENDIF
    endif 
    READ    EE_ADDRESS,BYTE_ALTO    'Lee la parte alta del dato en la EEPROM
    READ    EE_ADDRESS+1,BYTE_BAJO  'Lee la parte baja del dato en la EEPROM
    NUMERO[3] = (BYTE_ALTO & $F0)>>4    'Decodifica los millares
    NUMERO[2] = BYTE_ALTO & $0F     'Decodifica las centenas
    NUMERO[1] = (BYTE_BAJO & $F0)>>4    'Decodifica las decenas
    NUMERO[0] = BYTE_BAJO & $0F     'Decodifica las unidades
KEEP_DISP:
    GOSUB   DISPLAY_NUM     'Llama la subrutina para desplegar el dato en el display
    IF READ_SW = 1 AND FLAG_READ = 1 then
        GOTO    KEEP_DISP   'Si sigue presionado el botón de lectura continua el despliegue
    ELSE                'No, entonces:
        FLAG_READ = 0   'Baja la bandera del botón de lectura
        PAUSE   10      'No, entonces espera 10ms para eliminar rebotes
    ENDIF
    GOTO    INICIO  'Regresa a inicio
   
'********************************************************************
'                       Inicio de Subrutinas
'********************************************************************

'********************************************************************
'   Subrutina para desplegar el valor de 4 dígitos en el display
'   Nonmbre de la subrutina: DISPLAY_NUM
'   Entradas:   UNIDAD, DECENA, CENTENA, MILLAR
'   Salidas:    Ninguna
'********************************************************************
DISPLAY_NUM:
    DIGITO = 16         'Valor para el primer dígito (Unidades)
    for I=0 TO 3    'Realiza un ciclo FOR para mostrar cada uno de los 4 dígitos en el display en forma multiplexada
        PORTB = (DIGITO*i)+ NUMERO[I]   'Muestra en el puerto B el valor de un dígito y habilítalo
        PAUSE   1   'Manten el dígito encendido por 1ms
    NEXT    I   'Muestra el siguiente dígito
    RETURN      'Termina la subrutina
   

He usado el mismo esquemático que has proveído y lo he simulado en proteus para que lo puedas probar.

saludos

elreypic.

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1237
Re:GUARDAR Y LEER MEMORIA EPROM
« Respuesta #8 en: 26 de Febrero de 2021, 10:28:46 »
Que tal JOSE YC,

Espero que sigas trabajando con este proyecto de lo contrario habré gastado mi tiempo en vano. Jejeje.

De cualquier manera te comparte el código que he realizado para poder grabar los 16 números de 4 digitos en la memoria EEPROM y mostrarlos en un display de cuatro dígitos de 7 segmentos.
Este poseé 5 interruptores de tipo push conectados con resistencias de pull down:

1)READ (conectado al puerto RA.4)
2)PROGRAM (conectado al puerto RA.3)
3)UP (Conectado el puerto RA.2)
4)DIGIT (conectado al puerto RA.1)
5)ENTER (conetacto al puerto RA0).

El botón de READ tiene la función de mostrar el numero grabado en la EEPROM y cada vez que se presiona te muestra el siguiente número grabado en la EEPROM

El botón de PROGRAM hace que el circuito opere en modo de programación desde la última posición o número que estabas visualizando. Sabrás que este modo está activo porque solo muestra un dígito a la vez, comenzado por los millares de modo que al presionar el botón UP, incrmentas en uno el valor mostrado (0 a 9). Una vez seleccionado el número deseado, presionas el botón DIGIT para moverte al siguiente digito (centanas, decenas y unidades respectivamente). El presionar el botón ENTER ese valor que ya has seleccionado en tus cuatro digitos se guardará en esa posición actual. Si por alguna razón necesitas cancelar la operación, solamente presionas el botón de READ y regresará al modo de lectura y despliegue del numero en la EPPROM.

Saludos y espero que esto te ayudo a aprender mejor el lenguaje Basic del compilador PBP.

Código: [Seleccionar]
'****************************************************************
'*  Name    : MYNUM.PBP                                         *
'*  Author  : "elreypic"                                        *
'*  Notice  : Copyright (c) 2021                                *
'*          : All Rights Reserved                               *
'*  Date    : 2/25/2021                                         *
'*  Version : 1.0                                               *
'*  Notes   : Microcontroller: PIC16F84A                        *
'*          : Crystal: 4MHz                                     *
'****************************************************************
define OSC 4            'Define el valor del cristal u oscilador a utilizar (4MHz)

'******************************************************************************
'               Predefinición de datos en la EEPROM
'******************************************************************************
DATA    @0,$12,$34      'Predefine en la EEPROM el primer valor a desplegar
DATA    @2,$56,$78      'Predefine en la EEPROM el segundo valor a desplegar
DATA    @4,$90,$12      'Predefine en la EEPROM el tercer valor a desplegar
DATA    @6,$34,$56      'Predefine en la EEPROM el cuarto valor a desplegar
DATA    @8,$78,$90      'Predefine en la EEPROM el quinto valor a desplegar
DATA    @10,$00,$00     'Predefine en la EEPROM el sexto valor a desplegar
DATA    @12,$98,$76     'Predefine en la EEPROM el séptimo valor a desplegar
DATA    @14,$54,$32     'Predefine en la EEPROM el octavo valor a desplegar
DATA    @16,$10,$01     'Predefine en la EEPROM el noveno valor a desplegar
DATA    @18,$23,$45     'Predefine en la EEPROM el décimo valor a desplegar
DATA    @20,$67,$89     'Predefine en la EEPROM el undécimo valor a desplegar
DATA    @22,$01,$23     'Predefine en la EEPROM el duodécimo valor a desplegar
DATA    @24,$45,$67     'Predefine en la EEPROM el décimo tercer valor a deplegar
DATA    @26,$89,$00     'Predefine en la EEPROM el décimo cuarto valor a desplegar
DATA    @28,$11,$11     'Predefine en la EEPROM el décimo quinto valor a desplegar
DATA    @30,$22,$22     'Predefine en la EEPROM el décimo sexto valor a desplegar

'****************************************************************************************
'               DEFINICION DE PUERTOS Y BITS DE REGISTROS
'****************************************************************************************
READ_SW     VAR PORTA.4     'Pulsador para leer y mostrar los datos almacenados en la EEPROM
PROG_SW     VAR PORTA.3     'Pulsador para colocar el sistema en modo de programación
UP_SW       VAR PORTA.2     'Pulsador para incrementar el valor del número mostrado en el display
DIGI_SW     VAR PORTA.1     'Pulsador para cambiar entre los digitos mostrados en el display
ENTER_SW    VAR PORTA.0     'Pulsador de ENTER para realizar la grabación del número de 4 dígitos

'********************************************************************
'                   Definición de variables
'********************************************************************
NUMERO  VAR BYTE[4]    'Array para mostrar el valor en el display
BYTE_ALTO   VAR BYTE    'Variable que contiene la parte alta del dato leido de la EEPROM
BYTE_BAJO   VAR BYTE    'Variable que contiene la parte baja del dato leido de la EEPROM
I       VAR BYTE    'Variable auxiliar para el ciclo FOR
EE_ADDRESS   VAR BYTE    'Variable que contiene la dirección a leer de la EEPROM
FLAG_READ   VAR bit 'Bandera para indicar que se ha presionado el botón de lectura

'****************************************************************************************
'               DEFINICION DE CONSTANTES
'****************************************************************************************
MAX_EE_ADDRESS  CON 32      'Dirección límite de acceso a la EEPROM
DIGITO          CON 16      'Valor inicial del digito a mostrar

'******************************************************************************
'                       INICIO DE PROGRAMA PRINCIPAL
'******************************************************************************
INI:
    TRISA  = %11111     'Define el puerto A como entrada
    TRISB  = %00000000  'Define el Puerto B como salida
    EE_ADDRESS = 0      'Inicializa la dirección 0x00 de la EEPROM
    FLAG_READ = 0       'Inicializa la bandera del botón de lectura
INICIO:
    IF  READ_SW = 1 AND FLAG_READ = 0 then    'Se ha presionado el boton de leer la EEPROM?
        FLAG_READ = 1       'Levanta la bandera de botón de lectura
        EE_ADDRESS = EE_ADDRESS + 2    'Incrementa el valor de la dirección
        IF EE_ADDRESS = MAX_EE_ADDRESS then   'Se ha alcanzado la dirección máxima disponible?
            EE_ADDRESS = 0      'Sí, entonces regresa a leer la dirección 0x00
        ENDIF
    endif
CANCEL_PROG: 
    READ    EE_ADDRESS,BYTE_ALTO    'Lee la parte alta del dato en la EEPROM
    READ    EE_ADDRESS+1,BYTE_BAJO  'Lee la parte baja del dato en la EEPROM
    NUMERO[3] = (BYTE_ALTO & $F0)>>4    'Decodifica los millares
    NUMERO[2] = BYTE_ALTO & $0F     'Decodifica las centenas
    NUMERO[1] = (BYTE_BAJO & $F0)>>4    'Decodifica las decenas
    NUMERO[0] = BYTE_BAJO & $0F     'Decodifica las unidades
KEEP_DISP:
    GOSUB   DISPLAY_NUM     'Llama la subrutina para desplegar el dato en el display
    IF READ_SW = 1 AND FLAG_READ = 1 then
        GOTO    KEEP_DISP   'Si sigue presionado el botón de lectura continua el despliegue
    ELSE                'No, entonces:
        FLAG_READ = 0   'Baja la bandera del botón de lectura
        PAUSE   10      'No, entonces espera 10ms para eliminar rebotes
    ENDIF
'**********************************************************
'                   MODO DE PROGRAMACION
'**********************************************************
    if  PROG_SW = 0 THEN 'Se ha presionado el botón de modo de programación?
        GOTO    INICIO  'No, entonces regresa a inicio
    ENDIF
    I = 3   'Variable para indicar el dígito de los millares
    PORTB = (DIGITO*i) + NUMERO[I] 'Muestra el valor del dígito correspondiente del display
    while PROG_SW = 1   'Realiza delays de 20ms hasta que el botón de programación
        PAUSE 20        'sea liberado
    WEND
    PAUSE 20            'Realiza delay de 20ms para eliminar rebotes
PROGRAMA_DATO:
    If UP_SW = 1 THEN   'Se ha presionado el botón de incrementar en uno el valor mostrado?
        numero[i] = numero[i] + 1 'Sí, entonces incrementa el valor en 1 del valor mostrado
        if numero[i] > 9 then  'El valor alcanzado es mayor a 9?
            numero[i] = 0      'Reinicia el valor en 0
        endif
        PORTB = (digito*i) + numero[i]    'Muestra el valor del digito correspondiente del display
        WHILE UP_SW = 1     'Mientras esté presionado el botón de incrementar el valor en 1
            PAUSE 20        'realiza delays de 20ms hasta que se libere
        WEND
        PAUSE 20    'Una vez que se ha liberado realiza delay de 20ms para eliminar rebotes
    endif
    IF  DIGI_SW = 1 then
        I=I-1       'Decrementa la variable del digito a mostrar
        If I=255 THEN   'Se ha alcanzado el límite inferior?
            I = 3   'Sí, entonces asigna la variable del digito a mostrar en 3 para visualizar los millares
        endif
        PORTB = (digito*i) + numero[i]    'Muestra el valor del digito correspondiente del display
        WHILE DIGI_SW = 1   'Mientras el botón de cambio de digito este presionado, realiza delays de 20ms
            PAUSE 20
        WEND
        PAUSE 20    'Una vez liberado realiza un delay de 20ms para eliminar rebotes
    ENDIF
    IF ENTER_SW = 1 then    'Se ha presionado el botón de ENTER
        BYTE_ALTO = (NUMERO[3]<<4) | Numero[2]  'Prepara el byte alto a grabar en la EEPROM
        BYTE_BAJO = (NUMERO[1]<<4) | NUMERO[0]  'Prepara el byte bajo a grabar en la EEPROM
        WRITE EE_ADDRESS,BYTE_ALTO      'Graba en la EEPROM la parte alta del valor
        WRITE EE_ADDRESS+1,BYTE_BAJO    'Graba en la EEPROM la parte baja del valor
        WHILE ENTER_SW = 1  'Mientras esté presiondo el botón del ENTER
            PAUSE 20        'realiza delays de 20ms
        WEND
        PAUSE   20  'Una vez liberado, realiza un delay de 20 ms para eliminar rebotes
        GOTO    INIcio  'Regresa al inicio para mostrar el valor grabado
    ENDIF
    IF READ_SW = 1 then     'Se ha presionado el botónde read?
        FLAG_READ = 1       'Cancela el modo de programadión
        GOTO    CANCEL_PROG 'Regresa a leer el dato original de la EEPROM y muestralo en el display
    ENDIF
    GOTO    PROGRAMA_DATO   'Regresa al modo de programación
     
'********************************************************************
'                       Inicio de Subrutinas
'********************************************************************

'********************************************************************
'   Subrutina para desplegar el valor de 4 dígitos en el display
'   Nonmbre de la subrutina: DISPLAY_NUM
'   Entradas:   UNIDAD, DECENA, CENTENA, MILLAR
'   Salidas:    Ninguna
'********************************************************************
DISPLAY_NUM:0
    for I=0 TO 3    'Realiza un ciclo FOR para mostrar cada uno de los 4 dígitos en el display en forma multiplexada
        PORTB = (DIGITO*i)+ NUMERO[I]   'Muestra en el puerto B el valor de un dígito y habilítalo
        PAUSE   1   'Manten el dígito encendido por 1ms
    NEXT    I   'Muestra el siguiente dígito
    RETURN      'Termina la subrutina