Forum: Mikrocontroller und Digitale Elektronik AVR 7-segment Multiplex Probleme


von Steve M. (jodziste)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe einen attiny2313 der ein vierstelliges 7-Segment Display 
gemultiplexed ansteuert. So wie hier: 
https://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige
Das Programm habe ich in C geschrieben und mit AVR-GCC kompiliert. 
Soweit alles ganz simpel. Einzelne Digits anzusteuern funktioniert wie 
erwartet. Ebenfalls eine Zahl durchzuscrollen geht auch problemlos.
Wenn ich aber wie in angefügten Programm anfange die Digits 
durchzuscrollen (jeweils ein aufleuchten zu lassen, dann das nächste...) 
UND dazwischen die num variable zu ändern, sehe ich nur noch eine 7 bei 
der obere vertikale Balke fehlt.(also nur die a und c segmente eines 
Digits leuchten) Diese komische 7 scrollt dann unendlich lange durch.
Auch wenn ich versuche die num Variable um eins hochzuzählen (num++) 
kommen keine Zahlen mehr sondern nur einzelne Segmente.
An der Stromversorgung liegt es schonmal nicht, da es das gleiche sowohl 
am Programmer als auch am Labornetzteil tut.
Die Segmente an den Portpins (mit widerständen dazwischen):
a PB0
b PB1
c PB2
d PB3
e PB4
f PB5
g PD6
DP PA0
Die Digits am AVR: (an die Basis der PNP Transistoren über einen 
Widerstand)
1 PD2
2 PD3
3 PD4
4 PD5
MfG, Steven

: Bearbeitet durch User
von H.Joachim S. (crazyhorse)


Lesenswert?

Ohne jetzt dein eigentliches Problem gesucht oder gar gefunden zu haben 
- du solltest noch mal von vorn anfangen.

Die Umdierungsorgie ist übersichtlicher als switch/case-construkt. 
Nörmalerweise macht man das aber mit einer look-up-table im flash. Das 
ist die kleinste und auch die schnellste Lösung.

Die Multiplex-Ansteuerung solltest du in einem Timerinterrupt erledigen.

-alte Stelle aus
-neue Segmente ausgeben
-neue Stelle ein
-wenn durch von vorne

Dazu brauchst du ein char-array mit der Anzahl deiner Stellen. Dort 
schreibst du dann einfach asynchron deine Werte rein.

von Peter D. (peda)


Lesenswert?

Steven J. schrieb:
> PORTB |= ((segment & 0b00000001));

Und wo wird der Pin wieder rückgesetzt?
1
#include <avr/io.h>
2
3
void _7seg(uint8_t segmentnum, uint8_t segment){
4
5
  PORTD |= 0b00111101;          // all digits off
6
  if( !(segment & 0b01000000) )
7
    PORTD &= ~0b01000000; 
8
  PORTB = PORTB & 0b11000000 | segment & 0b00111111;
9
  PORTA &= ~0b00000001;
10
  if( segment & 0b10000000 )
11
    PORTA |= 0b00000001;
12
  PORTD |= (1<<segmentnum);     // wanted digit on
13
}

von Steve M. (jodziste)


Lesenswert?

Hallo,
danke für die Antworten.

Peter D. schrieb:
> void _7seg(uint8_t segmentnum, uint8_t segment){
>
>   PORTD |= 0b00111101;          // all digits off
>   if( !(segment & 0b01000000) )
>     PORTD &= ~0b01000000;
>   PORTB = PORTB & 0b11000000 | segment & 0b00111111;
>   PORTA &= ~0b00000001;
>   if( segment & 0b10000000 )
>     PORTA |= 0b00000001;
>   PORTD |= (1<<segmentnum);     // wanted digit on
> }

damit funktioniert es. Vielen Dank!
MfG, Steven

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.