Hallo,
so langsam drehe ich am Rad und bitte um Hilfe. Habe offensichtlich
einen Grundsatz-/Verständnisfehler in meiner "Denke".
Ich möchte einfach nur, wenn eine Taste gedrückt ist eine LED leuchten
lassen.
Bin auf dem Gebiet C und µC newbie.
Belegung:
Taste: PORTA Pin 0
LED: PORTA Pin 4
Code:
1
#include<avr/io.h>
2
3
voidinit(void);
4
5
intmain(void)
6
{
7
8
init();// Ports initialisieren
9
10
while(1){
11
12
if(PINA&(1<<PA0)){// Taste 1 gedrückt
13
PORTA&=~(1<<3);// LED PORTA - Pin 4 an
14
}
15
16
for(;;);
17
}//main
18
19
20
21
voidinit()
22
{
23
24
//PORTA auf Ausgang
25
DDRA=0xff;
26
27
// PORTA - Bit 0, 1 und 2 auf Eingang
28
DDRA&=~((1<<DDA0)|(1<<DDA1)|(1<<DDA2));
29
30
//set all internal pullups
31
PORTA=0xff;// on
32
}
Ich weiß, dass es Handbücher gibt, aber ich finde keine Lösung und bitte
um Hilfe.
Soll die LED beim Loslassen der Taste auch wieder aus gehen, oder nicht?
Bitte bei Fragen immer den echten Code posten. Den Code oben kannst du
gar nicht ausprobiert haben, denn der wird wegen einer fehlenden Klammer
gar nicht compilieren. Und da wir nicht wissen, wo diese zusätzliche
Klammer war/ist, wissen wir auch nicht, ob die zweite Endlosschleife
tatsächlich innerhalb der anderen war/ist (böse), oder dahinter
(überflüssig, aber harmlos).
@ Stefan:
ok, nur mein gesamter Originalcode ist zu lang und deshalb habe ich die
wesentlichen Stellen, wie ich meinte herausgezogen.
Wollte nur das Prinzip darstellen.
@ Simon:
Super, danke,
das war die Lösung. Mit dem bit_is_set Ausdruck hat es funktioniert, ist
auch einfacher.
Gruß
Dietmar
Nachtrag:
Schönheitsfehler: Wenn ich den Taster drücke, dann geht die LED an.
Aber wenn ich den Taster loslasse, dann flimmert die LED, geht auch mal
aus, aber nicht gleich, oder sie flimmert auch weiter.
Allerdings habe ich für alles den PORTA nehmen müssen.
Definition des PORTA:
// PORTS auf Ausgang
DDRA = 0xff;
// PORTA - Bit 0, 1 und 2 auf Eingang
DDRA &= ~(( 1<< DDA0 ) | ( 1<<DDA1) | ( 1<<DDA2));
//set all internal pullups
// PORTA=0xff; // on
Ist da was falsch?
Dietmar P. schrieb:> Nachtrag:>> Schönheitsfehler: Wenn ich den Taster drücke, dann geht die LED an.> Aber wenn ich den Taster loslasse, dann flimmert die LED, geht auch mal> aus, aber nicht gleich, oder sie flimmert auch weiter.> Allerdings habe ich für alles den PORTA nehmen müssen.
Welcher Prozessor?
wenn du das so schreibst:
// PORTA=0xff //on dann ist das Auskommentiert! und hat keine funktion.
nimm die beiden doppel Slasch weg oder
Klemm vor den taster einen Pull-Down hin und es funkt zu 100 %
Richtig, da habe ich den Wald vor lauter Bäumen wieder einmal nicht
gesehen.
ABER:
Das Geflimmer bleibt, habe es soeben auch mit externen Pullup's
probiert,
auch keine Veränderung, leider.
Noch 'ne Idee?
Dietmar P. schrieb:> Richtig, da habe ich den Wald vor lauter Bäumen wieder einmal nicht> gesehen.>> ABER:>> Das Geflimmer bleibt, habe es soeben auch mit externen Pullup's> probiert,> auch keine Veränderung, leider.>> Noch 'ne Idee?
OK.
Dann nochmal die Frage:
AVcc und AGND sind beschaltet?
Ich hoffe das passt so.
Ist da ein grundsätzlicher Fehler drin? Vor dem bit_is_set hatte ich da
folgende Codezeile:
if (!(PINA&(1<<PINA1));{
Ist das richtiger?? Mein Taster geht geschlossen auf GND.
Dietmar P. schrieb:> void taster_abfrage(void)> {>> if (bit_is_set (PINA, PINA0)){ // Taste 1 gedrückt
wenn deine Taster auf GND schalten, dann kriegst du bei gedrückten
Taster aber im Pin eine 0 und keine 1.
D.h.
if( bit_is_clear (PINA, PINA0) ) {
ausserdem solltest du noch einen else Zweig vorsehen, der die LED bei
nicht gedrückten Taster auch wieder zurückschaltet.
> Ist da ein grundsätzlicher Fehler drin? Vor dem bit_is_set hatte ich da> folgende Codezeile:>> if (!(PINA&(1<<PINA1));{
Da ist ein Strichpunkt zuviel.
Nichts gegen viele Funktionen und Aufteilung in mehrere Files. Aber
gerade am Anfang schafft dir das mehr Probleme, als es dir bringt. Die
verringerte Übersicht lässt dich Fehler begehen, die du nicht bemerkst
Also übertreibe es nicht, und schreibe deine ersten Programme kurz und
knackig. Du bist noch nicht so weit, physisch längere Programme zu
überblicken ohen ständig scrollen und Fenster wechseln zu müssen. Sei
froh, wenns zur Zeit auch noch so geht.
1
#include<avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 1000000UL // Takt CPU wird gesetzt
5
#endif
6
7
#include<util/delay.h>
8
9
intmain(void)
10
{
11
DDRA=0xff;// Port A, alles auf Ausgang
12
DDRA&=~((1<<DDA0)|(1<<DDA1)|(1<<DDA2));// bis auf die Tastereingaenge
13
PORTA=(1<<DDA0)|(1<<DDA1)|(1<<DDA2);// Pullups an den Tastern ein
14
15
while(1){
16
_delay_ms(0.5);// Verzögerung
17
18
if(PINA&(1<<PINA0))
19
PORTA|=(1<<PA4);
20
else
21
PORTA&=~(1<<PA4);
22
}
23
}
Ist 3-mal so kurz und gibt dir für den Anfang genug Stoff zum
experimentieren. Gerade am Anfang ist es wichtig, dass du nicht die
Übersicht verlierst, was du wo programmiert hast. Bei 10 oder 20-Zeilern
ist noch keine Gefahr, dass du durch Nicht-Aufteilen in Funktionen oder
Files die Übersicht verlierst, ganz im Gegenteil: Halte dir die Dinge
beisammen, so dass du möglichst das komplette Programm in einer
Bildschirmseite unterbringen kannst.
Die Schreibweise beim AVRGCC ist einfach grausig aber man kann sich das
Leben erheblich leichter machen wenn man ein paar wenige Macros
verwendet.
Diese Macros wurden hier in anderen Threads vorgestellt und erklärt wenn
du dich näher damit befassen möchtest.
1
intmain(void)
2
{
3
PORTD=0xFF;// Pullups an PortD ON
4
5
myLED_PIN=isOutput;
6
myKey_PIN=isInput;
7
8
for(;;){
9
if(myKey==isPressed){
10
myLED=ON;
11
}else{
12
myLED=OFF;
13
}
14
}
15
}
Das kann man besser lesen oder ?
Im Anhang das passende *.h file. Achtung, habe eine andere PIN Belegung
verwendet.
Hi,
ich habe noch eine andere Lösung der Aufgabe, sie setzt allerdings
voraus, dass an den restlichen PortPins nichts drangeschaltet ist (der
Taster ist hier an PIN0 und die LED an PIN1):
#include <avr/io.h>
#include <util/delay.h>
int main (void) {
DDRB = 0xFE;
PORTB = 0x01;
uint8_t temp = 1;
while(1) {
temp = PINB; //das funktioniert
temp <<= 1;
temp |= 1 << PB0;
PORTB = temp;
}
/* wird nie erreicht */
return 0;
}
MfG
Holger Steiger