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

OP #1457212
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
@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.
@  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
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.
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
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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.