Hallo,
ich versuche gerdade über einen Atmega8 Mikrocontroller eine Uhrzeit
über eine Lichtskulptur auszugeben.
Der Mikrokontroller steuert 8 LED Treiber (Allegro 6276 Schieberegister)
an.
Das Programm soll später natürlich noch erweitert werden.
Nun wollte ich die Ausgabe aber schon mal testen, nur leider
funktioniert mein Programm bis hier hin nicht richtig, bzw. es gibt
nichts aus.
Der Interrupt soll eigentlich jede 1ms kommen. Hierbei werde ich mich
wohl verechnet haben, jedoch sollte ja trozdem eine Ausgabe erfolgen.
An den Mikrokontroller habe ich einen 8 Megaherz Quarz angeschlossen.
Vieleicht erkennt ja jemand auf anhieb einen Fehler.
Gruß, Mike
>#include <avr/io.h>>#include <avr/interrupt.h>>//#define TIMER2_COMP_vect _VECTOR(3) // Zeile löschen>#include <util/delay.h>>#define F_CPU 8000000UL // Ist hier falsch
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL // besser in die Projektoptionen aufnehmen
#include <util/delay.h>
Übernimm das erst mal und dann noch mal melden.
So, habe das Programm jetzt soweit geändert.
#define F_CPU 8000000UL // besser in die Projektoptionen aufnehmen
diese Zeile habe ich nun gelöscht und im Programm (ich benutze AVR
Studio)
unter Project Options bei Frequency 8000000 eingetragen.
Habe ich das so richtig verstanden?
> for(a=0;a==9;a++) //Schieberegister auf 0 setzten
Schau bitte in ein C Buch deiner Wahl, wie die Einzelteile einer
for-Schleife funktionieren.
Das ist
for( initial; Schleifenbedingung; Inkrement )
Solange die Schleifenbedingung wahr ergibt (also ungleich 0) wird die
Schleife weiter ausgeführt. Bei dir wäre das: solange a den Wert 9 hat,
wird die Schleife ausgeführt. a wird aber nie 9 sein, denn du
initialisierst a mit 0. 0 ist aber nicht gleich 9 und damit kommt die
Schleife nie zur Ausführung.
Vergiss momentan mal die Zehener und Einer, Minuten und Stunden. Sieh
zu, dass du EIN Schieberegister in Betrieb nimmst. In deinem Code
wimmelt es nur so von lächerlichen C-Fehlern.
Volatile schüttet man nicht mit der Gießkanne aus.
Volatile sind ausschließlich die Variablen, die sowohl im Interrupt, als
auch im Main verwendet werden.
Und Konstanten schonmal garnicht.
Peter
Oh man,
das mit der for-Schleife ist natürlich ein Fehler!
Werde das heute Abend änderen sowie das Volatile vor allen Variablen
die nicht im Interrupt und Main genutzt werden weg nehmen.
Werde mich dann nochmal melden!
So, ich habe nun mal ein paar Sachen geändert.
Leider funktioniert es alles immer noch nicht.
Könnte ich evtl mit dem Timer bzw Interrupt etwas falsch gemacht haben?
Ich wollte eigentlich ereichen, dass der Interrupt jede 1ms ausgelöst
wird.
Oder evtl bei der sonstigen Ausgabe?
Mike32 schrieb:> So, ich habe nun mal ein paar Sachen geändert.
Wo?
Ich sehe immer noch die alten Fehler.
> if (neuse==altse)> for(a=0;a==b;a++) //Schieberegister weiter "schieben"> if (neusz==altsz)
usw. usw.
Soll ich dir jetzt wirklich jede einzelne Zeile raussuchen, damit du die
immer gleichen Fehler auch wirklich alle korrigierst?
Mike32 schrieb:> Habe dort nur 9 Led's. Danach soll in den Zehner Sekunden Block eine LED> angehen.
Wenn du meinst.
Dann zählt deine Uhr eben schon auf 10, wenn in der Realität nur 9
Sekunden vergangen sind. Tipp: Auch 0, wenn also keine LED brennt, ist
ein anzeigenswerte Zahl.
Aber das ist momentan noch nicht so wichtig. (Bei Minuten und Stunden
hast du denselben Quatsch. Deine Minute zb hat nur 49 Sekunden, sogar
weniger, weil ja pro 10 Sekunden 1 fehlt).
Erst mal kriegst du das jetzt zum Laufen. Um die korrekte Zählweise
kannst du dich später kümmern.
Was hast du da eigentlich mit deinem
"Schieberegister auf 0 setzen"?
Braucht doch kein Mensch. Du hast doch an einem Schieberegisterstrang,
so wie ich das im Code sehe, sowieso immer nur die Leds einer 'Spalte'
(also Zehner oder Einer). Schieb deine Zahlen raus und gut ists.
Du musst 9 LED für die Einer setzen: Wenn die Schleifenvariable kleiner
als die aktuelle Sekundenzahl ist, dann schiebst du ein 0 Bit raus und
ansonsten ein 1 Bit.
Und das ganze machst du nur, wenn du musst. Sprich, wenn sich die Einer
der Sekunden verändert haben.
Ich seh auch nicht, wo du in deinem Programm die Latch Enable bzw.
Output Enable Leitungen der SR bedienst.
Hast du denn ein paar Vorversuche mit EINEM Schieberegister gemacht, um
dich erst mal mit der prinzipiellen Vorgehensweise vertraut zu machen,
ehe du dich gleich auf eine Uhr gestürzt hast?
Es sind leider 16 bit Schieberegister, da diese vorhanden waren.
Das Programm war eigentlich so gedacht, dass ich 9x1 Bit hinein schiebe.
Wenn nun 9 Leds leuchten, wollte ich dort 9x eine "0" rein schieben und
dies schnell hintereinander damit alle neun leds wieder aus sind.
Schieberegister auf 0 setzen ist hier auch bestimmt eher unglücklich von
mir ausgedrückt.
Mike32 schrieb:> Wenn nun 9 Leds leuchten, wollte ich dort 9x eine "0" rein schieben und> dies schnell hintereinander damit alle neun leds wieder aus sind.
Ist doch viel zu kompliziert.
Du musst IMMER 9 Bits ins Schieberegister laden.
Die entscheidende Frage bei jedem Bit ist nur: muss es ein 0 Bit oder
ein 1 Bit sein
Den Latch Enable habe ich in der Schaltung dauerhaft auf High, den
Output Anable dauerhaft auf Low gelegt.
Bei dem manuellen probieren ohne Mikrokontroller sah man wie geschoben
wurde.
Mike32 schrieb:> Den Latch Enable habe ich in der Schaltung dauerhaft auf High, den> Output Anable dauerhaft auf Low gelegt.
Das heisst man sieht, wie du die Schieberegister befüllst :-)
Keine gute Idee.
Zumindest die Output Enable Leitung willst du steuern können!
Du willst die LED gezielt abschalten, dann die Schieberegister befüllen
und danach die LED wieder einschalten. Damit man eben nicht sieht, wie
du die Daten reintaktest.
Man könnte jetzt höchstens aus der Not eien Tugend machen, weil man ja
weiß dass die LED nicht in beliebiger Reihenfolge angehen, sondern immer
eine nach der anderen. Das verkompliziert aber das Programm ein wenig.
Also es war so gedacht, dass jede Sekunde eine Led mehr angeht und bei
der zehnten Sekunde alle neun "Einer Sekunden" Leds aus gehen und die
erste der 5 "Zehner Sekunden" Leds an geht.
Ab der elften Sekunde sollte wieder die erste "Einer Sekunden" Led an
gehen und dann nach 20 Sekunden die zweite "Zehner Sekunden" Led usw.
Habe das am Anfang glaube ich nicht so gut erklärt.
Oder habe ich hier einen Denkfehler?
Mike32 schrieb:> Oder habe ich hier einen Denkfehler?
Nein. Man kann das so machen.
Aber dein Programm geht noch nicht einmal ansatzweise in diese Richtung.
Es ist zwar nicht wahnsinnig schwer mit dieser Strategie die Uhr zu
befüllen, aber so wie ich das sehe ist das für dich noch schwer genug.
Daher: machs erst mal konventionell
Bei jeder Änderung die entsprechende Anzahl an leuchtenden LED neu
einstellen.
Und konzentrier dich für erste nur auf die Einsterstelle/Sekunden. Alles
andere löscht du jetzt erst mal raus.
Wenn du die korrekt laufen hast, dann baust du die Zehnerstelle ein. Und
wenn die dann geht, baust du die Minuten ein etc. etc.
Nicht zu viel auf einmal.
Eine eigene Frage?
Dieser Thread ist über 15 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.