Multiplexación de pantallas de 2 a siete segmentos con ARM 7

Actualmente estoy tratando de controlar dos pantallas de siete segmentos desde los mismos 7 pines (P0.0 - P0.6) de un microcontrolador ARM 7. Primero estoy probando esto en el software de simulación Proteus.

Estoy siguiendo el esquema de este tutorial de multiplexación 8051 , sin embargo, mis pantallas de 7 segmentos están conectadas desde el puerto 0.0 al puerto 0.6 y los dos transistores de control están conectados en P0.7 y P0.8.

Estoy bastante seguro de que la pantalla de siete segmentos y los transistores de mi simulación están conectados correctamente y que el problema surge del siguiente código. También probé mi código para asegurarme de mostrar los números correctos y que los pines del transistor estén configurados según sea necesario.

El problema que encuentro es que ambos dígitos se imprimen en ambas pantallas , en lugar de que se muestre la primera 1y la segunda 2.

 #include <LPC21xx.h>
 #define a 0x00000001 
 #define b 0x00000002
 #define c 0x00000004
 #define d 0x00000008
 #define e  0x00000010
 #define f 0x00000020
 #define g 0x00000040
 #define T2 0x00000080
 #define T1 0x00000100

 void small_delay (void);

 int main (void)
{

PINSEL0 = 0;                        //Set P0.0 - P0.15 as GPIOS
PINSEL1 = 0;                        //Set P0.16 - P0.31 as GPIOS
IO0DIR  = 0xFFFFFFFF;               //Set all port0 pins as outputs          



    while (1){  

    IO0SET = e;      //displaying number 1              
    IO0SET = f;      //displaying number 1 
    IO0SET = T1;     //switching on first display
    small_delay();   //calling short delay
    IO0CLR = T1;     //clearing first display

  IO0SET = a;       //displaying number 2
  IO0SET = b;       //displaying number 2
  IO0SET = g;       //displaying number 2
  IO0SET = e;       //displaying number 2
  IO0SET = d;       //displaying number 2
  IO0SET = T2;      //switching on first display
  small_delay();    //calling small delay
  IO0CLR = T2;      //clearing second display
    }

}

void small_delay (void) 
{
unsigned int i, j;

for (i=0; i<10; i++)
 {  
    //do nothing
 }
}

Esto es lo que estoy tratando de lograr con el código anterior:

  1. Envía datos 1a ambas pantallas.
  2. Habilitación del segmento siete izquierdo mediante el usoIO0SET = T1;
  3. Llamando a un corto delay.
  4. Deshabilitar el segmento siete izquierdo usandoIO0CLR = T1;
  5. Envío de datos 2a ambas pantallas.
  6. Habilitación del segmento siete derecho mediante el usoIO0SET = T2;
  7. Llamando a un corto delay.
  8. Deshabilitar el segmento siete derecho usandoIO0CLR = T2;
  9. Repetir.

¿Hay algún defecto en esta lógica? Cualquier sugerencia/idea sobre lo que estoy haciendo mal en mi codificación sería muy apreciada.

Aparte de la respuesta a continuación, su "pequeño retraso" es muy, muy pequeño. A menos que el núcleo funcione a Mhz o menos. Sospecho que tendrá que ser más largo para permitir una propagación y un enganche decentes en el mundo real. Y es posible que deba hacerlo volátil, para que no se optimice como código que, si lo etiqueta correctamente, no hace nada. ¿O puede haber funciones de retardo integradas? (Puede hacerlo volátil con un ASM volátil ("NOP") o cualquiera que sean las palabras clave de su conjunto de compiladores para insertar el comando ASM NOP.
Hola, @Asmyldof, primero gracias por tu contribución. Hasta donde yo sé, no hay funciones de retardo integradas. Aumentaré el tiempo de retraso como sugieres.

Respuestas (2)

Está activando segmentos individuales, pero nunca los vuelve a desactivar, por lo que el resultado es que muestra un 1 y un 2 superpuestos en ambas pantallas.

Cambie sus declaraciones IO0CLR = T1 e IO0CLR = T2 a IO0CLR = 0x000001FF para desactivar todos los segmentos, así como ambos ánodos comunes. Entonces sus salidas estarán listas para configurar los nuevos patrones de segmento.

Gracias por tu percepción sobre este asunto. Veo lo que estoy haciendo mal y he procedido a limpiar todos los segmentos y ánodos comunes. Sin embargo, como se señaló anteriormente, mi retraso es muy pequeño y los dígitos de la simulación no se muestran correctamente. Entonces aumentaré la demora en consecuencia.
Si hace que la demora sea lo suficientemente larga durante la depuración, verá que cada pantalla se ilumina por separado, lo que puede hacer que sea más fácil ver exactamente lo que está sucediendo.

Esto es lo que estoy tratando de lograr con el código anterior:

hay muchos ejemplos de este tipo en la red para que los busques. Todo bastante fácil de entender.

y funciona mejor también.

aquí está mi versión:

//display the content of vRAM[8]
void _7seg_display(void) {
    static unsigned char digit=0;                       //digit to be displayed

    DIG_OFF(DIGs);                                      //turn all digits off
    _7SEG_ON(_7seg_font[vRAM[digit]]);                  //display the digit
    //DIG_ON(1<<digit);                                 //turn on the digit
    switch (digit) {
    case 0:
        DIG_ON(DIG0);
        break;
    case 1:
        DIG_ON(DIG1);
        break;
    case 2:
        DIG_ON(DIG2);
        break;
    case 3:
        DIG_ON(DIG3);
        break;
    case 4:
        DIG_ON(DIG4);
        break;
    case 5:
        DIG_ON(DIG5);
        break;
    case 6:
        DIG_ON(DIG6);
        break;
    case 7:
        DIG_ON(DIG7);
        break;
    }
    digit+=1;                                           //increment the digit
    if (digit==_7SEG_NUMBER) digit=0;                   //reset the digit
}

es bastante simple en eso

  1. es independiente del hardware -> lo que significa que simplemente puede copiarlo en un nuevo proyecto y definir ciertas macros para ese proyecto/plataforma, volver a compilar y funcionará.

  2. sigue una lógica simple: inhibe el dígito actual, pone nuevos datos en los segmentos y luego enciende el siguiente dígito.

  3. el código se puede llamar periódicamente a través de una interrupción del temporizador o incluso en el ciclo principal.

  4. admite hasta 8 dígitos -> se puede expandir a más si lo desea.

Nuevamente, la clave es asegurarse de escribir su código independientemente del hardware para que pueda reutilizar el código.

Hola, gracias por tu aporte. Veo que su código es independiente del hardware, sin embargo, he tenido cuidado al ver otros códigos, ya que la mayoría no son independientes del hardware (por lo que puedo deducir). Implementaré esto con mi codificación en consecuencia.