2x 7 Segment Multiplexen mit ATmega32 - Grundlagenproblem

OP #1776687
Lesenswert?

Hallo allerseits!

Ich möchte gerne (später) 2 sieben Segment anzeigen benutzen um 
zweistellige Zahlen anzeigen zu können. Leider bin ich ein ziemlicher 
Neuling auf dem AVR Gebiet und bitte daher um ein wenig milde falls ich 
Dinge nicht auf anhieb verstehe... :)

Ich habe mein Steckboard erstmal gemäß des Tutorials aufgebaut, sodass 
eine einzelne 7-Segment-Anzeige funktioniert:

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

Die Anzeige ist an PortD, PD0 bis PD6 angeschlossen und ein Testprogramm 
was von 0-9 zählt funktioniert auch.

Um mich an das Multiplexing heranzutasten habe ich nun eine zweite 
7-Segment-Anzeige angeschlossen (wie das Schaltbild im Tutorial sagt) 
und zwischen Anzeigen und Vcc jeweils einen Bipolartransistor 
angeschlossen. Die Basis der Transistoren über einen 1k Widerstand an 
PC5 und PC4 angeschlossen.

Ich möchte nun zunächst die Anzeigen erstmal ohne "richtiges" 
Multiplexen seperat ansteuern. Ganz simpel:

Anzeige A anschalten
Anzeige A soll Zahl anzeigen
Anzeige A ausschalten

Anzeige B anschalten
Anzeige B soll Zahl anzeigen
Anzeige B ausschalten

Nun habe ich ein wenig rumprobiert aber es funktioniert leider 
garnichts. Unabhängig vom Zustand von PC4 / PC5 bleiben beide Anzeigen 
aus. Wenn ich nun die Transistoren wieder rausbaue, dann zeigen beide 
Anzeigen (gleichzeitig) die Zahl an, die ich an PORTD rausschicke.

Woran könnte es liegen, bzw. was mach ich falsch?
Danke schonmal für jede Hilfe :)

Gruß,
Frank
OP #1776749
Lesenswert?

Hallo!

Den Anschluss der Transistoren habe ich aus unserem Schaltplan für unser 
Lern-Board im 2. Semester abgeguckt. Die Transistoren müssten baugleich 
mit denen vom Plan sein, da ich einen von der Uni vorgefertigten 
Warenkorb zum Nachbau eben jenen Boards bestellt habe.

Ausschnitt im Anhang

Hier mal mein Code. Meines Verständnisses nach müsste die Anzeige, die 
an PC5 hängt eigentlich funktionieren. Leider tut sich aber garnichts.
1
 
2
#include <avr/io.h>
3

4
void sevenseg_show(int number);
5

6
void main(void) {
7

8
  int i = 0;
9
  int j = 0;
10

11
  DDRD = 0xff;
12
  PORTD = 0xff;
13

14
  DDRC = 0xff;
15
  PORTC &= ~(1<<PC4);
16
  PORTC |= (1<<PC5);
17

18
  while(1) {
19
      for (j = 0; j < 10; j++) {
20
        for (i = 0; i < 5000; i++) {}
21
        sevenseg_show(j);
22
      }
23
  }
24
}
25

26
void sevenseg_show(int number) {
27

28
  static int numbers[] = {0x6f, 0x21, 0x5D, 0x79, 0x33, 0x7A, 0x7E, 0x29, 0x7f, 0x7B};
29

30
  PORTD = 0xff;
31
  PORTD &= ~(numbers[number]);
32

33
  return;
34
}
Angehängte Dateien:
#1776758
Lesenswert?

Frank Thetank schrieb:
> Hallo!
>
> Den Anschluss der Transistoren habe ich aus unserem Schaltplan für unser
> Lern-Board im 2. Semester abgeguckt. Die Transistoren müssten baugleich
> mit denen vom Plan sein, da ich einen von der Uni vorgefertigten
> Warenkorb zum Nachbau eben jenen Boards bestellt habe.

Da sind mir zuviele 'müsste' in deinem Satz enthalten :-)
Lieber nachmessen.

Hast du darauf geachtet, dass JTAG per Fuse abzuschalten?

Schreib dir ein Testprogramm, mit dem du nur die Pins am Port C 
ansteuerst. Und zwar gaaaaanz langsam ansteuern. Mit dem Voltmeter 
kannst du dann kontrollieren, ob die Pins auch wirklich auf 0 bzw. 1 
gehen. Dann misst du weiter: nach dem Basiswiderstand an der Basis der 
Transistoren: ist dort 0 und 1 immer noch vorhanden.

Immer in kleinen Schritten arbeiten. Nichts als gegeben voraussetzen. 
Immer überlegen: welche Voraussetzungen müssen gegeben sein und (ganz 
wichtig) wie kann ich die überprüfen?

Wenn du nicht weißt, ob die Pins am Port C richtig funktionieren, dann 
muss man sich eben ein Verfahren dafür ausdenken, wie man das 
feststellen kann. Wenn du keine Messgeräte hast um schnelle Pulse zu 
messen (Osziloskop), dann muss man eben die Pulse soweit verlangsam, 
dass man mit dem vorhandenen Voltmeter die Pulse sehen kann. Hat man 
kein Voltmeter dann muss eben eine einzelne Led (+ Vorwiderstand) diese 
Aufgabe übernehmen. Dank Digitaltechnik kann der Ausgang ja nur +5V oder 
0V haben, also: Led leuchtet oder Led leuchtet nicht.
Beim Nachmessen immer bei der Quelle anfangen. Bei dir: an den µC-Pins. 
Wenn dort schon die Signale nicht stimmen, kann hinten nach nichts 
richtiges mehr rauskommen.
OP #1776780
Lesenswert?

Hallo!

--
Hast du darauf geachtet, dass JTAG per Fuse abzuschalten?
--

Leider hab ich keine Ahnung was ein JTAG Fuse ist bzw. wie ich es 
abschalte.
Ich arbeite mit AVR Studio 4.18, flashe mit einem AVRISP mkII, der uC 
ist ein ATmega32.
Angeschlossen ist bis auf die 7-Segment-Anzeigen und der Anschluss für 
den ISP nichts weiter.

Zum testen habe ich jetzt mal eine einzelne LED angeschlossen (Vcc => 
LED => 1k Widerstand => PC5). Den Code habe ich dann auf folgendes 
reduziert:

1
  DDRC = 0xff;
2
  PORTC &= ~(1<<PC5);
3
  PORTC |= (1<<PC4);


Leider geht die LED nicht.

Was mache ich nun?
Gast #1776787
Lesenswert?

Hi

>Leider hab ich keine Ahnung was ein JTAG Fuse ist bzw. wie ich es
>abschalte.

Am PortC befindet sich das JTAG-Intercace. Das ist werksmässig 
eingeschaltet und blockiert etliche Pins von Port C.

Siehe Datenblatt:

JTAG Interface and On-chip Debug System

MfG Spess
OP #1776798
Lesenswert?

Hallo!

Ich habe nun im AVR Studio eine Funktion unter "Auto-Connect => 
Fuses..." gefunden (siehe Screenshot). Nachdem ich JTAGEN deaktiviert 
habe, funktioniert jetzt die 7 Segment Anzeige an PC4 auch mit dem 
Transistor.
Allerdings geht die an PC5 nicht. Folgender Code soll beide Anzeigen 
abwechselnd von 0-9 zählen lassen. Aber immer wenn PC5 dran ist, bleibt 
sie dunkel. Gefühlt zählt der uC ganz normal hoch, wenn wieder PC4 
Anzeige dran ist, funktioniert diese, usw.


1
#include <avr/io.h>
2

3
void sevenseg_show(int number);
4

5
void main(void) {
6

7
  int i = 0;
8
  int j = 0;
9

10
  DDRD = 0xff;
11
  PORTD = 0xff;
12

13
  DDRC = 0xff;
14
  PORTC &= ~(1<<PC4);
15
  PORTC |= (1<<PC5);
16

17
  while(1) {
18
      for (j = 0; j < 10; j++) {
19
        for (i = 0; i < 15000; i++) {}
20
        sevenseg_show(j);
21
      }
22
      PORTC ^= (1<<PC4);
23
      PORTC ^= (1<<PC5);
24
  }
25
}
26

27
void sevenseg_show(int number) {
28

29
  static int numbers[] = {0x6f, 0x21, 0x5D, 0x79, 0x33, 0x7A, 0x7E, 0x29, 0x7f, 0x7B};
30

31
  PORTD = 0xff;
32
  PORTD &= ~(numbers[number]);
33

34
  return;
35
}


Nachtrag:

Schließe ich eine einzelne LED an PC5 an, dann funktioniert diese nun 
auch einwandfrei.
Angehängte Dateien:
#1776803
Lesenswert?

Frank Thetank schrieb:

> Allerdings geht die an PC5 nicht.

Dann mach wieder dasselbe Spiel wie vorher:
überprüfe zunächst, ob Pin PC5 sich so verhält, wie du es erwartest (LED 
drann und nachsehen ob ein/ausschalten geht)

> Folgender Code soll beide Anzeigen
> abwechselnd von 0-9 zählen lassen.

Dein Code ist zwar .... unorthodox.
Nichtsdesto trotz kann ich jetzt aber erst mal nichts sehen, was ein 
aufleuchten der anderen Anzeige verhindern würde.


Edit: Deinen Nachtrag zu spät gesehen :-)
#1776831
Lesenswert?

Frank Thetank schrieb:
> Wozu sind die leeren Anschlüsse da? Ich hab mich zwar drüber gewundert
> aber da ich ja alle Ziffern darstellen konnte war mir das dann egal. ^^

Datenblatt!

Das sind die Anoden der Anzeigen, kurz gesagt die Anschlüsse für +
Die Anzeigen haben 2 davon (auf Pin 8 und auf Pin 3) und normalerweise 
sollte man auch beide anschliessen.

Wenn ein Baustein meherer Anschlüsse für + oder - hat, dann bedeutet das 
nicht notwendigerweise 'such dir den aus, der dir besser ins Layout 
passt', sondern: Der Baustein zieht im Extremfall soviel Strom, dass ein 
einziger Anschluss alleine überlastet wäre.
Gast #1776986
Lesenswert?

Ha. Den Schaltplan kenne ich doch. Das ist ja unser Spicboard :-)
Schön, dass du es schon hinbekommen hast. Hab das 7-seg Modul vor ca. 2 
Wochen nachgebaut. Ist gar nicht so schwer.

Hast du das Timermodul schon fertig?

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