In der Funktion beid en Kommentaren kann man lesen was das Programm
können soll, allerdings blinkt die LED nach 3 Sekunden nur 1 mal kurz.
//----------------------------------------------------------------------
// Titel : Lichtschaltung mit Mikrocontroller MK2 von AVR
//----------------------------------------------------------------------
// Funktion : Wenn der Controller für <3 Sekunden betätigt wird
schaltet
// sich eine LED für genau 30 Sekunden ein. Bei längerem (3>)
// drücken schaltet sich die LED für 60 Sekunden an.
// Wenn der Taster für <1 gedrückt wird, leuchtet die LED
für 10 Sekunden.
// Schaltung : Taster an PORTD.2, LED an PORTB.0
//----------------------------------------------------------------------
// Prozessor : ATmega168P
// Takt : 3.6864 MHz
// Sprache : C
// Datum : 02.12.2005
// Version : 1.0
// Autor : Der Morrian
// Programmer : Der Morrian
// Port : ...
// CompilerOption: -Os
//----------------------------------------------------------------------
#define F_CPU 3686400 // Taktfrequenz des myAVR-Boards
#include <avr\io.h> // AVR Register und Konstantendefinitionen
#include <util\delay.h> //Wartefunktion
//----------------------------------------------------------------------
void light(int);
main()
{
int f;
DDRB = 0xFF; // PORTB = Ausgang
DDRD = 0x00; // PORTD = Eingang
PORTD = 0x04; // PORTD = PULL-UP
do
{
for(f=0;!(PIND&0x04);f++)
_delay_ms(20);
f*=20;
if(f<1000)
light(10000);
else if(f<3000)
light(30000);
else
light(60000);
}
while (true); // Mainloop
}
void light(int time_ms)
{
PORTB = 0x00;
_delay_ms(time_ms);
PORTB = 0xFF;
}
Der Moriaan schrieb:> // Datum : 02.12.2005
Wenn deine AVR-Libc genauso alt ist, kann das _delay_ms keine so großen
werte verarbeiten. => Update.
Und
Der Moriaan schrieb:> _delay_ms(time_ms);
ist eine ganz ganz schlechte Idee. Der Parameter zu _delay_ms muss immer
eine Konstante sein. Warum? => siehe Doku.
Konstante bedeutet?
Achso und Datum ist falsch.
Programm ist am neusten Stand.
würde das mit waitMS(time_ms) funktioniern?
@ Sebastian: ja nur kurz halbe sekunde oder so
Schreib eine Funktion:
void delay_ms(uint16_t time)
{
for(uint16_t i=0; i<time; time++)
{
_delay_ms(1);
}
}
-->So umgehst du das Problem mit der eigentlichen _delay_ms, da du hier
die konstante 1 halt so oft aufrust, wie du sie brauchst...ist zwar
nicht das genauste, aber dürfte für dein problem erstmal reichen.
Gruß, Muggel
Der Moriaan schrieb:> ich verstehe die Funktion nicht.> Wäre nett wenn du mir die erklären würdest.
Das ist eine ganz normale for-schleife. Die zählt von 0 bis "time" und
wartet jedes mal eine millisekunde.
Schlag mal dein C-Buch auf, "for" sollte da in den ersten Kapiteln schon
vorkommen.
Naja, wie Schorsch schon geschrieben hat, sollte als Übergabeparameter
für die Lib-Funktion _delay_ms eine Konstante stehen. Zudem bin ich mir
nicht sicher, ob man auch nur 8-Bit Werte an diese Funktion übergeben
kann(Was in etwa max 255ms entsprechen würde).
Mit dieser Funktion ohne _ for dem delay umgeht man diese Hürde. Ich
sage einfach das der Übergabeparameter für _delay_ms() KONSTANT 1 ist,
also immer 1ms verzögert. Mit dieser Funktion realisiere ich, dass ich
bis 65536 ms, also etwa 65sec Verzögerung bereitstellen kann(das
uint16_t sorgt dafür, dass ich 16-Bit-Werte übergeben kann).
Die for-Schleife ruft dann einfach time-mal die 1ms-Verzögerung auf. Das
wars schon.
Funktioniert sie denn??
kopier die Funktion, so wie sie ist über deine main und
ändere dann die light-Funktion wie folgt:
void light(uint16_t time_ms)
{
PORTB = 0x00;
delay_ms(time_ms);
PORTB = 0xFF;
}
und dann verrate mir, obs funktioniert, oder nicht!
// f soll die Zeit in ms sein, die ein Taster gedrückt wird
3
>if(f<1000)
4
>light(10000);
5
>
6
>elseif(f<3000)
7
>light(30000);
8
>
9
>else
10
>light(60000);
11
>}
Da musst Du schon ziemlich genau die 3 Sekunden einhalten, um ein
light(6000) zu erreichen. Schau Dir mal den Zahlenbereich einer
16-Bit-int an und welchen Spielraum Du von 30000 aufwärts hast bis sie
überläuft.
Angenommen, Dein Tastendruck würde genau gemessen (was aus den von
anderen beschriebenen Gründen nur sehr ungefähr hinhaut), dürftest Du
nur zwischen 3 und 3,28 Sekunden drücken. Darüber bekommst Du
light(1000), also Dein kürzeres Blinken.
Lichtschaltung mit Funktion.o: In function `main':
Lichtschaltung mit Funktion.cc:(.text+0x132): Linkerfehler: undefinierte
Sprungadresse: `light(int)'
Hc Zimmerer schrieb:> Da musst Du schon ziemlich genau die 3 Sekunden einhalten, um ein> light(6000) zu erreichen. Schau Dir mal den Zahlenbereich einer> 16-Bit-int an und welchen Spielraum Du von 30000 aufwärts hast bis sie> überläuft.>> Angenommen, Dein Tastendruck würde genau gemessen (was aus den von> anderen beschriebenen Gründen nur sehr ungefähr hinhaut), dürftest Du> nur zwischen 3 und 3,28 Sekunden drücken. Darüber bekommst Du> light(1000), also Dein kürzeres Blinken.
Würde es denn mit einem anderen Datentyp funktionieren?
Hmm.. ich hab's mir gerade noch mal angeschaut. Ich war zu schnell und
meine Antwort kannst Du vergessen. Irgendwie sah ich dort, wo 3000
steht, 30000 stehen. Dann hätte die Antwort hingehauen. So aber nicht.
Argl ... jetzt kommt die Korrektur der Korrektur. An einer anderen
Stelle hast Du nämlich tatsächlich einen Überlauf.
Du kannst keinen light(60000) aufrufen, wenn der Parameter von light()
eine 16-Bit-Integer (signed) ist. Nimm kleinere Zahlen, übergebe z.B.
die Blinkzeit in Sekunden oder Zehntelsekunden.
.... etc. Oder?!
kann ich mir nicht vorstellen.
Überleg doch mal wie schnell f bei dir wächst :-)
(wenn er das f ganz einfach vernünftig warteZeit genannt hätte, dann
wärs wahrscheinlich zu einfach gewesen. Und im übrigen muss man die Zeit
eigentlich ja auch nicht explizit ausrechnen. Man kann ja die Vergleiche
auch auf die Anzahl der Schleifenwiederholungen aufbauen.
Ausserdem: Was passiert wohl, wenn der Benutzer auf der Taste
einschläft?
lol ja stimmt. bin schon zu müde und schreib nur stuss. ich klink mich
aus. wollte helfen aber verursache nur chaos. schönen abend alle
zusammen und guten erfolg.
//----------------------------------------------------------------------
// Titel : Lichtschaltung mit Mikrocontroller MK2 von AVR
//----------------------------------------------------------------------
// Funktion : Wenn der Controller für <3 Sekunden betätigt wird
//schaltet
// sich eine LED für genau 30 Sekunden ein. Bei längerem (3>)
// drücken schaltet sich die LED für 60 Sekunden an.
// Wenn der Taster für <1 gedrückt wird, leuchtet die LED
//für 10 Sekunden.
// Schaltung : Taster an PORTD.2, LED an PORTB.0
//----------------------------------------------------------------------
// Prozessor : ATmega168P
// Takt : 3.6864 MHz
// Sprache : C
// Datum : 02.12.2005
// Version : 1.0
// Autor : Der Morrian
// Programmer : Der Morrian
// Port : ...
// CompilerOption: -Os
//----------------------------------------------------------------------
#define F_CPU 3686400 // Taktfrequenz des myAVR-Boards
#include <avr\io.h> // AVR Register und Konstantendefinitionen
#include <util\delay.h> //Wartefunktion
//----------------------------------------------------------------------
void light(int);
void delay_ms(uint16_t time)
{
for(uint16_t i=0; i<time; time++)
{
_delay_ms(1);
}
}
main()
{
int f;
DDRB = 0xFF; // PORTB = Ausgang
DDRD = 0x00; // PORTD = Eingang
PORTD = 0x04; // PORTD = PULL-UP
do
{
for(f=0;!(PIND&0x04);f++)
_delay_ms(20);
f*=20;
if(f<1000)
light(10000);
else if(f<3000)
light(30000);
else
light(60000);
}
while (true); // Mainloop
}
void light(uint16_t time_ms)
{
PORTB = 0x00;
_delay_ms(time_ms);
PORTB = 0xFF;
}
Aktueller Code mit folgedem Fehler..
und bei dem ganzen Fachchinesisch hier versteh ich eh nix :/
/* Lichtschaltung mit Funktion.o: In function `main':
Lichtschaltung mit Funktion.cc:(.text+0x132): Linkerfehler: undefinierte
Sprungadresse: `light(int)'
*/
Sebastian schrieb:> lol ja stimmt. bin schon zu müde und schreib nur stuss.
Würd ich so nicht sagen.
Das Bespiel an sich ist nicht schwer, aber die ganze Vorlage ist schon
nahezu für die Tonne.
Allerdings sieht mir das alles zu sehr nach Hausaufgabe aus, sodass ich
mich ebenfalls ausklinke.
ohne jemandem nahetreten zu wollen, vorlage ist zu vergessen und
threaderöffner kann die tips nicht umsetzen.
diese Funktion hier:
1
voiddelay_ms(uint16_ttime)
2
{
3
for(uint16_ti=0;i<time;time++)
4
{
5
_delay_ms(1);
6
}
7
}
musst du hier
1
voidlight(uint16_ttime_ms)
2
{
3
PORTB=0x00;
4
_delay_ms(time_ms);
5
PORTB=0xFF;
6
}
aufrufen. Am besten auch gleich mit _delay_ms(100) auf 10tel sekunden
umbaun. aber ich glaub in deiner ganzen programmlogik ist der hund drin.
das mit f hochzählen funktioniert imho so nicht.
jetzt aber wirklich schluss. baba
Sebastian schrieb:> ohne jemandem nahetreten zu wollen, vorlage ist zu vergessen und> threaderöffner kann die tips nicht umsetzen.
Das Problem ist wieder mal das Übliche.
Die Grundlagen nicht lernen wollen, aber programmieren.
Und das hat alles nichts damit zu tun, kein C-Experte zu sein. Das ist
bis jetzt Stoff der 2ten oder 3ten der Unterrichtseinheit von 40.