Ansteuerung einer 7-Segment-Anzeige mit ATmega8 funktioniert nicht mehr

OP #1457212
Lesenswert?

Hallo!

Kann sich bitte einer von euch meinen Quelltext anschauen und mir sagen, 
was ich falsch gemacht habe?
Ursprünglich hat dieser Code mal einen ATmega8 dazu gebracht, YEAH auf 
einer 7-Segment-Anzeige auszugeben.
Dann habe ich die Anzeige in eine Unterfunktion anzeigen() ausgelagert - 
und schon leuchtet nur noch die erste Ziffer der Anzeige (Punkt und alle 
Segmente außer dem Obersten).
Die Verschaltung der Anzeige seht ihr im angehängten Schaltplan (die 
Ziffern hängen in Wirklichkeit allerdings zusammen).
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 1000000UL  //Taktfrequenz einstellen, damit _delay_ms() funktioniert
4
#endif
5
#include <util/delay.h>
6
#include <stdint.h>
7

8
////
9
////Beginn des neuen Teils
10
////
11

12
uint8_t bwert;  //wird in anzeigen() verwendet
13
uint8_t cwert;  //wird in anzeigen() verwendet
14

15
void anzeigen(uint8_t stelle, char zeichen)
16
{
17
  switch (stelle)  //der Stelle, die angesteuert werden soll, + geben, die anderen ausschalten
18
  {
19
    case 1: PORTD = ((PORTD && 0b11001100) || 0b00000001);
20
        break;
21
    case 2: PORTD = ((PORTD && 0b11001100) || 0b00000010);
22
        break;
23
    case 3: PORTD = ((PORTD && 0b11001100) || 0b00010000);
24
        break;
25
    case 4: PORTD = ((PORTD && 0b11001100) || 0b00100000);
26
        break;
27
  }
28
  switch (zeichen)  //den benötigten Segmentteilen - geben, die anderen ausschalten
29
  {
30
    case 'Y':  {
31
            bwert = 0b11010001;
32
            cwert = 0b11001111;
33
            break;
34
          }
35
    case 'E':  {
36
            bwert = 0b11100100;
37
            cwert = 0b11001111;
38
            break;
39
          }
40
    case 'A':  {
41
            bwert = 0b11000000;
42
            cwert = 0b11011111;
43
            break;
44
          }
45
    case 'H':  {
46
            bwert = 0b11000001;
47
            cwert = 0b11011111;
48
            break;
49
          }
50
  }
51
  PORTB = ((PORTB && 0b11000000) || bwert);
52
  PORTC = ((PORTC && 0b11001111) || cwert);
53
}
54

55
////
56
////Ende des neuen Teils
57
////
58

59
int main(void)
60
{
61
  DDRB = 0xFF;
62
  DDRC = 0xFF;
63
  DDRD = 0xFF;
64
  while (1)
65
  {
66
    /********
67
    Der alte Code zum YEAH-Erzeugen:
68
    PORTB = 0b00010001;
69
    PORTC = 0b00100000;
70
    PORTD = 0b00000001;
71
    _delay_ms(3);
72
    PORTB = 0b00100100;
73
    PORTC = 0b00100000;
74
    PORTD = 0b00000010;
75
    _delay_ms(3);
76
    PORTB = 0b00000000;
77
    PORTC = 0b00110000;
78
    PORTD = 0b00010000;
79
    _delay_ms(3);
80
    PORTB = 0b00000001;
81
    PORTC = 0b00110000;
82
    PORTD = 0b00100000;
83
    _delay_ms(3);
84
    ********/
85

86
    ////Der neue Code zum YEAH-Erzeugen
87
    anzeigen(1, 'Y');
88
    _delay_ms(3);
89
    anzeigen(2, 'E');
90
    _delay_ms(3);
91
    anzeigen(3, 'A');
92
    _delay_ms(3);
93
    anzeigen(4, 'H');
94
    _delay_ms(3);
95
    ////
96
  }
97
  return 0;
98
}
Angehängte Dateien:
OP #1457810
Lesenswert?

@Lothar:
Das war tatsächlich der Fehler. Ich habe die || durch | und && durch & 
ersetzt - und die Anzeige funktioniert wieder.
Vielen Dank für deine Hilfe.

@Ben:
Ich weiß nicht, ob das eine low-current-Anzeige ist, allerdings wird der 
ATmega8 kein bisschen warm (und das müsste er bei Überlastung doch 
werden, oder?).
Außerdem: Dadurch, dass ich die Anzeige multiplexe, sind die 
Zeichen-Pins (PD0,1,4,5) sowieso nur ein Viertel der Zeit belastet, also 
müsste ich ja theoretisch bis zu 80mA Last dran hängen können.
Zu den Vorwiderständen: Ich hatte gerade keine vier 150 Ohm-Widerstände 
da, also habe ich einfach je eine LED zwischen die Anode jedes Zeichens 
und den entsprechenden Pin am ATmega gehängt.
#1457824
Lesenswert?

@  Nils S. (n-regen)

>Ich weiß nicht, ob das eine low-current-Anzeige ist, allerdings wird der
>ATmega8 kein bisschen warm (und das müsste er bei Überlastung doch
>werden, oder?).

Ohje. Du hast mehr Glück als Verstand. Die Ausgänge vom AVR haben so um 
die 30 Ohm Ausgangswderstnd und begrenzen dadurch den Strom.

>Außerdem: Dadurch, dass ich die Anzeige multiplexe, sind die
>Zeichen-Pins (PD0,1,4,5) sowieso nur ein Viertel der Zeit belastet, also
>müsste ich ja theoretisch bis zu 80mA Last dran hängen können.

Nö.

>Zu den Vorwiderständen: Ich hatte gerade keine vier 150 Ohm-Widerstände
>da, also habe ich einfach je eine LED zwischen die Anode jedes Zeichens
>und den entsprechenden Pin am ATmega gehängt.

[ ] Du kennst den Unterschied zwischen einer Diode und einem Widerstand.

Naja
Gast #1458070
Lesenswert?

na klasse...

also da besteht wohl noch etwas verbesserungsbedarf. hattest du 
wenigstens einen netztrafo zur hand? oder läuft der atmega direkt an 
230V~?

schon komisch auf was für ideen manche leute kommen.

die strombegrenzung gehört übrigens nicht in die gemeinsame 
stromversorgung der segmente (in deinem fall die anode). bei dir braucht 
jede kathode ihren widerstand. da du die anzeige gemultiplext betreibst 
reichen 7 stück am "kathode-port" des atmega. wirst staunen, da 
verschwindet auch dein problem, daß die anzeigen bei verschienen zeichen 
verschieden hell leuchten.

und was die spitzenströme angeht hast du prinzipiell recht, da die 
effektive einschaltzeit nur 25% sind. 80mA find ich aber dennoch ganz 
schön viel für einen einzigen pin. beim nächsten mal einfach vier 
PNP-transistoren (mit basiswiderständen bitte!!) opfern bzw. zur hand 
haben und du kannst sicher sein, daß es dauerhaft funktioniert. mußt nur 
aufpassen, daß die PNP-transistoren das signal invertieren, sprich bei 
logisch 0 am ausgang hast du 5v auf der segmentanzeige.
#1458539
Lesenswert?

Ben schrieb:

> und was die spitzenströme angeht hast du prinzipiell recht, da die
> effektive einschaltzeit nur 25% sind.

Allerdings muss der Strom ja auch durch die Spannungsanschlusspins des 
µC erst mal in den µC hineinkommen. Es gibt also nicht nur die eine 
Grenze, weiviel Strom durch einen einzelnen Pin rauskommen darf, sondern 
auch noch die Grenze, dass der Gesamtstrom eine Grenze nicht 
überschreiten darf.
OP #1458662
Lesenswert?

Die "Absolute Maximum Ratings" sind laut ATmega8-Datenblatt 05/09, Seite 
242 40mA pro I/O-Pin und 300mA bei den VCC- und GND-Pins.
Und dann schreiben sie, dass ein Port kurzzeitig auch mehr als 20mA 
aushält, dass aber dabei alle Ports zusammen nicht mit mehr als 300mA, 
die Pins C0-C5 nicht mit mehr als 100mA und die Ports B0-B7, C6, D0-D7 
und XTAL2 nicht mit mehr als 200mA belastet werden dürfen.

Da meine Anzeige funktioniert, werde ich die Schaltung nicht mehr 
umbauen (das würde außerdem entgültig zu Chaos auf meiner Platine 
führen), aber bei der nächsten Anzeige kann ich ja vor dem Löten mal 
etwas messen und rechnen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren