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
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
intmain(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
unsignedcharanzahl=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
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.
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 ;-)
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