Hallo Leute!!
Habe folgendes Problem: möchte mit einem Taster ein lauflicht starten
und dann wieder unterbrechen bzw. die drei leds die als Lauflicht (beim
ersten betätigen des Tasters)an sind mit dem zweite betätigen des
Tasters ausmachen. Bist zum an machen des Lauflichtes mit LED
funktioniert mein code, jedoch das ausmachen nicht. Wo ist der fehler ?
Bzw. wie sag ich dem Controller das der taster zum zweiten mal gedrückt
wurde?
#include <mega8.h>
#include <delay.h>
#include <stdint.h>
void main (void)
{
uint8_t pPortB,test;
pPortB = PINB.0;
pPortB+=2;
test=pPortB;
DDRD = 0xFF; // PORTD als Ausgang
PORTD = 0xFF; //PORTD auf high (5V)
DDRB = 0x00; // PORTB als Eingang
PORTB = 0x01; // Pull up Widerstand aktiv an PORTB.0
while (1)
{
if (PINB.0 == 0)
{
while (1){
PORTD.0=0;
delay_ms (10);
PORTD.0=1;
delay_ms (50);
PORTD.1=0;
delay_ms (10);
PORTD.1=1;
delay_ms (50);
PORTD.2=0;
delay_ms (10);
PORTD.2=1;
delay_ms (50);
}
}
else
{
PORTD.0 = 1; //LED1 aus
PORTD.1 = 1; //LED2 aus
PORTD.2 = 1; //LED3 aus
}
if (test == 2);
{
PORTD.0 = 1; //LED1
PORTD.1 = 1; //LED2 aus
PORTD.2 = 1; //LED3 aus
break;
}
}
}
Du musst anfangen mal einen vernünftigen Programmierstil zu entwickeln!
Dazu gehören vernünftige und konsistente Einrückungen. Auch das
Einfügen von exzessiven Leerzeilen-Blöcken trägt nicht wirklich
zur Übersicht bei. Im Gegenteil, dadurch daß der Code nur unnötig
in die Länge gezogen wird, leidet die Übersicht.
Dein Code mal etwas umformatiert
1
#include<mega8.h>
2
#include<delay.h>
3
#include<stdint.h>
4
5
voidmain(void)
6
{
7
uint8_tpPortB,test;
8
9
pPortB=PINB.0;
10
pPortB+=2;
11
12
test=pPortB;
13
14
DDRD=0xFF;// PORTD als Ausgang
15
PORTD=0xFF;//PORTD auf high (5V)
16
DDRB=0x00;// PORTB als Eingang
17
PORTB=0x01;// Pull up Widerstand aktiv an PORTB.0
18
19
while(1)
20
{
21
if(PINB.0==0)
22
{
23
while(1)
24
{
25
PORTD.0=0;
26
delay_ms(10);
27
PORTD.0=1;
28
delay_ms(50);
29
PORTD.1=0;
30
delay_ms(10);
31
PORTD.1=1;
32
delay_ms(50);
33
PORTD.2=0;
34
delay_ms(10);
35
PORTD.2=1;
36
delay_ms(50);
37
}
38
}
39
else
40
{
41
PORTD.0=1;//LED1 aus
42
PORTD.1=1;//LED2 aus
43
PORTD.2=1;//LED3 aus
44
}
45
46
if(test==2)
47
;
48
{
49
PORTD.0=1;//LED1
50
PORTD.1=1;//LED2 aus
51
PORTD.2=1;//LED3 aus
52
break;
53
}
54
}
55
}
Und jetzt gehst du mal zu deinem Lauflichtcode und siehst dir
die umgebende Kontrollstruktur darin an. Wenn du das tust, dann
findest du, dass dieser LED-Blink Code in einer while(1) Schleife
eingebettet ist, also einer Endlosschleife. Sobald die Programm-
ausführung da drin angelangt ist, kommt sie nie wieder raus.
PS: Der Strichpunkt beim Test von test auf 2 war wahrscheinlich
so nicht gewollt. Trotzdem ist er drinnen und sorgt so dafür,
daß der nachfolgende Programmblock nicht unter Kontrolle des
if steht.
hmm leider hab ich immer noch keine ahnung wie ich dem controller
mitteilen soll das der taster zum zweiten mal gedrpckt wurde hat einer
ein beispiel code oder ne idee?
Vitalij K. wrote:
> hmm leider hab ich immer noch keine ahnung wie ich dem controller> mitteilen soll das der taster zum zweiten mal gedrpckt wurde hat einer> ein beispiel code oder ne idee?
Das Problem ist das Erkennen eines Tastendrucks. Das ist zunächst
mal ziemlich schwierig, weil dir da die Hardware unter Umständen
einen Strich durch die Rechnung macht: Taster prellen. D.h. was
du als einmaligen Tastendruck empfindest, sieht für den µC so
aus als ob der Taster in kurzer Zeit ein paar mal gedrückt und
wieder losgelassen wird. Und Entprellen eines Tasters ist,
wenn man es gut machen will, gar nicht so einfach.
Aber seis drum.
Einen Tastendruck erkennt man daran, dass man einen Flankenwechsel
erkennen muss. D.h. Der Taster wechselt den Eingansgpegel von
1 auf 0. Und es ist nur diese Änderung die dich interessiert,
nicht das der Pegel jetzt dauernd auf 0 ist. Du musst also in
einer Variablen den Zustand des Einganspins speichern um im
nächsten Schleifendurchlauf erkennen zu können, ob sich der
Pegel verändert hat.
Probier mal das hier aus
1
#include<mega8.h>
2
#include<delay.h>
3
#include<stdint.h>
4
5
intmain(void)
6
{
7
uint8_tTasterJetzt,TasterVorher;
8
uint8_tCount;
9
10
DDRD=0xFF;// PORTD als Ausgang
11
PORTD=0xFF;// PORTD auf high (5V)
12
DDRB=0x00;// PORTB als Eingang
13
PORTB=0x01;// Pull up Widerstand aktiv an PORTB.0
14
15
TasterVorher=1;
16
Count=0;
17
18
while(1)
19
{
20
TasterJetzt=PINB.0;// den jetzigen Zustand des Tasters feststellen
21
22
if(TasterJetzt!=TasterVorher)// gibt es einen Unterschied?
23
{
24
// Der Unterschied kann jetzt beides bedeuten:
25
// Taster wurde gedrückt oder
26
// Taster wurde losgelassen
27
// Wir sind nur am Fall 'Taster gedrückt' interessiert
28
// Wenn der Taster aber gedrückt wurde, dann muss TasterJetzt
29
// aber den Wert 0 haben
30
31
if(TasterJetzt==0)
32
{
33
// mitzählen wie oft die Taste gedrückt wurde
34
Count++;
35
36
// Der wievielte Tastendruck war das jetzt?
37
// Der erste? -> Led einschalten
38
// Der zweite? -> Led ausschalten und die Tasterzählung
39
// wieder von vorne beginnen
40
if(Count==1)
41
PORTD.0=0;
42
43
if(Count==2)
44
{
45
PORTD.0=1;
46
Count=0;
47
}
48
}
49
}
50
51
// den jetzigen Zustand des Tasters als den vorhergehenden
52
// merken, damit beim nächsten Abfragen des Tasters damit
53
// verglichen werden kann und ein Wechsel detektiert werden kann
54
TasterVorher=TasterJetzt;
55
56
// etwas warten um das Tastenprellproblem etwas zu entschärfen
Gut.
bedenke immer, ich muss blind programmieren, da ich nicht deinen
Compiler habe.
Zu deinem Lauflicht:
Du musst von der Vorstellung weg, dass du einen Codeblock
hast, in dem ständig eine LED nach der anderen ein/aus
geschaltet wird.
Stattdessen musst du das in der Hauptschleife machen.
Dazu benutzt du eine weitere Variable, die dir anzeigt
welche LED als nächstes einzuschalten ist. Diese Variable
wird dann laufend erhöht.
Ungefähr so
1
....
2
3
intmain(void)
4
{
5
....
6
uint8_tNextLed;
7
....
8
9
NextLed=0;
10
11
while(1)
12
{
13
....
14
15
// alle LED mal aus
16
PORTD.0=1;
17
PORTD.1=1;
18
PORTD.2=1;
19
20
// welche LED ist als nächstes drann mit einschalten
21
if(NextLed==0)
22
PORTD.0=0;
23
24
elseif(NextLed==1)
25
PORTD.1=0;
26
27
elseif(NextLed==2)
28
PORTD.2=0;
29
30
// und merken, dass im nächsten Schleifendurchlauf die
31
// nächste Led drannkommt. Aber aufpassen: Nach der
32
// letzten LED muss wieder die erste drann kommen
33
NextLed++;
34
if(NextLed==3)
35
NextLed=0;
36
37
// etwas warten
38
delay_ms(10);
39
}
40
}
Und jetzt liegt es an dir, die beiden Teile: Tastendrücke
und Lauflicht, miteinander zu verbinden. Ich würde dazu eine
weitere Variable benutzen, die mir anzeigt, ob das Lauflicht
ein oder ausgeschaltet ist. Der Tastencode setzt diese Variable
entsprechend und der Lauflichtcode wird vom Inhalt dieser
Variablen abhängig gemacht.
Habe entlich wieder Zeit gefunden meine C-Kenntnisse zu erweitern und an
dem Lauflicht zu programmieren. Leider nicht vom Erfolg gekrönt was mach
ich falsch hier der code:
#include <mega8.h>
#include <delay.h>
#include <stdint.h>
void main (void)
{
uint8_t TasterJetzt, TasterVorher;
uint8_t ZaehlerTaster;
uint8_t ZaehlerLED;
uint8_t LED1,LED2,LED3;
DDRD = 0xFF; // PORTD als Ausgang
PORTD = 0xFF; //PORTD auf high (5V)
DDRB = 0x00; // PORTB als Eingang
PORTB = 0x01; // Pull up Widerstand aktiv an PORTB.0
TasterVorher = 1;
ZaehlerTaster = 0;
ZaehlerLED = 0;
LED1 = PORTD.0;
LED2 = PORTD.1;
LED3 = PORTD.2;
while (1)
{
LED1 = 1; // LED1 (grün) aus
LED2 = 1; // LED2 (gelb) aus
LED3 = 1; // LED3 (rot) aus
TasterJetzt = PINB.0; // den jetzigen Zustand des Tasters
feststellen
if( TasterJetzt != TasterVorher ) // gibt es einen Unterschied?
{
// Der Unterschied kann jetzt beides bedeuten:
// Taster wurde gedrückt oder
// Taster wurde losgelassen
// Wir sind nur am Fall 'Taster gedrückt' interessiert
// Wenn der Taster aber gedrückt wurde, dann muss TasterJetzt
// aber den Wert 0 haben
if( TasterJetzt == 0 )
{
// mitzählen wie oft die Taste gedrückt wurde
ZaehlerTaster++;
// Der wievielte Tastendruck war das jetzt?
// Der erste? -> Led einschalten
// Der zweite? -> Led ausschalten und die Tasterzählung
// wieder von vorne beginnen
if( ZaehlerTaster == 1 )
if( ZaehlerLED == 0)
{
LED1 = 0;
delay_ms (100);
LED1 = 1;
}
if( ZaehlerLED == 1)
{
LED2 = 0;
delay_ms (100);
LED2=1;
}
if( ZaehlerLED == 2)
{
LED3 = 0;
delay_ms(100);
LED3 = 1;
ZaehlerLED++;
if( ZaehlerLED == 3)
{
ZaehlerLED = 0;
}
}
if( ZaehlerTaster == 2 )
{
PORTD.0 = 1;
PORTD.1 = 1;
PORTD.2 = 1;
ZaehlerTaster = 0;
}
}
}
// den jetzigen Zustand des Tasters als den vorhergehenden
// merken, damit beim nächsten Abfragen des Tasters damit
// verglichen werden kann und ein Wechsel detektiert werden kann
TasterVorher = TasterJetzt;
// etwas warten um das Tastenprellproblem etwas zu entschärfen
delay_ms (10);
}
}
ABgesehen von so manch anderem Problem,
seit wann wird eine LED eingeschaltet, indem man einer
unbeteiligten Variablen etwas zuweist
1
voidmain(void)
2
{
3
...
4
uint8_tLED1,LED2,LED3;
5
6
....
7
8
LED1=PORTD.0;
9
LED2=PORTD.1;
10
LED3=PORTD.2;
11
12
while(1)
13
{
14
LED1=1;// LED1 (grün) aus
15
LED2=1;// LED2 (gelb) aus
16
LED3=1;// LED3 (rot) aus
17
....
Nach der Zuweisung
LED1 = PORTD.0;
ist LED1 nicht gleichbedeutend mit PORTD.0
LED1 bekommt den Wert von PORTD.0, aber LED1 und PORTD.0
sind auch danach 2 völlig voneinander verschiedene Dinge!
Wenn du eine LED ein oder ausschalten willst, dann musst du
schon etwas an PORTD.0 zuweisen!
davon ausgehend das der undleserliche code am anfang frei von
syntaxfehlern ist versuch folgendes (ist absolut unsauber
programmiert!!!)
#include <mega8.h>
#include <delay.h>
#include <stdint.h>
void main (void)
{
uint8_t pPortB,test, hilfsvariable;
pPortB = PINB.0;
pPortB+=2;
test=pPortB;
DDRD = 0xFF; // PORTD als Ausgang
PORTD = 0xFF; //PORTD auf high (5V)
DDRB = 0x00; // PORTB als Eingang
PORTB = 0x01; // Pull up Widerstand aktiv an PORTB.0
hilfsvariable = 1;
while (1)
{
if (PINB.0 == 0)
hilfsvariable = 1;
{
while (hilfsvariable == 1){
PORTD.0=0;
delay_ms (10);
PORTD.0=1;
delay_ms (50);
PORTD.1=0;
delay_ms (10);
PORTD.1=1;
delay_ms (50);
PORTD.2=0;
delay_ms (10);
PORTD.2=1;
delay_ms (50);
if (PINB.0 == 1)
(
hilfsvariable = 0;
)
}
}
else
{
PORTD.0 = 1; //LED1 aus
PORTD.1 = 1; //LED2 aus
PORTD.2 = 1; //LED3 aus
}
if (test == 2);
{
PORTD.0 = 1; //LED1
PORTD.1 = 1; //LED2 aus
PORTD.2 = 1; //LED3 aus
break;
}
}
}
wird funktionieren, aber wie gesagt, pfuschig programmiert (war zu faul
dir das sauber zu machen...
versuchs, und als nächerster schritt würde ich empfehlen dies mit einer
schrittkette zu lösen (switch, case)
Hallo Karl heinz,
vielleichts kannst du mir auch helfen!
bin Afänger und soll zu sagen habe einiege Kapitel von Tutorial
"bestanden".
mein Problem:
mein Testboard hat 2 Taster die ich beliebig benutzen kann, wenn ich die
Taster benutzen will Aktiviere ich die "Pull ups" und und funktioniert
ganz gut.
Nun habe ich ein "Externe Taster Modul" (??) wie im Anhang gelötet also
mit 10K als vorwiderstand oder als Pull up es bedeutet jetzt brauche ich
die interne Pull up von controller NICHT mehr oder????
Frage 1:
Wenn ich im Code "kein Pull up" aktiviere funktioniert mein Modul nicht,
aktiviere ich die Pull up dann funktioniert! warum?
Frage 2: brauche ich überhaupt die "externe" widerstand, ist sowas
Sinnvoll?
vielen Dank für die Hilfe
Gruß
Martin