viernes, 18 de marzo de 2011

Manejando Display 7-seg

Ahora mostrare un sencillo programa que muestra una cuenta ascendente de cuatro dígitos, que se almacenan en memoria (CUENTA1:CUENTA2:CUENTA3:CUENTA4), en 4 displays de 7-segmentos.

Link Programa

Agregaremos una macro más a nuestro archivo macros.inc:

MACRO

MOVIF toma un inmediato (@1) y lo guarda en una posición de memoria (@0).

El programa tiene dos rutinas, una llamada muestra y otra llamada incrementa.

Muestra toma cada dígito y lo envía a su respectivo display. También genera un retardo antes de pasar el siguiente display, ya que esto permite visualizar el dígito.

Incrementa va aumentando en 1 el valor de la cuenta, la cuenta será de 0-9999.

prog1

prog2

El circuito en el cual se usan displays con ánodo común es el mostrado abajo.

DISPLAY

En el siguiente vídeo se muestra la simulación del programa, aunque no se aprecia muy bien debido al programa de captura.


8 comentarios:

  1. Hola estaba estudiando un programam de un decodificador binario de 7 segmentos. Pero tengo dudas con el código ya que lo compilo y si funciona viene en un libro, pero no explican algunas cosas, puse los comentarios de lo que he logrado entender del código.
    Tengo duda con la parte del ADD R30,R16. Lo que yo entiendo es que se va pocisionando conforme yo vaya poniendo un valor en el puerto D. Por ejemplo si leeo un cero (IN R16,PIND ) mas la direccion que se encuentra en la pocision cero de la tabla en este caso el primero sería 0x3F. Bueno eso es lo que entiendo muy vagamente. Ojala me puedieras ayudar a comprenderlo. Gracías

    ********************************************
    LDI R16,0x00 //Se utiliza como entrada
    OUT DDRB,R16
    LDI R16,0xFF
    OUT PORTD,R16 // El uso del puerto D, es utilizado para los switch
    // Primero se configuro como entrada y despues se activaron las resistencias de PULL-UP,
    // Pero al activarlas con 0xFF ese numero quedo guardado en el registro que equivale a
    // ponerlo como salida.
    OUT DDRB,R16 // Puerto como B como salida

    LOOP:

    IN R16,PIND // Lectura del PIND lo que hace es pocisionarse deacuerdo a los binarios
    ANDI R16,0x0F //

    LDI R31,HIGH(2*tabla);
    LDI R30,LOW(2*tabla)
    ADD R30,R16
    BRCC s1
    INC R31

    s1:
    LPM R17,Z
    OUT PORTB,R17
    RJMP LOOP

    tabla: .DB 0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07
    .DB 0x7F,0x67,0x77,0x7C,0x39,0x5E,0x79,0x71

    ResponderEliminar
    Respuestas
    1. En lineas generales esta bien lo que me dices sobre el codigo, pero debes ser un poco mas concreto con tu pregunta.
      Saludos.

      Eliminar
  2. Si disculpa tienesrazón. Lo que no entiendo del código es, esta línea
    ¿Cómo funciona este pedacito de código? jeje

    ADD R30,R16

    Esto es lo que pienso:
    Lo que pienso que hace segun va sumando la instrucción y la pocision de la tabla,si yo pongo un 0 en la entrada de mi puerto D, que es donde estan mis botones los suma con el primer valor que puse de la tabla
    ya que el primero es 0x3F.(Que corresponde a la forma que tendría el cero en el display)

    Despues si yo escribo un 1 (0x06)en el puerto D, lo va a sumar con el valor de la tabla que se encuentra en la tabla y así sucesivamente. Entonces lo que logro ver al tanteo es que cada vez que se escribe un número en el puerto D y se hace la suma, toma el valor de cero y lo suma con una pocision cualquiera de la tabla. Ya que si realmente hago la suma y quiero mostrar el valor .

    Tambien entiendo que esta parte del código hace que siempre la parte baja este limpia, no se si quiere
    decir que va estar en cero.
    ANDI R16,0x0F

    ResponderEliminar
    Respuestas
    1. En un display puedes mostrar de 0 hasta F, eso es solamente un nible, es por eso que despues de leer se filtra r16(solamente necesitas 4 bits para eso). En la tabla se ubican los valores que representan a '0'=0x3F, '1'=0x06 ... . Lo que se hace es apuntar al inicio de la tabla (con el puntero Z=r31:r30, el inicio de la tabla siempre es el primer dato de esta, en este caso 0x3F) y luego sumar un offset para ubicar el valor que queremos representar. Por ejemplo, si lees el valor '5' =0b00000101=0x05 en PIND y lo guardas en r16, el valor que debes jalar de la tabla es 0x6D, para esto sumas Z+r16, con esto estarias apuntando a 0x6D. Luego al usar LPM se estaria poniendo 0x6D a r17.

      Espero haberte ayudado.
      Saludos.

      Eliminar
  3. Hola que tal

    Por ejemplo, si lees el valor '5' =0b00000101=0x05 en PIND y lo guardas en r16, el valor que debes jalar de la tabla es 0x6D, para esto sumas Z+r16, con esto estarias apuntando a 0x6D. Luego al usar LPM se estaria poniendo 0x6D a r17. Disculpame confundí un poco con el ejemplo ,cual es el valor de Z. Se supone que la suman debe ser Z+0b00000101 = 1101101?

    Disculpa de nuevo

    ResponderEliminar
    Respuestas
    1. Se supone que la suman debe ser Z+0b00000101 = 1101101
      Z=01101000

      Eliminar
    2. Z es un puntero. El valor de Z es desconocido para mi, cuando se hace LDI R31,HIGH(2*tabla) y LDI R30,LOW(2*tabla) se carga el valor de la DIRECCION de memoria (FLASH) donde inicia la tabla.
      Cuando declaras la tabla "tabla: .DB 0x3F, 0x...." el compilador asigna una direccion de memoria a la etiquela "tabla", esta es la direccion que se carga en Z. Debido a esto la direccion es desconocida para mi, y tampoco importa cual es el valor, lo importante es apuntar al inicio de la tabla.

      Saludos.

      Eliminar
    3. He esttado checando esta parte del código al principio no le preste mucha importancia
      pero al andentrarme un poco mas línea por línea resulto ser un poco confuso el concepto.
      He esta buscando especificamente a que hace referencia este parte del código
      ANDI R16,0x0F
      Al parecer limpia la parte alta del nibble es como un enmascarado
      pero me cuesta entender este concepto. Al principio pense que refiere que debido
      a que solo se utilizaran 4 bits con los cuales se representaran los
      números de entrada y que son de PD0 a PD3 que representan los bits menos significativos,
      pero modifique el código poniendole así ANDI R16,0xF0 y al poner en uno cualquier entrada
      me mostraba en el display quiza un 8 o un B.

      Eliminar