Forum: Mikrocontroller und Digitale Elektronik 2x 7 Segment Anzeige - Multiplexen mit HF lässt Board ausgehen?


von Frank T. (franktank87)


Lesenswert?

Hallo allerseits!

Ich habe zwei 7-Segment-Anzeigen an meinen ATmega32 angeschlossen und 
würde gerne über Multiplexing eine zweistellige Zahl anzeigen. 
Zehnerstelle ist über einen Bipolartransistor an PC4 angeschlossen, 
Einerstelle an PC5.

Der Ablauf meiner Darstellungsfunktion sieht so aus:

Zehnerstelle einschalten
Zahl Darstellen
warten
Zehnerstelle ausschalten

Einerstelle einschalten
Zahl Darstellen
warten
Einerstelle ausschalten

Hier mal mein Code:
1
#include <avr/io.h>
2
3
void sevenseg_show_mp(int number);
4
5
void main(void) {
6
7
  DDRD = 0xff;
8
  PORTD = 0xff;
9
10
  DDRC = 0xff;
11
  PORTC &= ~(1<<PC4);
12
  PORTC |= (1<<PC5);
13
14
  while(1) {
15
      sevenseg_show_mp(4);
16
      PORTC ^= (1<<PC4);
17
      PORTC ^= (1<<PC5);
18
      sevenseg_show_mp(5);
19
      PORTC ^= (1<<PC4);
20
      PORTC ^= (1<<PC5);
21
  }
22
}
23
24
void sevenseg_show_mp(int number) {
25
26
  static int numbers1[] = {0x6f, 0x21, 0x5D, 0x79, 0x33, 0x7A, 0x7E, 0x29, 0x7f, 0x7B};
27
  int k = 0;
28
29
  PORTD = 0xff;
30
  PORTD &= ~(numbers1[number]);
31
  for (k = 0; k < 500; k++) {}
32
  PORTD = 0xff;
33
34
  return;
35
}

Wenn ich nun in der Funktion "sevenseg_show_mp" den Wert von k in der 
Warteschleife reduziere, z.B.
1
for (k=0; k < 100; k++) {}

dann geht nach ca. ein bis drei Sekunden das komplette Board mitsamt ISP 
einfach aus.
Bei k < 500 geht aber alles ganz normal. Warum ist das so und könnte es 
zu irgendwelchen HF Störungen des Boards kommen?
Eine genaue ms Zeit wie lange meine Schleife wartet hab ich leider auch 
nicht weil die _delay_ms() Funktion bei mir leider nicht funktioniert.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> dann geht nach ca. ein bis drei Sekunden das komplette Board mitsamt ISP
> einfach aus.
Sperr die Tür ab. Dann kann das Board nicht mehr einfach so ausgehen...
Oder definierst du "ausgehen" anders?

> Bei k < 500 geht aber alles ganz normal.
Häh? Passt doch: 100 ist doch kleiner als 500...

> weil die _delay_ms() Funktion bei mir leider nicht funktioniert.
Das würde mir aber zu denken geben. Such mal nach der Ursache.


Wie sieht übrigens die Schaltung aus (am besten in Bildform)?
Wie sieht die Versorgung aus?
Wird irgendwas warm?

von Anonym (Gast)


Lesenswert?

Ah wieder der Kollege mit dem Spicboard. "_delay_ms()" geht deswegen 
nicht, da das Modul nicht dem -ansi Standard entspricht.
Also entweder Ansi nicht eintragen oder besser ein eigenes Timermodul 
bastel.
Für die libspicboard  wurde der 16-bit Timer(1) im CTC-Modus, Prescaler 
1/8,
OCR 125 verwendet. damit klapp es super.

von Peter D. (peda)


Lesenswert?

Frank Thetank schrieb:
> dann geht nach ca. ein bis drei Sekunden das komplette Board mitsamt ISP
> einfach aus.

Werd mal konkreter.
Geht ein Reset?
Welcher Strom fließt?
Wird was warm?


> Bei k < 500 geht aber alles ganz normal. Warum ist das so und könnte es
> zu irgendwelchen HF Störungen des Boards kommen?

Unwarscheinlich.


> weil die _delay_ms() Funktion bei mir leider nicht funktioniert.

Da kommt doch bestimmt ne Fehlermeldung.

Allerdings ist fürs Multiplexen immer der Timerinterrupt zu nehmen, 
sonst flackern Deine LEDs abhängig vom Programm.

Und nimm besser uint8_t für Bytevariablen. Man muß ja den SRAM/Flash 
nicht mit Absicht verschwenden (int = 2 Byte).


Peter

von Frank T. (franktank87)


Lesenswert?

Hi!

-- Häh? Passt doch: 100 ist doch kleiner als 500... --

Sorry, das war ein Schreibfehler. Wenn ich k < 500 wähle schalten sich 
nach wenigen Sekunden sowohl ISP als auch Board ab.

-- Wie sieht übrigens die Schaltung aus (am besten in Bildform)?
Wie sieht die Versorgung aus?
Wird irgendwas warm? --

Die Schaltung ist exakt die gleiche wie im Tutorial:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige

Versorgung läuft über USB 5V, warm wird nichts (zumindest wenn ich AVR 
und die LEDs mit dem Finger prüfe).

-- Allerdings ist fürs Multiplexen immer der Timerinterrupt zu nehmen,
sonst flackern Deine LEDs abhängig vom Programm. --

Habe ich auch vor. Allerdings wollte ich zunächst das Prinzip verstehen 
und an einem einfachen Beispiel nachvollziehen.

-- Und nimm besser uint8_t für Bytevariablen. Man muß ja den SRAM/Flash
nicht mit Absicht verschwenden (int = 2 Byte). --

Wird gemacht :)

von Floh (Gast)


Lesenswert?

Frank Thetank schrieb:
> Versorgung läuft über USB 5V, warm wird nichts (zumindest wenn ich AVR
> und die LEDs mit dem Finger prüfe).

Kannst du deine Versorgungsspannung mal oszilloskopieren?
Würd mich nicht wundern wenn der USB-Port dir ohne Anmeldung den Strom 
verweigert.

von Karl H. (kbuchegg)


Lesenswert?

Frank Thetank schrieb:

Bitte benutze in Zukunft den Punkt 'Antwort mit Zitat', den du in jedem 
Beitrag unten rechts findest.
Es ist dann leichter auseinenaderzuhalten, worauf du antwortest und 
welches deine Antwort ist.

> -- Häh? Passt doch: 100 ist doch kleiner als 500... --
>
> Sorry, das war ein Schreibfehler. Wenn ich k < 500 wähle schalten sich
> nach wenigen Sekunden sowohl ISP als auch Board ab.

Das Bord wird sich nicht abschalten.
Aber ich denke mal deine Versorgungseinheit, die das Bord über USB mit 
Strom versorgt wird die Stromversorgung kappen.


> -- Allerdings ist fürs Multiplexen immer der Timerinterrupt zu nehmen,
> sonst flackern Deine LEDs abhängig vom Programm. --
>
> Habe ich auch vor. Allerdings wollte ich zunächst das Prinzip verstehen
> und an einem einfachen Beispiel nachvollziehen.

Ja. ok.
Für erste Spielereien ist das auch ok.
Nur solltest du dir fürs erste solche Dinge
1
  for (k = 0; k < 500; k++) {}

um damit Wartezeiten zu realisieren, von vorne herein gleich abgewöhnen. 
Wo immer du das her hast, es ist Unsinn. Jeder halbwegs brauchbare 
Compiler, der auch bei der größten Hitze noch bei Trost ist, schmeisst 
dir so eine Schleife wegen groben Unfugs raus.

Du bist auf einem AVR mit gcc. Da gibt es eine Funktion _delay_ms()
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

Auch wenn das so nicht bleiben wird, um zu warten ist das der Weg denn 
du gehen sollst und nicht irgendwelche Schleifenkonstrukte, die vom 
Compiler eliminiert werden.

Und das was Anonym (Gast) weiter oben geschrieben hat: Ignoriere es. Da 
dürfte die Hitze zugeschlagen haben.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Versorgung läuft über USB 5V
Ändere das mal auf eine vernünftige Versorgung. Gerade bei der 
Entwicklung sollte man solche unnötige Fehlerquellen ausschliessen...

>>>> Ich habe zwei 7-Segment-Anzeigen ... angeschlossen...
> Die Schaltung ist exakt die gleiche wie im Tutorial:
Kann gar nicht sein. denn dort gibt es keine Schaltung, die exakt zwei 
Anzeigen hat. Also kann es nur eine abgespeckte Version der hier sein: 
http://www.mikrocontroller.net/articles/Datei:Tut_7_Seg_03.gif
Stimmt das?
Welche Widerstände hast du verbaut?

von Klaus 2. (klaus2m5)


Lesenswert?

Frank Thetank schrieb:
> Zehnerstelle ist über einen Bipolartransistor an PC4 angeschlossen,
> Einerstelle an PC5.

HF-Transistoren? Verlustleistung steigt bei HF! Wenn es keine 
HF-Transistoren sind, sind beide Anzeigen vermutlich immer an = zuviel 
Strom. Grenzfrequenz beachten!

von Karl H. (kbuchegg)


Lesenswert?

Lothar Miller schrieb:

>> Versorgung läuft über USB 5V
> Ändere das mal auf eine vernünftige Versorgung. Gerade bei der
> Entwicklung sollte man solche unnötige Fehlerquellen ausschliessen...

Seh ich auch so.
Zumal wohl jeder heutzutage eine Unmenge an geeigneten Wandwarzen zu 
Hause rumliegen hat.

> Stimmt das?
> Welche Widerstände hast du verbaut?

Aus dem Vorgängerthread: 7 * 330 Ohm pro Anzeige.
Also eigentlich ziemlich moderat. Aber in Summe wohl doch zuviel für den 
USB Controller, so dass der abschaltet.

von Boa is des warm heid (Gast)


Lesenswert?

Servus miteinand!
Kann es sein, dass das 
(http://www4.informatik.uni-erlangen.de/Lehre/SS10/V_SPIC/Board/) deine 
Schaltung ist?

Wurde weiter oben ja bereits erwähnt.

von Anonym (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Und das was Anonym (Gast) weiter oben geschrieben hat: Ignoriere es. Da
> dürfte die Hitze zugeschlagen haben.

Äh?!? NEIN

In der Uni wurde uns gesagt, wir sollen folgendes im AVRStudio 
einstellen:
> Setzen der Projekteinstellungen (Project - Configuration Options)
> Frequency: 1000000 Hz (1 MHz = 1.000.000)
> Optimization: -O0
> Wichtig: Die vier Haken rechts daneben deaktivieren
> Bereich Include Directories: Q:\i4\ aufnehmen
> Bereich Libraries (bei Verwendung der SPiCboard-Bibliothek)
> Q:\i4\ in Library Search Path aufnehmen
> libspicboard.a bei Available Link Objects anwählen, Add Library klicken
> Compileroptionen im Bereich Custom Options
> -std=gnu99 entfernen
> -ansi hinzufügen
> -pedantic hinzufügen
> -ffreestanding hinzufügen

Wenn man nun die Funktion "_delay_ms()" verwenden will funktioniert dies 
nicht. Wenn man -ansi weglässt funktioniert es.

Die Sache zum Timer, die ich gesagt habe. Bezieht sich auf andere 
Module, die wir in der Uni verwenden 
http://www4.informatik.uni-erlangen.de/Lehre/SS10/V_GSPIC/Uebungen/doc/
Das Timer-Modul verwendet den von mir erwähnten Timer.

Verzeihung, wenn ich mich noch nicht zu gut auskenne wir jemand, der das 
schon seit 30 Jahren macht.
Ich beschäftige mich (so wie der Fragesteller wahrscheinlich auch) erste 
seit diesem Semester mit µC.

@ Boa is des warm heid: Ja das ist unser Spicboard ;-)

von Karl H. (kbuchegg)


Lesenswert?

Anonym schrieb:

>> Setzen der Projekteinstellungen (Project - Configuration Options)
>> Frequency: 1000000 Hz (1 MHz = 1.000.000)
>> Optimization: -O0
>> Wichtig: Die vier Haken rechts daneben deaktivieren
>> Bereich Include Directories: Q:\i4\ aufnehmen
>> Bereich Libraries (bei Verwendung der SPiCboard-Bibliothek)
>> Q:\i4\ in Library Search Path aufnehmen
>> libspicboard.a bei Available Link Objects anwählen, Add Library klicken
>> Compileroptionen im Bereich Custom Options
>> -std=gnu99 entfernen
>> -ansi hinzufügen
>> -pedantic hinzufügen
>> -ffreestanding hinzufügen
>
> Wenn man nun die Funktion "_delay_ms()" verwenden will funktioniert dies
> nicht. Wenn man -ansi weglässt funktioniert es.

Das mag sein, dass der Compiler dann ein paar Warnungen wirft.
Aber ein Board an sich ist weder 'ANSI-Kombatibel' noch ist es das 
nicht. Das ist einfach nur grober Unfug.

>> Optimization: -O0

Hier liegt dein eigentliches Problem. _delay_ms liefert nur dann 
einigermassen richtige Wartezeiten, wenn die Optimierung aktiviert ist. 
Also -Os anstelle von -OO

Wenn der Compiler dann immer noch, aufgrund -ansi, ein paar Warnungen 
wirft, müsste man sich die einmal ansehen. Ich schätze mal, dass sich 
der Compiler beschwert, dass sich -ansi und der geinlinte Assembler-Code 
beißt.

von Boa is des warm heid (Gast)


Lesenswert?

@Frank Thetank, bist du "mohamed.th" aus dem Uni-Forum?
@Anonym, ich studiere E-Technik 2. Semester auch in Erlangen, deshalb 
kam mir der Begriff Spicboard bekannt vor.

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:

>>> Compileroptionen im Bereich Custom Options
>>> -std=gnu99 entfernen
>>> -ansi hinzufügen
>>> -pedantic hinzufügen
>>> -ffreestanding hinzufügen

> Wenn der Compiler dann immer noch, aufgrund -ansi, ein paar Warnungen
> wirft, müsste man sich die einmal ansehen. Ich schätze mal, dass sich
> der Compiler beschwert, dass sich -ansi und der geinlinte Assembler-Code
> beißt.

Nicht mal das.
Aber das Entfernen von -std=gnu99
ist kein so guter Rat.

von Karl H. (kbuchegg)


Lesenswert?

@Anonym

<Auf den Kopf schlag>
Ach mit 'Modul' war das Delay-'Modul' gemeint!
Ich hab das aufs Board bezogen.

Muss wohl die Hitze sein.

von Peter D. (peda)


Lesenswert?

Die Standardeinstellungen der AVRStudio sind eigentlich ganz vernünftig.
Sie durch unsinnige zu ersetzen, halte ich für groben Unfug.

Insbesondere das "-O0" ist problematisch, es macht das Assemblerlisting 
quasi unlesbar, weil haufenweise unnötige Instruktionen ausgeführt 
werden. Was mit "-Os" vielleicht in einem Befehl gemacht werden könnte, 
kostet dann etwa 20 Befehle.

Und das "-std=gnu99" braucht man unbedingt, wenn man Interrupts benutzen 
will. Dann braucht man die "atomic.h", sonst krachts.

"-fno-inline-small-functions" ist auch ganz nützlich.


Will man richtig programmieren lernen, dann darf man nur das 
hinschreiben, wovon man weiß, was es macht.
Bei der Zählschleife bis 100 oder 500 weißt Du es aber nicht. Das ist 
also finsteres Mittelalter der Programmiertechnik, pures Trail&Error, 
das absolute Nogo.
Sowas löscht Dir jeder Programmierer ungefragt von der Festplatte, wenn 
er es sieht.

Bei einem _delay_ms( Zeit ) weiß aber jeder Bescheid und Du brauchst 
Dich danach auch nicht mit der Stoppuhr daneben zu stellen, um die Zeit 
auszumessen.


Peter

von Frank T. (franktank87)


Lesenswert?

Hallo nochmal!

@ Erlangen-Crew:
Nein, ich bin nicht im SPiC Forum. Ich studiere zwar E-Technik in 
Erlangen im 4 Semester, hatte Spaß an SPiC und will nun das ganze Zeug 
selbst verstehen, designen und nutzen können aber im Forum war ich dort 
nie weiter.

Zum Thema:

Ich habe jetzt "-ansi" entfernt und "-std-gnu=99" wieder eingefügt sowie 
die Optimierung auf "-0s" gesetzt. Die "_delay_ms()" Funktion geht jetzt 
einwandfrei und das flashen geht auch schneller. Das lustige ist, dass 
der Compiler mit "-ansi" nichtmal Kommentare im Code zulässt. Warum das 
also empfohlen wird erschließt sich mir nicht. Falls mir keinen einen 
Grund angeben kann wozu das gut ist, bleibt "-ansi" draußen.

von Achim (Gast)


Lesenswert?

Kommentare werden mit "-ansi" auch unterstützt, allerdings nur Standard 
C Kommentar Blöcke (/* ... */). Die einzeiligen Kommmentare (// ...), 
wie sie in C++ eingeführt wurden, sind erst Bestandteil von C99.

Aber auch wenn das geht würde ich "-ansi" trozdem, aus den schon 
genannten Gründen, nicht nutzen.

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.