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
Mike32 schrieb: > An den Mikrokontroller habe ich einen 8 Megaherz Quarz angeschlossen. ... und hoffentlich auch aktiviert. Gruss Klaus
>#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.
Auf PIND schreibt man nicht;) Nimm PORTD. PIND &=~(1<<PIND0); //0 an PD0 Ausgeben //0 an Data PIND |=(1<<PIND1); //1 an PD1 Ausgeben //1 an Clock
Wow, das geht ja schnell. Danke! Ich ändere das mal eben und melde mich dann nochmal.
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?
> if (neuse==altse) > { Wieso "gleich"? Der Update muss erfolgen, wenn sich was verändert hat, wenn die Werte also ungleich sind!
> 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?
Hi
>if(second==9)
10 Sekunden dauern bei dir nur 9?
MfG Spess
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
1 | if (second != altse) |
2 | {
|
3 | for( i = 0; i < 9; ++i ) |
4 | {
|
5 | if( i < second ) |
6 | PORTD &=~(1<<PORTD0); |
7 | else
|
8 | PORTD |= (1<<PORTD0); |
9 | |
10 | PORTD |=(1<<PORTD1); |
11 | _delay_ms(1); |
12 | PORTD &=~(1<<PORTD1); |
13 | }
|
14 | |
15 | altse = second; |
16 | }
|
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.
Ja, dann vielen Dank erstmal. Werde mal ein wenig rum probieren. Wenn ich nochmal Fragen habe (und die habe ich bestimmt ;) ) melde ich mich nochmal.
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.