Hallo Leute, ich bin Neu auf dieser Webseite und schwer begeistert von den vielen Informationen. Seit nun ein paar Tagen habe ich angefangen, hier zu lesen und mich etwas in die Materie einzuarbeiten. Ziel soll es sein, dass ich kein Code - Kopierer werde, sondern das ich die Materie verstehe und selber entwerfen kann. (auch wenn es lange dauert:-) ) Es sind bei mir auch einfachste Grundkenntnisse in C vorhanden. Aber irgendwie bekomme ich das folgende Übungsprogramm trotzdem nicht zum laufen und hoffe auf Hilfe. Ich möchte lediglich ein Programm schreiben, welches die Tastendrücke zählt, die in einer bestimmten Zeit anliegen und diese dann später wieder ausgibt. Mein erster Ansatz, liegt in der angehängten Datei. Ich hoffe, mir kann einer meinen Gedankenfehler aufzeigen und erklären. MfG, Julian
Codeausschnitt:
1 | if (!(PIND & (1 << PD7))) // Führe Aktion aus wenn, |
2 | // PD 7 auf Masse gezogen wird
|
3 | {
|
4 | anzahl++; // Inkrementiere anzahl um 1 |
5 | while(PIND & (1 << PD7)){ // Starte Schleife, |
6 | // wenn an PD7 ein High anliegt
|
Um in dem if Fall in das while reinzukommen, musst du den Taster extrem schnell loslassen. Das schafft das kein Mensch (außer Chuck Norris natürlich).
Hallo, Du hast zwar verraten, was Du erreichen willst, nicht aber, was stattdessen passiert... Gruß aus Berlin Michael
Hallo, unabhängig davon, ob Dein Code wirklich das tut was er soll, hast Du Deine Aussgabe (LED blinken) innerhalb des Bereichs positioniert in dem der Schalter gedrückt ist.
1 | #include <avr/io.h> // Register Deklaration |
2 | #include <util/delay.h> // Timer Funktion |
3 | |
4 | int main(void){ // Hauptfunktion |
5 | |
6 | DDRB = 0xff; // Port B ist Ausgang |
7 | DDRD = 0x00; // Port D ist Eingang, Eing�nge sind �ber einen Wid. nach VCC gezogen |
8 | |
9 | unsigned char anzahl=0, i; // Variablendefinition |
10 | |
11 | |
12 | for(;;) |
13 | { // Endlosschleife |
14 | if (!(PIND & (1 << PD7))) // F�hre Aktion aus wenn,PD 7 auf Masse gezogen wird |
15 | {
|
16 | anzahl++; // Inkrementiere anzahl um 1 |
17 | }
|
18 | |
19 | if (PIND & (1 << PD7)) |
20 | { // Starte Schleife, wenn an PD7 ein High anliegt |
21 | _delay_ms(500); // ca. 5 Sekunden warten |
22 | for(i = 0;i > anzahl;i++) |
23 | { // Schleife, so oft ausf�hren wie Tastegedr�ckt worden ist |
24 | |
25 | PORTB = 0xff; // Port B einschalten |
26 | _delay_ms(100); // ca. 1 Sekunde Pause |
27 | PORTB = 0x00; // Port B ausschalten |
28 | _delay_ms(100); // ca. 1 Sekunde warten |
29 | } // Ende for |
30 | } // Ende if |
31 | } // Ende for, Endlos |
32 | }
|
Gruß Frank
So könnte es gehen:
1 | #include <avr/io.h> // Register Deklaration |
2 | #include <util/delay.h> // Timer Funktion |
3 | |
4 | int main(void) |
5 | {
|
6 | unsigned char anzahl = 0; |
7 | unsigned char hunderstel = 0; |
8 | unsigned char i; |
9 | |
10 | // Hardwareinitialisierung
|
11 | DDRB = 0xff; // Port B ist Ausgang |
12 | DDRD = 0x00; // Port D ist Eingang, |
13 | // Eingänge sind über einen externen Widerstand nach VCC gezogen
|
14 | |
15 | // Arbeitsschleife
|
16 | for(;;) |
17 | {
|
18 | // Grobe Uhr
|
19 | _delay_ms(100); |
20 | hunderstel++; |
21 | |
22 | // Eingabe
|
23 | if (!(PIND & (1 << PD7))) |
24 | {
|
25 | // Zählen, wenn PD7 auf Masse gezogen wird
|
26 | anzahl++; |
27 | |
28 | // Warten auf losgelassen
|
29 | while(!(PIND & (1 << PD7))) |
30 | {
|
31 | _delay_ms(100); |
32 | hunderstel++; |
33 | }
|
34 | }
|
35 | |
36 | // Ausgabe
|
37 | if (hunderstel >= 50) // ca. 5 Sekunden Eingabe abgelaufen? |
38 | {
|
39 | // Anzahl-mal Blinken
|
40 | for(i = 0; i < anzahl; i++) |
41 | {
|
42 | PORTB = 0xff; // Port B einschalten |
43 | _delay_ms(1000); // ca. 1 Sekunde Pause |
44 | PORTB = 0x00; // Port B ausschalten |
45 | _delay_ms(1000); // ca. 1 Sekunde warten |
46 | }
|
47 | |
48 | // Ausgabe erledigt, jetzt Uhr und Eingabe zurücksetzen
|
49 | anzahl = 0; |
50 | hunderstel = 0; |
51 | }
|
52 | }
|
53 | }
|
Hallo, danke für die ganzen schnellen Antworten!!! Also die letzte Version von Stefan B. habe ich getestet, aber sie läuft nicht richtig. Versuchsaufbau: ATmega 8 mit internem Takt von 8 MHz, Pin 13(PD7) mit Widerstand nach 5 VDC. Der Taster verbindet PD7 bei Betätigung mit Masse. An Port D sind LED Angeschlossen. Die Zeiten für An/Aus habe ich etwas nach unten geändert. Wenn ich den Taster betätige, wobei die Anzahl der Betätigungen keine Rolle zu spielen schein, dann blinken die LED's einmal auf und mehr passiert nicht. Eigentlich müsste er doch in der while- Schleife hängen, oder? Da der Taster nach der Eingabe nicht mehr betätigt wird, müsste er doch die hunderstel ins Endlose zählen?!?! MfG
> ATmega 8 mit internem Takt von 8 MHz Sicher? Ab Werk sind es 1 MHz. 8 MHz geht nur nach Umprogrammieren der Fuses. > An Port D sind LED Angeschlossen. Die LED müssen an PORTB angeschlossen werden! > Eigentlich müsste er doch in der while- Schleife hängen, oder? Da der > Taster nach der Eingabe nicht mehr betätigt wird, müsste er doch die > hunderstel ins Endlose zählen?!?! In der while Schleife bleibt der Eingabeteil so lange, wie der Taster noch gedrückt ist. Ewig gedrückt zählt auch hunderstel hoch bis ein Überlauf stattfindet (255 => 0), d.h. max. in 255*0,1s = 25-26s stellt sich die Uhr selbst zurück. Alle Zeiten sind nur gültig, wenn der Takt stimmt (1 MHz/8 MHz Geschichte). Bei falscher Einstellung hier wird es komisch.
Ja ich denke schon, habe den Takt im Makefile definiert (siehe Anhang). Ja sind sie, hatte mich vertippt.
Julian Vogel schrieb:
> Ja ich denke schon, habe den Takt im Makefile definiert (siehe Anhang).
Reicht nicht. Die HARDWARE muss entsprechend zur Definition im Makefile
eingestellt sein bzw. die Definition im Makefile richtet sich nach der
aktuellen Taktrate in der Hardware.
> In der while Schleife bleibt der Eingabeteil so lange, wie der Taster > noch gedrückt ist. Ewig gedrückt zählt auch hunderstel hoch bis ein > Überlauf stattfindet (255 => 0), d.h. max. in 255*0,1s = 25-26s stellt > sich die Uhr selbst zurück. Stimmt, die while Schleife ist ja hinter dem ersten if............ich sollte besser lesen ;-)
im Makefile steht aber doch: DEVICE = atmega8 CLOCK = 8000000 PROGRAMMER = -c USBasp Verstehe nicht was wo fehlt, bzw wo ich es einstelle.
Wenn deine Hardware wie ab Werk mit 1 MHz läuft und deine Definition im Makefile 8 MHz ist, dann laufen deine Wartefunktionen (_delay_ms) 8x zu langsam. Die grobe Uhr tickt statt im 0,1s Takt fast im 1s Takt. Eine Ausgabe ist erst statt in 5s in ca. 40s zu erwarten... Das kann die Geduld eines Testers auf die Probe stellen. Die Definition im Makefile ist in dem Fall nur (!!!) dazu da, um die Anzahl der Maschinenbefehle in der _delay_ms Funktion zu berechnen, so dass (Anzahl der Befehle) multipliziert mit (Zeit für einen Befehl) die angegebene Zeit vertröderlt wird. Wenn von der Hardware her die Zeit für einen Befehl nicht stimmt (Oszillator auf 1 MHz statt auf 8 MHz), stimmt die Rechnung nicht. Wie du die Taktrate (Clock) Hardware anders als in der Werkseinstellung einstellst, steht im Datenblatt. Ich rate dir als Anfänger aber, daran zunächst nichts zu ändern. Ändere lieber das Makefile von von 8000000 auf 1000000.
Stefan B. schrieb: > Wenn deine Hardware wie ab Werk mit 1 MHz läuft und deine Definition im > Makefile 8 MHz ist, dann laufen deine Wartefunktionen (_delay_ms) 8x zu > langsam. > > Die grobe Uhr tickt statt im 0,1s Takt fast im 1s Takt. Eine Ausgabe ist > erst statt in 5s in ca. 40s zu erwarten... Das kann die Geduld eines > Testers auf die Probe stellen. ggg alles klar, ich habe jetzt den Takt im Makefile auf 1 MHz gestellt und siehe da, deine Lösung funktioniert einwandfrei!!! Vielen Dank!! Gut daraus lerne ich, meine Fragen in Zukunft genauer zu stellen und mehr meine Birne anzustrengen. Motiviert durch den Erfolg, werde ich bestimmt zu einem Stammgast werden. MfG, Julian
Hallo Julian, die AVR werden aus Anlaufgründen (siehe Datenblatt) nicht mit der externen Taktfrequenz angefahren sondern es wird ein Vorteiler eingeschaltet (typisch /8). Diesen kannst du SW-technisch ausschalten, danach läuft der Prozessor mit voller Geschwindigkeit. Dein Makefile sollte daher auf die von Dir im Prozessor eingestellte Geschwindigkeit abgestimmt sein. Dies hast du in deinem Fall dadurch erreicht, daß du das Makefile geändert hast. SO geht es natürlich aus, aber die prozessorgeschwindigkeit hast Du damit noch nicht geändert. rgds
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.