Zwei gemultiplexte 7-Segment-Anzeigen flackern

Ich arbeite an einem Temperatursensor. Ich habe:

  • LM35 (Fühler)
  • LM741 (Operationsverstärker zur Verstärkung von LM35 Vout auf 5 V)
  • PIC 14F458

Die Temperatur wird auf zwei 7-Segment-Anzeigen mit nur einem BCD-Wandler (4511) angezeigt. Deshalb habe ich diese beiden Displays gemultiplext.

Das Problem ist, dass meine 7-Segment-Anzeigen stark flackern und ich nicht weiß, warum.

Wenn Sie die Simulation auf Proteus sehen möchten: LM35 - SSD

Hier ist das schematische Diagramm auf Proteus:

schematische Darstellung

Und hier ist der C-Code auf CCS.

#include <sonde2.h>
#include <math.h>

#define CONV_CST 0.48875855327
#define TRESHOLD 25
#define TENS_DISPLAY PIN_E0
#define UNITY_DISPLAY PIN_E1
#define GREEN_LED PIN_C0
#define RED_LED PIN_C1


int simpleBCDConverter(value) {
   // Shift tens from 4 bits to the left
   // So we have ([Tens] [Unity]) XXXX XXXX
   return ((value / 10 % 10 << 4) + value % 10);
}

/**
 * Convert a number of 10 bits to its BCD equivalent
 */
void bitsToBCD(int value) {
   int tens = value / 10 % 10;
   int unity = value % 10;

   output_high(TENS_DISPLAY);
   output_d(tens);
   output_low(UNITY_DISPLAY);
   delay_ms(10);

   output_high(UNITY_DISPLAY);
   output_d(unity);
   output_low(TENS_DISPLAY);
   delay_ms(10);


}

/**
 * Check temp level, and switch on the right led
 */
void checkLed(int temp) {
   // If temps is greater than treshold
   // Blinking Red LED with 555 (astable)
   if (temp > TRESHOLD) {
      output_low(GREEN_LED);
      output_high(RED_LED);
   } else { // Otherwise, green LED
      output_high(GREEN_LED);
   }
}

void main()
{
   setup_adc_ports(AN0);
   set_adc_channel(0); // A0 connecté à l'entrée analogique
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT); // 51,2 us overflow
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //13,1 ms overflow

   setup_low_volt_detect(FALSE);

   int temperature;

   while(TRUE) {
      //delay_ms(10);
      // Read the value from A/N converter (10bits [0 => 1023])
      // And convert it to a range from 0 to 100 (°C)
      // 0.48 => (5 / 1023) * 100
      temperature = read_adc() * CONV_CST;

      // Check temp level
      checkLed(temperature);

      // Convert bits to BCD
      // And show temp on 7 segment displays
      bitsToBCD(temperature);
   }

}

Danke.

Dies liegt wahrscheinlich daran, dass der Simulator nicht mit Echtzeitgeschwindigkeit läuft. Wenn Sie dies in Hardware einbauen, wechseln die Ziffern schnell genug, dass die Persistenz des Sehens dazu führt, dass sie gleichzeitig beleuchtet erscheinen. Mit anderen Worten, dieses Problem ist sehr wahrscheinlich darauf zurückzuführen, dass man dem Simulator zu sehr vertraut. Simulatoren bringen dich nur so weit...
Beachten Sie, dass diese Schaltung nicht wie vorgesehen funktioniert - Sie können einen 741-Operationsverstärker nicht mit einer 5-V-Versorgung betreiben.

Antworten (2)

Das Problem ist, dass meine 7-Segment-Anzeigen stark flackern und ich nicht weiß, warum.

Führen Sie die Anzeigeroutine in einem Timer-ISR aus, damit sie in einem festen Intervall aktualisiert wird.

Ich würde vorschlagen, den Code so zu strukturieren:

output_d(tens);
output_high(TENS_DISPLAY);
delay_ms(10);
output_low(TENS_DISPLAY);

output_d(unity);
output_high(UNITY_DISPLAY);
delay_ms(10);
output_low(UNITY_DISPLAY);

Dies macht deutlicher, wie das Timing durchgeführt wird (ich wurde anfangs davon getäuscht, daher war meine erste Antwort falsch). Dadurch wird auch sichergestellt, dass beide Ziffern die gleiche Leuchtzeit erhalten, anstatt dass eine von ihnen auch die Verarbeitungszeit enthält, wodurch sie etwas heller wird.

Ein weiterer Vorschlag ist, dass Sie diese Verzögerungen von 10 ms möglicherweise verringern möchten. Sie geben Ihnen 20 ms pro vollständiger Anzeige und werfen etwas Zeit für ADC und Verarbeitung ein ... Ihre Anzeige flackert mit weniger als 50 Hz. Das macht sich vielleicht bemerkbar. Vielleicht möchten Sie dies auf 1 ms verringern. Es ist ein Kompromiss, der davon abhängt, wie langsam die andere Verarbeitung ist. Wenn Sie die Verzögerung zu klein machen, bleibt das Display die meiste Zeit unbeleuchtet (während der Verarbeitung) und wird als geringere Helligkeit wahrgenommen.

Wie @uint128_t kommentierte, könnte Ihre Simulationsgeschwindigkeit auch etwas langsam sein, aber versuchen Sie zuerst die Codeänderungen.

Um ehrlich zu sein, ist die Anzeige schlechter
Unter der Annahme, dass keine anderen Overheads vorhanden sind, sind 20 ms pro Aktualisierung 50 Hz. Das ist ziemlich niedrig, und Ihr Auge wird sehr wenig Toleranz für Abweichungen haben, bevor es es als Flimmern wahrnimmt. Besser wäre es, die Anzeigesegmente mit 100 Hz oder höher zu aktualisieren. Verwenden Sie eine Interrupt-Routine, um die Aktualisierungen durchzuführen. Eine einfache Zustandsmaschine, die einen 1-kHz-Interrupt ausführt, könnte zwischen den Ziffern wechseln, wobei jede Ziffer pünktlich gleich wird, und wenig oder keine Zeit haben, wenn eine der Ziffern nicht leuchtet. Das Lesen des Werts und die Berechnung der Ziffern würden in einem separaten Thread erfolgen, wahrscheinlich einfach in der Hauptschleife, die darauf wartet, dass der ADC beendet wird.