Forum: Mikrocontroller und Digitale Elektronik 7-Segment Multiplex Library


von D. M. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich wollte mir eine Konstantstromquelle mit 4 7-Segment-Anzeigen bauen.
Probleme habe ich noch bei der Ansteuerung der 7-Segment-Anzeigen und 
meinem Atmega8.
Gibt es eine Library in der man einfach die Portpins angeben kann, an 
denen die einzelnen Segmente angeschlossen sind?

Im Anhang ist der Schaltplan mit den Anzeigen.

Noch eine andere Frage:
Müssen die Ansteuerleitungen alle an einen Port angeschlossen sein?
Ist wahrscheinlich einfacher zum Programmieren, ich frage jedoch weil 
bei mir das dummerweise nicht so ist...

Ich hoffe ihr könnt mir helfen.

Vielen Dank im Voraus!

Gruß
DM

von Karol B. (johnpatcher)


Lesenswert?

D. M. schrieb:
> Müssen die Ansteuerleitungen alle an einen Port angeschlossen sein?

Das kommt doch ganz darauf an wie du das Ganze programmierst. I.d.R. 
kann man unter der Voraussetzung, dass sich alles am selben Port 
abspielt "effizienteren" Code produzieren, in der Praxis spielt das wohl 
kaum eine Rolle.

Passende Libraries sind mir keine bekannt, aber das Konzept wird hier 
[1] beschrieben und sollte sich problemlos umsetzen lassen. Wie man 
7-Segment anzeigen umsetzt, steht dann wiederum hier [2] - zwar in 
Assembler, das Konzept bleibt aber gleich.

Genug Beispielcode schwirrt hier im Forum (bzw. im Internet) auch herum.

D. M. schrieb:
> Probleme habe ich noch bei der Ansteuerung der 7-Segment-Anzeigen und
> meinem Atmega8.

Hast du denn konkrete Probleme? Wie sieht dein bisheriger Code denn aus? 
Was funktioniert nicht? Wie äußert sich das?

Mit freundlichen Grüßen,
Karol Babioch

[1]: https://www.mikrocontroller.net/articles/LED-Matrix
[2]: 
https://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige

von m.n. (Gast)


Lesenswert?

Deine Verdrahtung ist leider ungeschickt; nimm für die 
Segementansteuerung den kompletten PortD. Ferner brauchen heutige 
7-Segementanzeigen (10-14mm) keine sonderlich hohen Ströme 
(2-5mA/Segment), sodass nur zusätzliche Digittreiber notwendig sind.
Mein Vorschlag inkl. Software: 
http://www.mino-elektronik.de/7-Segment-Variationen/LCD.htm#led4

von MaWin (Gast)


Lesenswert?

D. M. schrieb:
> Gibt es eine Library in der man einfach die Portpins angeben kann, an
> denen die einzelnen Segmente angeschlossen sind?

Gerade so eine fertige Bibliothek wäre doch extrem blöd, weil sehr 
codeaufwändig (vergleichbar mit sprintf in einem uC-programm, mit der 
Gefahr, daß der rumgetragene Ballast nicht erlaubt, daß das 
Gesamtprogramm noch in den Speicher passt).

D. M. schrieb:
> Müssen die Ansteuerleitungen alle an einen Port angeschlossen sein?
> Ist wahrscheinlich einfacher zum Programmieren,

und wird schneller ausgeführt

> ich frage jedoch weil bei mir das dummerweise nicht so ist...
1
uint8_t digit=0;
2
uint8_t segment[10]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,0b10010010,0b10000010,0b11111000,0b10000000,0b10010000 };
3
int zahl;
4
5
uint8_t ziffer(int zahl,int stelle)
6
{
7
    while(stelle-->0) zahl/=10;
8
    return zahl%10;
9
}

so einfach ist der Code wenn die Ports passen
1
loop() // Hauptschleife oder timergesteuert
2
{
3
    PORTB~=1<<digit;
4
    digit=(digit+1)&3; // angenommen 4 Stellen
5
    PORTD=segment[ziffer(zahl,digit)];
6
    PORTB|=1<<digit;
7
    :
8
    restliches Hauptschleifenprogramm
9
    :
10
    _delay_ms(10); // falls nicht timergesteuert
11
}

So aufwändig wenn sie nicht passen:
1
struct
2
{
3
   int port;
4
   int bit;
5
}
6
definition[]=
7
{
8
   {PORTB,0}, // womöglich noch Polarität
9
   {PORTB,1},
10
   {PORTB,2},
11
   {PORTB,3},
12
   {PORTB,4},
13
   {PORTB,5},
14
   {PORTB,6},
15
   {PORTB,7},
16
   {PORTD,0},
17
   {PORTD,1},
18
   {PORTD,2},
19
   {PORTD,3}
20
};
21
22
void setpin(uint8_t pin,uint8_t value)
23
{
24
    if(value)
25
    {
26
        *(definition[pin].port)|=1<<definition[pin].bit;
27
    }
28
    else
29
    {
30
        *(definition[pin].port)&=~(1<<definition[pin].bit);
31
    }
32
}
33
34
loop() // Hauptschleife oder timergesteuert
35
{
36
    uint8_t i;
37
38
    setpin(8+digit,0);
39
    digit=(digit+1)&3; // angenommen 4 Stellen
40
    for(i=0;i<8;i++) setpin(i,segment[ziffer(zahl,digit)]&(1<<i);
41
    setpin(8+digit,1);
42
    :
43
    restliches Hauptschleifenprogramm
44
    :
45
    _delay_ms(10); // falls nicht timergesteuert
46
}

http://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige

von Peter D. (peda)


Lesenswert?

D. M. schrieb:
> Müssen die Ansteuerleitungen alle an einen Port angeschlossen sein?

Alle Segmente an einem Port: OUT Byte = 1 Befehl

Segmente wild verteilt: 8 * Clear Pin, Test Bit, Set Pin = 24 Befehle

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Kannst ja mal nen Blieck hierrauf werfen:
http://www.fritzler-avr.de/HP/tipps/multi.php

von Thomas E. (thomase)


Lesenswert?

Peter Dannegger schrieb:
> Segmente wild verteilt: 8 * Clear Pin, Test Bit, Set Pin = 24 Befehle

Wenn es nicht anders geht, muss man da durch.

Atmega328: Quarz, UART, ADC und ein bisschen PWM...

mfg.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter Dannegger schrieb:
> Alle Segmente an einem Port: OUT Byte = 1 Befehl
>
> Segmente wild verteilt: 8 * Clear Pin, Test Bit, Set Pin = 24 Befehle

 Muss ja nicht sein.
 Mit einer etwas geänderter Tabelle fur Werte 0-9 geht das
 auch schneller
  ldi  zl, low(Table<<1)
  ldi  zh, high(Table<<1)
  clr  r15
  add  r16, r16          ; r16 ist die anzuzeigende Zahl
  add  zl, r16
  adc  zh, r15
  lpm    r16, Z+        ; Wert 1 aus Tabelle laden
  in     r24, PIND
  andi   r24, 0xC0
  or     r24, r16
  out    PORTD, r24
  lpm    r16, Z+        ; Wert 2 aus Tabelle laden
  in     r24, PINC
  andi   r24, 0x30
  or     r24, r16
  out    PORTC, r24

 DP mußt du in beiden Fällen gesondert rechnen, bzw. setzen, Byte
 mußt du auch in jedem Fall aus einer Tabelle laden, so...
 Und die paar Bytes und Cycles mehr machen kaum einen Unterschied.
 Besser als neue Platine zu machen...

: Bearbeitet durch User
von D. M. (Gast)


Lesenswert?

Hallo zusammen,

danke für die vielen Antworten!

Martin Wende schrieb:
> Kannst ja mal nen Blieck hierrauf werfen:
> http://www.fritzler-avr.de/HP/tipps/multi.php

Mit dem Code habe ich schon rumhantiert, bislang leider erfolglos, da 
bei mir die Zeilen und Spalten nicht jeweils an einem Port hängen.

Mein Code ist eigentlich nur Kopiertes und Umhergeworfenes von dieser 
Seite...

Marc Vesely schrieb:
> Peter Dannegger schrieb:
>> Alle Segmente an einem Port: OUT Byte = 1 Befehl
>>
>> Segmente wild verteilt: 8 * Clear Pin, Test Bit, Set Pin = 24 Befehle
>
>  Muss ja nicht sein.
>  Mit einer etwas geänderter Tabelle fur Werte 0-9 geht das
>  auch schneller
>   ldi  zl, low(Table<<1)
>   ldi  zh, high(Table<<1)
>   clr  r15
>   add  r16, r16          ; r16 ist die anzuzeigende Zahl
>   add  zl, r16
>   adc  zh, r15
>   lpm    r16, Z+        ; Wert 1 aus Tabelle laden
>   in     r24, PIND
>   andi   r24, 0xC0
>   or     r24, r16
>   out    PORTD, r24
>   lpm    r16, Z+        ; Wert 2 aus Tabelle laden
>   in     r24, PINC
>   andi   r24, 0x30
>   or     r24, r16
>   out    PORTC, r24
>
>  DP mußt du in beiden Fällen gesondert rechnen, bzw. setzen, Byte
>  mußt du auch in jedem Fall aus einer Tabelle laden, so...
>  Und die paar Bytes und Cycles mehr machen kaum einen Unterschied.
>  Besser als neue Platine zu machen...

Eine neue Platine würde ich ungern machen, sieht aber ganz danach aus, 
da ich nur C lerne und es erstmal zum Laufen bekommen möchte.
Um mir die funktionierenden Codes für meinen Anwendungsfall 
umzuschreiben, fehlt mir aktuell noch die Erfahrung.
Deswegen die Frage nach den Libraries :)

Trotzdem vielen Dank an alle!
I'll be back! :D

Gruß DM

Beitrag #5691718 wurde von einem Moderator gelöscht.
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.