mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Ansteuerung einer 7-Segment-Anzeige mit ATmega8 funktioniert nicht mehr


Autor: Nils ‫‪ (n-regen)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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).
#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 1000000UL  //Taktfrequenz einstellen, damit _delay_ms() funktioniert
#endif
#include <util/delay.h>
#include <stdint.h>

////
////Beginn des neuen Teils
////

uint8_t bwert;  //wird in anzeigen() verwendet
uint8_t cwert;  //wird in anzeigen() verwendet

void anzeigen(uint8_t stelle, char zeichen)
{
  switch (stelle)  //der Stelle, die angesteuert werden soll, + geben, die anderen ausschalten
  {
    case 1: PORTD = ((PORTD && 0b11001100) || 0b00000001);
        break;
    case 2: PORTD = ((PORTD && 0b11001100) || 0b00000010);
        break;
    case 3: PORTD = ((PORTD && 0b11001100) || 0b00010000);
        break;
    case 4: PORTD = ((PORTD && 0b11001100) || 0b00100000);
        break;
  }
  switch (zeichen)  //den benötigten Segmentteilen - geben, die anderen ausschalten
  {
    case 'Y':  {
            bwert = 0b11010001;
            cwert = 0b11001111;
            break;
          }
    case 'E':  {
            bwert = 0b11100100;
            cwert = 0b11001111;
            break;
          }
    case 'A':  {
            bwert = 0b11000000;
            cwert = 0b11011111;
            break;
          }
    case 'H':  {
            bwert = 0b11000001;
            cwert = 0b11011111;
            break;
          }
  }
  PORTB = ((PORTB && 0b11000000) || bwert);
  PORTC = ((PORTC && 0b11001111) || cwert);
}

////
////Ende des neuen Teils
////

int main(void)
{
  DDRB = 0xFF;
  DDRC = 0xFF;
  DDRD = 0xFF;
  while (1)
  {
    /********
    Der alte Code zum YEAH-Erzeugen:
    PORTB = 0b00010001;
    PORTC = 0b00100000;
    PORTD = 0b00000001;
    _delay_ms(3);
    PORTB = 0b00100100;
    PORTC = 0b00100000;
    PORTD = 0b00000010;
    _delay_ms(3);
    PORTB = 0b00000000;
    PORTC = 0b00110000;
    PORTD = 0b00010000;
    _delay_ms(3);
    PORTB = 0b00000001;
    PORTC = 0b00110000;
    PORTD = 0b00100000;
    _delay_ms(3);
    ********/

    ////Der neue Code zum YEAH-Erzeugen
    anzeigen(1, 'Y');
    _delay_ms(3);
    anzeigen(2, 'E');
    _delay_ms(3);
    anzeigen(3, 'A');
    _delay_ms(3);
    anzeigen(4, 'H');
    _delay_ms(3);
    ////
  }
  return 0;
}

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probiers mal so:
  PORTB = ((PORTB & 0b11000000) | bwert);
  PORTC = ((PORTC & 0b11001111) | cwert);
Stichworte: logische Verknüpfung und bitweise Verknüpfung.

Autor: Ben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zuerst hoff ich mal die anzeigen sind low-current-typen und die 
vorwiderstände hast du nur im schaltplan weggelassen?

Autor: Nils ‫‪ (n-regen)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Ben (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die steht im datenblatt, ich glaub 20mA pro pin, 100mA pro port und 200 
oder 300mA fürs ganze gerät.

Autor: Nils ‫‪ (n-regen)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: pyotr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/Da meine Anzeige funktioniert, werde ich die Schaltung nicht mehr
umbauen.../

Naja, die Frage ist, wie lange die funktioniert...

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nils S. schrieb:
> 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.

rofl

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.