PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AVR programmieren in C - Einsteigerfragen



Christoph2
27.07.2007, 17:02
Hallo!
Ich habe vor 2 Tagen begonnen, mikrocontoller zu programmieren, und habe auch schon ein paar Programme geschrieben, die dann auch funktioniert haben (Led an, ports als ein- oder ausgang festlegen, blinklichter, ...)
Das war aber alles nur mit ausgängen, jetzt will ich auch mal eingänge probieren. Dazu habe ich dann folgendes programm geschrieben:


#include <avr/io.h>
#include <stdint.h>

#define F_CPU 3686400UL
#include <util/delay.h>


int main (void)

{ DDRB=0x00; // Port B als Eingang
PORTB=0xff; // Pull-ups auf Port B ein
DDRC=0xff; // Port C als Ausgang
PORTC=0x00; // Alle Pins auf Port C auf low

uint8_t taster;

while (1)
{ taster=PINB; // Zustände von Port B in Variable taster speichern

while (taster) // Wenn taster gedrückt
{ PORTC=0xff; // Port C (wo LED angeschlossen) ein
taster=PINB; // Abfragen ob taster gedrückt
}


while(taster==0) // Wenn Taster nicht gedrückt
{ PORTC=0x00; // Led aus
taster=PINB; // Abfragen ob taster gedrückt
}

}
return 0;
}

Die led hängt auf port c, der taster auf port b.
Die Led sollte leuchten, wenn ich den taster drücke.

wenn ich es auf dn AVR brenne, leuchtet die led einfach nur, egal ob ich drücke oder nicht.

Könnt ihr mir sagen was ich falsch mache?
Und kennt ihr ein tutorial, bei dem das programmieren anhand von beispielen erklärt wird, oder nur irgendeine homepage, wo es den quellcode von so einfachen programmen gibt?
Beim tutorial von microcontroller.net finde ich gibt es zu wenige (vollständige) beispiele.

Grüße,
Christoph

user529
27.07.2007, 17:27
du machst alle pull ups an => PORTB geht auf 255, daraus folgt das teil springt in die erste schleife und bleibt dort, bis du den taster drückst. jetzt wartet die schleife so lange (while) bis das PORTB auf null geht, das kann er aber nicht, da 254 das höchste der gefühle ist.
beim zweiten hast du den gleichen fehler, da kann taster auch nie null werden.

Christoph2
27.07.2007, 19:17
Danke für die schnelle Antwort!
Ich habe das jetzt umgschrieben:


#include <avr/io.h>
#include <stdint.h>

#define F_CPU 3686400UL
#include <util/delay.h>


int main (void)

{ DDRB=0x00; // Port B als Eingang
PORTB=0xff; // Pull-ups auf Port B ein
DDRC=0xff; // Port C als Ausgang
PORTC=0x00; // Alle Pins auf Port C auf low

while (1)
{ while (bit_is_set(PINB, 3))
{ PORTC&=~(1<<PC5);
}

while (bit_is_set(PINB, 3))
{ PORTC|=(1<<PC5);
}

}
return 0;
}


Die Led hängt jetzt an C5 und der Taster an B2
Jetzt leuchtet die Led immer, außer wenn ich auf den Taster drücke, auch wenn ich bit_is_set und bit_is_clear vertausche.

Woran liegt das?

Grüße,
Christoph

izaseba
27.07.2007, 19:46
lass doch while hier weg, besser ist eine if Abfrage z.B.


if (PORTB & (1<<PB2))
PORTC &=~(1<<PC5);
else
PORTC |=(1<<PC5);



Gruß Sebastian

Christoph2
28.07.2007, 12:45
ok, ich habe das jetzt auf folgendes umgeändert:


#include <avr/io.h>
#include <stdint.h>

#define F_CPU 3686400UL
#include <util/delay.h>


int main (void)

{ DDRB=0x00; // Port B als Eingang
PORTB=0xff; // Pull-ups auf Port B ein
DDRC=0xff; // Port C als Ausgang
PORTC=0x00; // Alle Pins auf Port C auf low

while (1)
{ if(PINB & (1<<1))
{ PORTC|=(1<<PC5);

}
else
{
PORTC&=~(1<<5);
}

}
return 0;
}

es funktioniert immer noch nicht, ich bin wohl einfach zu dumm...
Die led auf c5 leuchtet jetzt immer, egal ob ich den taster drücke oder nicht.
Hat das wieder etwas mit den pullups zu tun?

Grüße,
Christoph

Christoph2
28.07.2007, 13:52
OK, ich bin schon weiter, ich habe in der IF abfrage PORTB statt PINB verwendet.

Die led leuchtet aber trotzdem immer, außer wenn ich auf den Taster drücke. Ich will aber, dass sie nur leuchtet, wenn man den taster drückt. Wenn ich die beiden if abfragen vertausche, den inhalt aber gleich lasse, sollte es doch umgekehrt sein? is es aber nicht. Was mache ich falsch???

EDIT: Jetzt habe ich es geschafft. ich weiß zwar nicht was falsch war, aber auf einmal gehts....

Grüße
Christoph

izaseba
28.07.2007, 14:00
2 Möglichkeiten ?:


while (1)
{ if (!(PINB & (1<<1)))
{ PORTC|=(1<<PC5);

}
else
{
PORTC&=~(1<<5);
}

}
oder

while (1)
{ if(PINB & (1<<1))
{
PORTC&=~(1<<5);
}
else
{
PORTC|=(1<<PC5);
}

}

Christoph2
30.07.2007, 11:05
Danke, ich habs jetzt geschafft!
Welche funktion kann ich verwenden, wenn ich ein paar sekkunden warten will? Das geht ja mit _delay_ms() nicht.

Grüße,
Christoph

Hubert.G
30.07.2007, 18:19
www.roboternetz.de/wissen/index.php/C-Tutorial
www.mikrocontroller.net/articles/AVR-GCC-Tutorial
Schau dir mal diese Tutorials an, die Kapitel mit den Timer, diese sind für Wartezeiten besser geeignet. Wenn deine Programme einmal etwas komplexer werden wirst du mit delay nicht glücklich, in dieser Zeit macht dein Kontroller nämlich nichts ausser warten, du kannst keine Eingänge pollen, nichts ausgeben usw.
Hubert