Multiplexing von 2-Sieben-Segment-Anzeigen mit ARM 7

Ich versuche derzeit, zwei Sieben-Segment-Anzeigen von denselben 7 Pins (P0.0 - P0.6) eines ARM 7-Mikrocontrollers zu steuern. Ich teste dies zuerst mit der Proteus-Simulationssoftware.

Ich folge dem Schema aus diesem 8051-Multiplexing-Tutorial , aber meine 7-Segment-Anzeigen sind von Port 0.0 bis Port 0.6 verbunden und die beiden Steuertransistoren sind an P0.7 und P0.8 angeschlossen.

Ich bin mir ziemlich sicher, dass die Siebensegmentanzeige und die Transistoren meiner Simulation korrekt angeschlossen sind und dass das Problem durch den folgenden Code verursacht wird. Ich habe auch meinen Code getestet, um sicherzustellen, dass ich die richtigen Zahlen zeige und dass die Transistorstifte wie erforderlich konfiguriert sind.

Das Problem, auf das ich stoße, ist, dass beide Ziffern auf beiden Displays gedruckt werden , anstatt dass das erste Display 1und das zweite Display angezeigt werden 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
 }
}

Das versuche ich mit dem obigen Code zu erreichen:

  1. Senden Sie Daten 1an beide Displays.
  2. Aktivieren des linken sieben Segments mitIO0SET = T1;
  3. Kurz anrufen delay.
  4. Deaktivieren des linken sieben Segments mitIO0CLR = T1;
  5. Senden von Daten 2an beide Displays.
  6. Aktivieren des rechten Siebensegments mitIO0SET = T2;
  7. Kurz anrufen delay.
  8. Deaktivieren des rechten sieben Segments mitIO0CLR = T2;
  9. Wiederholen.

Gibt es Fehler in dieser Logik? Irgendwelche Vorschläge/Ideen bezüglich dessen, was ich in meiner Codierung falsch mache, wären sehr dankbar.

Abgesehen von der folgenden Antwort ist Ihre "kleine Verzögerung" sehr, sehr gering. Es sei denn, der Kern läuft mit einem MHz oder weniger. Ich vermute, dass es länger dauern muss, um eine anständige Ausbreitung und Latch-up in der realen Welt zu ermöglichen. Und Sie müssen es möglicherweise flüchtig machen, damit es nicht als Code optimiert wird, der, wie Sie es richtig bezeichnen, nichts tut. Oder gibt es eingebaute Verzögerungsfunktionen? (Sie können es mit einem flüchtigen ASM ("NOP") oder was auch immer die Codewörter Ihrer Compiler-Suite sind, flüchtig machen, um den ASM NOP-Befehl einzufügen.
Hi, @Asmyldof, erstmal danke für deinen Beitrag. Soweit ich weiß, gibt es keine eingebauten Verzögerungsfunktionen. Ich werde die Verzögerungszeit erhöhen, wie Sie vorschlagen.

Antworten (2)

Sie schalten einzelne Segmente ein, aber nie wieder aus. Das Ergebnis ist also, dass Sie auf beiden Displays eine 1 und eine 2 überlagert anzeigen.

Ändern Sie Ihre IO0CLR = T1- und IO0CLR = T2-Anweisungen in IO0CLR = 0x000001FF, um alle Segmente sowie beide gemeinsamen Anoden auszuschalten. Dann sind Ihre Ausgänge bereit für die Einrichtung der neuen Segmentmuster.

Vielen Dank für Ihren Einblick in diese Angelegenheit. Ich sehe, was ich falsch mache, und habe damit fortgefahren, alle Segmente und gemeinsamen Anoden zu löschen. Wie bereits erwähnt, ist meine Verzögerung jedoch sehr gering und die Ziffern in der Simulation werden nicht richtig angezeigt. Ich werde dann die Verzögerung entsprechend erhöhen.
Wenn Sie die Verzögerung beim Debuggen lang genug machen, sehen Sie, dass jede Anzeige separat aufleuchtet – das kann es einfacher machen, genau zu sehen, was passiert.

Das versuche ich mit dem obigen Code zu erreichen:

Es gibt viele solcher Beispiele im Netz, die Sie durchsuchen können. Alles ziemlich leicht verständlich.

und funktioniert auch besser.

hier ist meine version:

//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
}

darin ist es ziemlich einfach

  1. es ist unabhängig von der Hardware -> das heißt, Sie können es einfach in ein neues Projekt kopieren und bestimmte Makros für dieses Projekt / diese Plattform definieren, neu kompilieren und es wird funktionieren.

  2. Es folgt einer einfachen Logik: Es sperrt die aktuelle Ziffer, legt neue Daten auf die Segmente und schaltet dann die nächste Ziffer ein.

  3. Der Code kann periodisch über einen Timer-Interrupt oder sogar in der Hauptschleife aufgerufen werden.

  4. Es unterstützt bis zu 8 Ziffern -> kann auf mehr erweitert werden, wenn Sie möchten.

Auch hier ist der Schlüssel, sicherzustellen, dass Sie Ihren Code unabhängig von der Hardware schreiben, damit Sie den Code wiederverwenden können.

Hallo, danke für deinen Beitrag. Ich sehe, dass Ihr Code unabhängig von der Hardware ist, aber ich war vorsichtig, als ich andere Codes sah, da die meisten nicht unabhängig von der Hardware sind (soweit ich das beurteilen kann). Ich werde dies mit meiner Codierung entsprechend implementieren.