Hallo, Ich möchte eine LED an einem Pin des ATmega8 blinken lassen. Das Warten zwischen dem High- und dem Lowsetzen des Pins möchte ich mit der _delay_ms() funktion realisieren. Statt eines festen Wertes für die delay-funktion, möchte ich jedoch einen Parameter übergeben, welchen ich während der Programmlaufzeit verändern kann. Also in dem ich 2 weitere Pins als Eingänge definiere und wenn ich diese jeweils auf high lege, soll der an delay übergebene Parameter erhöht o. verringert werden. Die Programmierung erfolgt mit C im AVR-Studio, als Compiler verwende ich den GCC. Im Anhang habe ich einen Codeausschnitt eingefügt, wie ich es realisieren würde. Mein Problem ist, dass ich jedeoch die Wartezeit während Programmausführung auf dem µC nicht beeinflussen kann. Übergebe ich delay einen festen Wert u. lasse das herauf- / herabsetzen der Wartezeit weg, blinkt die LED wie gewünscht. Binde ich aber die While-schleifen zum wartezeit erhöhen o. verringern ein, lässt sich die delay-funktion nicht wie gewünscht beeinflussen. Mir ist leider nicht ganz klar wo hier das Problem liegt und wie ich diesen Fehler umgehen kann. Ich würde mich freuen wenn mir jemand einen Tipp geben könnte wie sich das geschilderte Problem mit Hilfe der Delay Funktion lösen lässt. Vielen Dank.
@ muckelsoft (Gast) >Statt eines festen Wertes für die delay-funktion, >möchte ich jedoch einen Parameter übergeben, welchen ich >während der Programmlaufzeit verändern kann. Mach es so.
1 | void long_delay(uint16_t ms) { |
2 | for (; ms>0; ms--) _delay_ms(1); |
3 | }
|
>Mein Problem ist, dass ich jedeoch die Wartezeit während >Programmausführung auf dem µC nicht beeinflussen kann. Doch kann man schon. Aber ein Blick in die Doku der libc verrät, dass man die Funktion nur mit einem konstantem Paramter aufrufen sollte, weil sonst Fliesskommaberechnungen nötig sind. Ausserdem sit deine Tastenabfrage nicht viel wert. Nicht enprellt und auserdem viel zu schnell. MFG Falk
@ Falk: Danke für die schnelle Antwort. Habe deinen Vorschlag mit der For-Schleife jetzt eingebunden. Das löst allerdings noch nicht mein Problem, wie ich während der Laufzeit die Wartezeit fürs An/Aus der LED beeinflussen kann. Das ist eigentlich das Hauptproblem an dem ich nicht so richtig weiterkomme. Ich würde den Wert für die entspr. Variable eben gerne während der Laufzeit (m.H. der Abfrage der 2 Pins, s.Quellcode) erhöhen oder verringern. Selbst wenn ich die Variable zuvor mit einem Konstanten Wert initialisiere ("int frq=30"),scheint es einfach nicht zu funktionieren. Wär super wenn mir jemand sagen könnte, wie das klappen könnte...
Punkt 1: Wenn du ein Problem mit einem Programmstück hast, dann poste das Programmstück und nicht eine Beschriebung davon Punkt 2: So in etwa
1 | void Warte( int ms ) |
2 | {
|
3 | int i; |
4 | |
5 | for( i = 0; i < ms; ++i ) |
6 | _delay_ms( 1 ); |
7 | }
|
8 | |
9 | int main() |
10 | {
|
11 | int Wartezeit; |
12 | |
13 | while( 1 ) { |
14 | |
15 | for( Wartezeit = 10; Wartezeit < 1000; Wartezeit += 10 ) { |
16 | Led_ON; |
17 | Warte( Wartezeit ); |
18 | Led_Off; |
19 | Warte( Wartezeit ); |
20 | }
|
21 | }
|
22 | }
|
Nach jedem Blinken wird die Wartezeit um ein kleines bischen länger, bis sie ihren Maximalwert von 1 Sekunde erreicht hat. Danach geht das Spielchen wieder von vorne los.
Du hast die beiden _delay_ms-Aufrufe aus deinem Code, durch ein long_delay(frq); ersetzt, ja? Dann würde ich in den beiden while-Schlifen in denen frq geändert wird, noch ein _delay_ms(2); ('2' nur als Beispiel) einfügen, und aus der 10 eine 1 machen. Denn sonst wird die Variable viel zu schnell rauf bzw. runter gezählt. Was dein Code bissher macht, is folgendes: Wenn du PD0 auf Low setzt, hört die LED auf zu blinken, und du kannst mit PD1 und PD3 die Blinkgeschwindigkeit einstellen. Wenn du PD0 wieder auf High setzt, blinkt die LED mit der neuen geschwindigkeit. Is das das was du beabsichtigst?
@ Eiko: "Was dein Code bissher macht, is folgendes: Wenn du PD0 auf Low setzt, hört die LED auf zu blinken, und du kannst mit PD1 und PD3 die Blinkgeschwindigkeit einstellen. Wenn du PD0 wieder auf High setzt, blinkt die LED mit der neuen geschwindigkeit. Is das das was du beabsichtigst?" Ja, genau dass sollte er tun, aber es funktioniert nicht. Ich habe den kompletten Code des Programms nochmal in den Anhang geladen.Dann könnt ihr nochmal drauf schauen, wo der Fehler stecken könnte/was ich falsch gemacht habe. Beim Compillieren bekomme ich auch keine Fehlermeldung, wenn ich den Code in den Atmega8 lade, gehts nicht wie es soll. Der Atmel läuft bei mir mit 8Mhz und als Optimierung habe ich "-Os" eingestellt.
muckelsoft wrote: > Ja, genau dass sollte er tun, aber es funktioniert nicht. Kannst du das präzisieren? Was bedeutet: Funktioniert nicht. So wie ich das sehe, musst du deine Steuerleitungen schon eine ganze Weile auf 1 halten, damit du die freq Variable hinreichend weit veränderst um eine Änderung der Blink- frequenz sehen zu können. Du hast in der Schleife eine Wartezeit von 30 ms. D.h. nach 1 Sekunde Steuereingang auf 1, hat sich die freq Variable von 30 auf 60 erhöht. Das entspricht dann einer Abnahme der Frequenz von 16Hz auf 8Hz. Bei 33Hz solltest du als Normalsterblicher noch ev. ein Flimmern der LED erkennen können, bei 8Hz ist das dann eher ein hektisches Geflacker.
Noch eine Frage: Wie sieht bei dir die Beschaltung vom PORTD aus? Sind da Taster oder sonstwas dran? Grund der Frage: So wie du das in deinem Program hast, ist das eher unüblich. Deine Taster sind laut Programm high-side geschaltet. D.h. du musst am AVR Pin einen Widerstand nach Masse haben, sowie einen Taster der den Pin nach 5V zieht. Der Widerstand als Pull-Down Widerstand ist absolut notwendig! Ansonsten weiss nur Gott alleine, welchen Wert dein Port bei offenem Eingang meldet.
@ kbuchegg: An den Pins habe ich einen Taster, der diese mit 5Volt verbindet. Hat bis jetzt bei anderen Projekten immer geklappt, deswegen denk ich nicht das fehlende Widerstände die Ursache dafür sind, dass mein Programm nicht geht. Ich vermute den Fehler eher irgendwo im Code. (Für den Fall das es doch am Widerstand liegen sollte, welchen kOhm-Wert soll ich dranlöten?) Mit "geht nicht" meine ich, dass ich zwar PD0 auf 5V legen kann (Taster gedrückt) dann blinkt die LED. Drücke ich die Taster für Wartezeit herauf/herab also PD1 oder PD3, hat das keinen Einfluss auf auf die Blinkfrequenz (was es aber eigentlich haben sollte) wenn ich danach wieder den PD0 Taster drücke...
@ muckelsoft (Gast) >An den Pins habe ich einen Taster, der diese mit 5Volt verbindet. Und warum machst du es nciht wie alle anderen? AVR-Tutorial: IO-Grundlagen >Hat bis jetzt bei anderen Projekten immer geklappt, deswegen >denk ich nicht das fehlende Widerstände die Ursache dafür sind, dass DOCH! MFG Falk
muckelsoft wrote: > @ kbuchegg: > > An den Pins habe ich einen Taster, der diese mit 5Volt verbindet. OK. Was hängt am Eingang, wenn der Taster nicht gedrückt ist? > Hat bis jetzt bei anderen Projekten immer geklappt, deswegen > denk ich nicht das fehlende Widerstände die Ursache dafür sind, dass > mein Programm nicht geht. Ich vermute den Fehler eher irgendwo im Code. > (Für den Fall das es doch am Widerstand liegen sollte, welchen > kOhm-Wert soll ich dranlöten?) Nimm 10k. Der Wert ist nicht allzukritisch. Du kannst alles von 1k bis 1M benutzen, solange es nur den Pin bei nicht gedrücktem Taster auf Masse zieht. Vcc | | / / | AVR -----------+ | +-+ | | 10k | | +-+ | | GND Ob das bei anderen Projekten geklappt hat oder nicht, spielt keine Rolle. Wenn der Widerstand nicht da ist, hängt der Eingang des AVR in der Luft und der fängt sich dort alles möglich ein. Als ich meinen ersten Frequenzmesser mit einem AVR baute, zeigte der am offenen Eingang, also ohne dass irgendetwas an den Pin angeschlossen war, wunderbare 50Hz an. Rate mal wo die herkommen :-) Oder aber du machst das ganze anders rum. Den Taster schliesst du vom AVR-Pin nach Masse an. Dann kannst du an diesem Port die im AVR eingebauten Widerstände aktivieren und brauchst keine äusseren. Einziger Unterschied: Per Programm stellst du eine 1 fest, wenn der Taster nicht gedrückt ist, und eine 0 wenn der Taster gedrückt ist. Das ist dann eigentlich auch die übliche Art einen Taster anzuschliessen, weil man sich dadurch die externen Widerstände spart.
@ kbuchegg: Danke für die ausführliche Hilfestellung. Hab den Pulldown Widerstand jetzt drangelötet und siehe da, es funktioniert nun :) Lag also demnach wirklich nur am Widerstand... Danke nochmal an alle für die schnelle Hilfe.
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.