Hey! Das eine LED blinkt ist kein Problem. Ich habe jetzt aber versucht in meiner _delay_ms() Funktion eine Variable zu setzen statt einer Zahl: _delay_ms(x) -> das geht nicht. mit google fand ich die erklärung wieso das nicht funktioniert. Doch jetzt stellt sich mir die Frage, wie sonst geht das ?? Ich will das mit einem Poti sozusagen einstellen (den Wert -- zB 200 -> 200ms --> in _delay_ms(200);))
Nimm _delay_ms(1), pack den in eine Schleife und lass die 200mal durchlaufen.
Stefan S. schrieb: > Doch jetzt stellt sich mir die Frage, wie sonst geht das ?? Wenn dein µC auch noch andere Aufgaben übernehmen soll, vergiss die Funktion _delay_ms() ganz schnell wieder. Damit legst du den µC lahm, weil er die ganze Zeit mit Zeittotschlagen beschäftigt ist. Besser ist es, einen Timer so zu programmieren, dass er von sich aus läuft und entweder direkt (wenn du ihn anderweitig nicht brauchst) oder über regelmäßige Interrupts, in denen du Zählerstände auswertest (z.B. LED 200 Takte an, 50 Takte aus), die LED steuert.
Grundsätzlich stimme ich Patryk zu, nimm einen Timer und versuche es "Thread-ähnlich" aufzubauen. Solltest du dennoch, für einfache Aufgaben, den Delay nutzen wollen, mach es einfach so:
1 | void delayMS(uint16_t delay) |
2 | {
|
3 | for(uint16_t i = 0;i<delay;i++) |
4 | {
|
5 | _delay_ms(1); |
6 | }
|
7 | }
|
Aufrufen tust du das ganze dann halt einfach so:
1 | |
2 | delayMS(1000); |
3 | |
4 | //oder eben mit Variable:
|
5 | |
6 | uint16_t Warte = 2300; |
7 | delayMS(Warte); |
Draco schrieb: > Solltest du dennoch, für einfache Aufgaben, den Delay nutzen wollen Ich sehe das so: ein Delay zur bewussten Rechenzeitverschwendung hat in einer Hauptschleife nichts zu suchen und ist als Programmierfehler (oder besser Konzeptfehler) zu sehen... Gerade an einer simplen blinkenden LED kann man ideal z.B. mal einen Timer mit Interrupt ausprobieren und das Ganze mit einem Zustandsautomaten abhandeln. Damit wäre das ein Ansatz: http://www.lothar-miller.de/s9y/categories/22-Zeiten Wenn man keine ganz so langen Zeiten braucht (ein long reicht für einen ms-Takt von Montag früh bis Donnerstag Mittag), dann reicht auch eine 16 Bit Zählvariable.
das mit der for-schleife in einem unterprogramm, das habe ich mir auch schon überlegt. ich werde mich etwas mit den timern spielen. mal sehen ob sich da was gscheit's ergibt. falls ich was interessantes hab poste ich es
Hi >gibt es eigentlich eine Beschreibung zu dem Blockschaltbild von der ADU >(eine gute?) Also was zB ADMUX; ADCSRA,SFIOR, also die ganzen Register >machen bzw wozu sie dienen. Aktuelles Datenblatt? MfG Spess
1 | else if (counter == 3) |
2 | {
|
3 | ADC_Wert = ADC_Umsetzung(1); |
4 | itoa(ADC_Wert,Text,10); |
5 | lcd_print(1,0,Text); |
6 | lcd_write(" "); |
7 | |
8 | if(!(PIND & (1<<PD3))) break; |
9 | }
|
1 | uint16_t ADC_Umsetzung(uint8_t AD_Channel) |
2 | {
|
3 | // Kanal auswählen
|
4 | ADMUX |= AD_Channel; |
5 | // Umsetzung starten
|
6 | ADCSRA |= (1<<ADSC); |
7 | // warten bis Umsetzung beendet
|
8 | while (ADCSRA & (1<<ADSC)); |
9 | |
10 | return(ADC); |
11 | }
|
Das AD_Init ist richtig eingestellt. Mein Programm: Drücke ich das dritte mal den blauen Taster komme ich in diese If Bedingung die oben abgebildet ist. Gestern war der Wert am LCD immer aktuell, sobald ich am Poti gedreht habe. Solang der counter==3 war. Ich hab immer den richtigen Wert gehabt. Doch heute muss ich feststellen, (habe ein bisschen mit MUX0 gespielt, jedoch wieder den Bit gelöscht dann!) dass der immer nur einen Wert (den ersten anzeigt). War mein Poti ganz am Ende als ich in den counter==3 If reingekommen bin, hat er nur 1023 angezeigt, egal ob ich drehe oder nicht,.. woran kann das liegen? (gestern gings noch ohne eine while...........)
Zumindest das ist falsch: Stefan S. schrieb: > ADMUX |= AD_Channel; Das setzt nur zusätzliche "1"-Bits (ODER-Verknüpfung!). Du musst vorher alle Channel-Bits löschen (mit UND-Verknüpfung) bevor Du den neuen Channel-Wert hinein-ODER-st. Ob das jetzt Dein beschriebenes Problem löst habe ich nicht geschaut. Gruß Dietrich
Draco schrieb: > Grundsätzlich stimme ich Patryk zu, nimm einen Timer und versuche es > "Thread-ähnlich" aufzubauen. Sowas nennt sich "ereignisorientierte Programmierung". Hat mit Threads nur sehr bedingt etwas zu tun, eigentlich garnix. Eine gewisse Analogie entsteht nur daraus, das Ereignisse (im abstrakten Sinn) bei µC-Applikationen oft sehr direkt aus Interrupts stammen statt dass diese Tatsache durch Unmassen zeitfressender Schichten nutzlosen Glue-Codes vor dem Anwendungsprogrammierer verborgen wird, wie das bei "richtigen OS" gewöhnlich der Fall ist.
Na, das hättest Du doch dort Beitrag "Atmega32, Poti, ADC, Poti-am LCD ausgeben" gleich dranhängen können ... Stefan S. schrieb: > if(!(PIND & (1<<PD3))) break; Hast Du da nur die MAIN-(WHILE-) Schleife drum? Falls ja, solltest Du mal nachlesen, was so ein BREAK-Statement macht :-) Wenn der Prozessor nicht mehr arbeitet wird auch das LCD nicht mehr aktualisiert ...
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.