Hallo, vorerst muss ich gestehen, dass ich ein blutiger Anfänger im Bereich Mikrocontrollerprogrammierung bin aber schon ganz fleißig arbeite :D Ich benutze ein 4-Ziffern 7-Segmentanzeige (https://www.conrad.de/de/7-segment-anzeige-rot-high-efficiency-red-14-mm-2-v-ziffernanzahl-4-kingbright-cc56-11ewa-186570.html) Ich habe mir es selbst die Aufgabe gegeben mit den Mikrocontroller ATMEGA8 bis 9999 zu zählen und diese auf den 7-Segmentanzeige anzuzeigen und es auch in C Programmiert und auf den Flashspeicher des Mikrocontrollers draufgespielt. Folgende Pinbelegung habe ich PC0-PC3 werden die an oder ausgeschaltet. Die Ausgänge PD0-6 werden die Segmente angesteuert. In 3ms-Takt werden diese Ziffern halt an und ausgeschaltet. Abgesehen davon, dass ich pro minute 2,4 Sekunden langsamer zähle ist programmiertechnisch alles bestens. Nun stimmt die Anzeige nicht ganz, bzw. es scheint so, als könnte der Mikrocontroller nicht genug Strom erzeugen. Bei Atmega8 soll es ja pro PIN max. 40mA rausgegeben werden soll, wie viel es mA es insgesamt rausgeben kann weiß ich leider nicht. Da ich ja "multiplexe" (bzw. der Mikrocontroller nicht ich), dürfte ich ja nur den Stromverbrauch eines Ziffers in Betracht ziehen. Bei 7-Segmenten, was in meinem Fall 20mA pro LED verbraucht, bräuchte ich max. 140mA bei und das bei Ziffer 8. Das sollte doch für den ATMEGA8 kein Problem sein oder doch? PROBLEM: Was mich auch noch stutzig macht ist, dass immer die Segmente die im inneren Bereich sind, nicht richtig dargestellt werden (warum?). Bis 99 zeigt die Anzeige alles korrekt, ab 100 wird die mittlere Zahl nicht angezeigt und ab 1000 drei mal dürft ihr raten fehlen die beiden Nullen in der Mitte wieder. Etwa so : SOLL IST 9 9 99 99 999 9X9 9999 9XX9 Im obigen Beispiel zeigt die Buchstabe X die Stellen an, die ausgeschaltet sind. Ich hoffe ihr könnt mir weiterhelfen... Liebe Grüße :)
Das ich 2,4 Sekunden langsamer gezählt habe hing daran, dass ich ein Denkfehler reingehauen habe. Es ist so, dass ich bei den Timer 0.26112 Sekunden pro overflow hatte. Nun ist es so, dass ich gecheckt hatte ob mein Zähler >= 1 (also 1 Sekunde vergangen sind) war und habe dann den Zähler auf 0 gesetzt, dadurch gingen mir halt jedes mal 0,04448 Sekunden verloren gegangen. Nun ziehe ich den Zähler eine Sekunde ab und mir verbleiben die 0,04448 Sekunden noch auf den Zähler nicht mehr auf 0. Jetzt ist das ausgerechnet so, dass jede 6. Sekunde keine Sekunde dauert sondern ~0,8 Sekunden, aber was anderes fällt mir nicht ein. Aber hat niemand eine Idee, warum die Zwischenziffern nicht angezeigt werden? :/
Sercan S. schrieb: > Aber hat niemand eine Idee, warum die Zwischenziffern nicht angezeigt > werden? :/ Um 2 Uhr ? Hardware ist es nicht und ohne Code kann dir nur ein Hellseher weiterhelfen.
Ein MC hat keinen eigenen Willen. Er macht immer nur das, was Du einprogrammiert hast. Und er bewertet Deinen Code nicht, d.h. er führt auch den größten Bockmist aus, ohne mit der Wimper zu zucken. Alle auftretenden Fehler hast nur Du selber so einprogrammiert. Es gibt aber einen Trick, mal andere in den Code schauen zu lassen, die Quelldatei (*.c) als Anhang posten.
Sercan S. schrieb: > Bei 7-Segmenten, was in meinem Fall 20mA pro > LED verbraucht, bräuchte ich max. 140mA bei und das bei Ziffer 8. Das > sollte doch für den ATMEGA8 kein Problem sein oder doch? Kann es sein, dass du keine Vorwiderstände drin hast?
Kommentiere im Code doch mal die einzelnen Ziffern aus, dann kannst du eine "Stromknappkeit" ausschließen. Oder einfach mal den Strom messen, den deine Schaltung aufnimmt.
Sercan S. schrieb: > Aber hat niemand eine Idee, warum die Zwischenziffern nicht angezeigt > werden? :/ Es könnte am Programm liegen. Oder an der Hardware. Beides ist leider unbekannt.
Lothar M. schrieb: > Beides ist leider unbekannt. Und die Kristallkugeln sind schon wieder so stark verschlissen...
Sercan S. schrieb: > es scheint so, als könnte der Mikrocontroller nicht genug Strom erzeugen Natürlich nicht. Sercan S. schrieb: > dürfte ich ja nur den Stromverbrauch eines > Ziffers in Betracht ziehen. Bei 7-Segmenten, was in meinem Fall 20mA pro > LED verbraucht, bräuchte ich max. 140mA bei und das bei Ziffer 8. Ja. Dauerstrom für Dauerleuchten. > Das sollte doch für den ATMEGA8 kein Problem sein oder doch? Schau doch einfach ins Datenblatt. Bei mehr als 20mA wird bei den Ausgängen nichts mehr garantiert. Warum meinst du wohl, verwenden andere Leute extra stromverstärkende Bauteile zwischen uC und Anzeige ? Wenn du übrigens 4 Ziffern hast die wirklich 20mA (und nicht bloss 10mA wie bei den meisten Anzeigen) für Normalhelligkeit brauchen, dann musst du, bei 4-stelliger Multiplexanzeige, sogar 1/4 der Zeit 80mA pro Segment fliessen lassen, also 560mA pro Stelle, damit die Anzeige so hell wie bei Dauerstrom erscheint. http://www.dse-faq.elektronik-kompendium.de/dse-faq.htm#F.8.1
Nimm erst einaml Vorwiderstände für die Segmentleitungen, die den Segmentstrom (und damit auch den Stellenstrom) auf einen geringeren Strom bringen. worst case ist bei multiplex-Betrieb etwa: eine Stelle eingeschaltet, mit 8 Segmenten ein (eine "8" + dezpkt)um 2,5mA Segmentstrom und 20mA Stellenstrom einzustellen. Da muss der Widerstand zwischen µC-Pin und Segmentpin den Wert haben: (5V-1,6V) /2,5 mA = 1,36 kOhm ( 5V Betriebsspannung, 1,6V Spannung der LED im Segment). Dann leuchtet die Anzeige nicht gerade überwältigend, aber die Grenzwerte für den Pin eines atmega8 werden dann eingehalten. (Stellenstrom < 8x2,5 mA ) Ich selbst nehme, ganz brutal bastlerisch, meist 330 Ohm, ohne dabei wesentliche Störungen zu sehen. (bei "1" sind die Segmente aber etwas heller als bei "8") Bei 150 Ohm machte mit der Zeit der Stellen-Ausgang die Grätsche. bei größeren Helligkeiten muss man jedenfalls Stellentreiber einsetzen. Was die fehlenden Zeichen und die falschen Zeiten angeht, das ist sicher eine Frage der Software.
Peter R. schrieb: > worst case ist bei multiplex-Betrieb etwa: eine Stelle eingeschaltet, > mit 8 Segmenten ein (eine "8" + dezpkt)um 2,5mA Segmentstrom und 20mA > Stellenstrom einzustellen. Die Werte noch einmal mit der Anzahl der Stellen multiplizieren, um die effektiven Ströme der Segemente bei Multiplexbetrieb zu erhalten! > Da muss der Widerstand zwischen µC-Pin und Segmentpin den Wert haben: > (5V-1,6V) /2,5 mA = 1,36 kOhm ( 5V Betriebsspannung, 1,6V Spannung der > LED im Segment). Da weitere Spannungsabfälle an den Digit-Treibern (BCxxx oder MOSFET) entstehen, rechnet man besser (5 - 2,5) V / (4 x 2,5) mA = 250 Ohm pro Segment. Bei den o.g. Anzeigen ist der Wirkungsgrad mittelprächtig, weshalb man besser 100 - 150 Ohm verwendet.
Hallo, ich wollte mich bei euch bedanken, dass Ihr euch die Zeit genommen habt mir paar Ideen zu nennen. Ich habe das ganze mit 450 Ohm Widerständen ausprobiert und anschließend mit 1kOhm versucht zu betreiben und es war leider keine Besserung da. Ich bin nochmal mein Code durchgegangen ob ich irgendwelche Fehler erkenne und leider bin ich auf nichts gestoßen (leider erkennt man an seinem eigenen Code die Fehler nicht direkt), außer dass ich die PINs vllt. mal in ein Array reinpacke wo ich die durchiterieren kann um die Segmente ein und ausschalten zu können, daran wird es aber nicht scheitern, dass die Zwischensegmente wegbleiben. Am besten zeige ich euch mal den Code und Ihr habt vllt. ein Idee woran es scheitert...
1 | ISR (TIMER0_OVF_vect) |
2 | {
|
3 | interruptSecondCounter += 0.26112; // Bei 1Mhz, 8-Bit Timer und einem //prescalar von 1024 errechnet sich pro Interrupt so viel Zeit in Sekunden |
4 | if(interruptSecondCounter >= 1){ |
5 | interruptSecondCounter -= 1; //Eine Sekunde ist vergangen, wir //zählen hoch und ziehen, das unserem interruptSecondCounter ab |
6 | secondCounter++; //Zählt die tatsächlichen Sekunden |
7 | |
8 | //Bsp.: 9999 - (9999 % 1000) /1000 = (9999 - (999)) /1000 = 9
|
9 | digits[0] = (secondCounter - (secondCounter % 1000)) / 1000; |
10 | |
11 | //Bsp.: 9999 - (9999 % 100).... Ahh du heiliger Bimbo...
|
12 | //Ich kann doch nicht einfach 9999 % 100 machen und es von
|
13 | //9999 abziehen. Lägen wir bei 99 und das durch 100 sind 0,99
|
14 | // :D Fehler selbst gefunden...
|
15 | digits[1] = (secondCounter - (secondCounter % 100)) / 100; |
16 | digits[2] = (secondCounter - (secondCounter % 10)) / 10; |
17 | digits[3] = secondCounter % 10; |
18 | }
|
19 | |
20 | }
|
Wie ihr in meinem Timer-Interrupt sehen könnt, bin ich selbst auf den Fehler gekommen, während ich mein Code kommentiert habe :D :D :D Nehmen wir an wir haben die Zahl 155 gehabt. (155 - 55) / 100 = 1 (155 - 5) / 10 = 1,5 :D :D :D 155 % 5 = 5 Da ich die Ziffern einzeln abspeicher, habe ich bei der Berechnung von den zwischenstellen folgendes eingefügt: (155-5 - 100er-Ziffernanzahl * 100 - 1000er Ziffernzahl*1000) / 10 = (155-5-100-0) / 10 = 5 Wie mein Lehrer damals in der Lehre sagte: "Sercan der Fehler, liegt meistens 30 cm vor dem Bildschirm..." Ich danke euch allen, die versucht haben mir zu helfen. Ich glaube, das nächste mal sollte ich mein Code Schritt für Schritt durchgehen...
Hi Sercan! Kannst du vielleicht deinen kompletten Code posten, wenn du ihn noch hast? Ich hänge gerade vor einem ähnlichen Problem und würde das von dir gerne richtig nachvollziehen wollen :) LG Tomato
Auch so ein Satz der in jeden zweiten Thread passt : Mach Debugausgaben im Terminal. Sercan S. schrieb: > Ich danke euch allen, die versucht haben mir zu helfen. Ich glaube, das > nächste mal sollte ich mein Code Schritt für Schritt durchgehen... nein, sondern SOFORT wenn du auf einen Fehler stößt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.