Hallo,
bin gerade dabei ein Programm für eine einfache Tasterentprellung zu
schreiben. Leider bekomme ich beim Compilieren bisher immer noch einen
Übersetzungsfehler. Hier ist mein bisheriges Programm:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include"lcd-routines.h"
4
5
charbuffer[20];
6
7
8
voiddelay_ms(uint16_tms)
9
{
10
while(ms>0)
11
{
12
_delay_ms(1);
13
ms--;
14
}
15
}
16
17
18
boolentprellung(uint8_tport)
19
{
20
21
22
if(!(PIND&(1<<port)))//wenn Taster gedrückt, also PD0 auf low
23
{
24
delay_ms(10);//10ms warten, danach abfragen ob Pin PD0 immer noch auf low ist
25
26
if(!(PIND&(1<<port)))
27
{lcd_setcursor(0,1);
28
lcd_string("buffer");
29
return1;
30
31
}
32
return0;
33
}
34
}
35
36
37
38
intmain(void)
39
{
40
41
DDRD=0x00;//alle Ports als Eingang
42
DDRB=0xFF;//alle Ports als Ausgang
43
PORTB=0xFF;//alle LEDs aus
44
45
lcd_init();
46
lcd_setcursor(0,1);
47
lcd_string("Hallo");
48
49
50
51
52
while(1)
53
{
54
if(entprellung(PD0))
55
{
56
PORTB&=~(1<<PB7);//LED7 an, wenn taster an PD0 gedrückt
57
}
58
59
60
61
}
62
63
64
65
}
Der Fehler muss auf jeden Fall an meiner Funktion entprellung liegen.
Ich möchte, dass diese bei gedrücktem Taster ein True und bei nicht
gedrückem ein False zurückgibt und somit bestimmt ob die LED7 an PD0
eingeschaltet wird.
Wer kann mir sagen, was ich codetechnisch ändern muss, damit das
Programm fehlerfrei übersetzt wird?
Gruß
hier ist die Fehlermeldung:
../Tasterentprellung.c:18: error: expected '=', ',', ';', 'asm' or
'__attribute__' before 'entprellung'
Leider wird mir die Stelle im Programm beim anklicken der Fehlermeldung
grad nicht angezeigt. Weiß auch nicht warum das des AVR Studio da nicht
macht. Normal geht des nämlich schon.
Frank schrieb:> Der Fehler muss auf jeden Fall an meiner Funktion entprellung liegen.
Nein. Deine Fehlermeldung sagt dir doch, wo der Fehler liegt:
> ../Tasterentprellung.c:18: error: expected '=', ',', ';', 'asm' or> '__attribute__' before 'entprellung'>>before 'entprellung'
Da fehlt VORHER was.
#include <avr/io.h>
#include <util/delay.h>
#include "lcd-routines.h"
die io.h und die delay.h gehören zur libc, die lcd-routines.h und die
vermutliche lcd-routines.c sind von dir.
Wahrscheinlich fehlt irgendwo ein Semikolon.
Entscheide selber, wo du anfängst zu suchen.
mfg.
Booool schrieb:> C - kein bool Datentyp ( standardmäßig )> C++ - hat bool
Was gibt es dann für ne alternative Möglichkeit das Ganze in C zu
programmieren?
Frank schrieb:> Booool schrieb:>> C - kein bool Datentyp ( standardmäßig )>> C++ - hat bool>> Was gibt es dann für ne alternative Möglichkeit das Ganze in C zu> programmieren?
Keine Ahnung, was der will. Wahrscheinlich hat er letzte Nacht zuviel
getrunken.
mfg.
Thomas Eckmann schrieb:> die io.h und die delay.h gehören zur libc, die lcd-routines.h und die> vermutliche lcd-routines.c sind von dir.> Wahrscheinlich fehlt irgendwo ein Semikolon.> Entscheide selber, wo du anfängst zu suchen
Also einen Fehler in den LCD-Unterprogrammen kann ich ausschließen. Die
wurden in der Vergangenheit schon ausgiebig getestet und verwendet.
Falls also wirklich ein Semikolon fehlen sollte, kann es nur im
dargestellten Code sein.
Gruß
Frank schrieb:> Also einen Fehler in den LCD-Unterprogrammen kann ich ausschließen.
Das sagen alle. Aber dann würde es auch laufen.
Frank schrieb:> Falls also wirklich ein Semikolon fehlen sollte, kann es nur im> dargestellten Code sein.
Da ist kein Fehler drin.
Peter II schrieb:> jeder schlaue compiler wird sie einfach ignorieren
Warum sollte er das tun?
mfg.
>> Frank:> Was gibt es dann für ne alternative Möglichkeit das Ganze in C zu> programmieren?
Einen in C bekannten Datentyp nehmen.
Also statt
bool entprellung(uint8_t port)
z.B.
#include <stdint.h> // für uint8_t
...
uint8_t entprellung(uint8_t port)
>> Peter II:> deine funktion delay_ms ist auch sehr ungünstig. jeder schlaue compiler> wird sie einfach ignorieren.
IMHO stimmt das nicht. delay_ms hat als Seiteneffekt einen Aufruf
Funktion _delay_ms, die ihrerseite volatile gekennzeichnete Anweisungen
enthält. Der Aufruf von delay_ms darf nicht "wegoptimiert" werden.
Peter II schrieb:> deine funktion delay_ms ist auch sehr ungünstig. jeder schlaue compiler> wird sie einfach ignorieren.
Ich habs gerade mit meinem LCD getestet. Die Funktion delay_ms() wird
ausgeführt.
Jetzt hab ich das Programm leicht abgeändert und jetzt funktioniert es
wie gewünscht:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include"lcd-routines.h"
4
5
charbuffer[20];
6
7
8
voiddelay_ms(uint16_tms)
9
{
10
while(ms>0)
11
{lcd_setcursor(0,1);
12
lcd_string("Zeitverzoegerung");
13
_delay_ms(1);
14
ms--;
15
}
16
}
17
18
19
inlineuint8_tentprellung(uint8_tport)
20
{
21
22
23
if(!(PIND&(1<<port)))//wenn Taster gedrückt, also PD0 auf low
24
{
25
delay_ms(10);//10ms warten, danach abfragen ob Pin PD0 immer noch auf low ist
26
27
if(!(PIND&(1<<port)))
28
{
29
return1;
30
31
}
32
return0;
33
}
34
}
35
36
37
38
intmain(void)
39
{
40
41
DDRD=0x00;//alle Ports als Eingang
42
DDRB=0xFF;//alle Ports als Ausgang
43
PORTB=0xFF;//alle Pins auf high => alle LEDs aus
44
45
lcd_init();
46
lcd_setcursor(0,1);
47
lcd_string("Hallo");
48
49
50
51
52
while(1)
53
{
54
if(entprellung(PD0))
55
{
56
PORTB&=~(1<<PB7);//LED7 an, wenn taster an PD0 gedrückt
57
}
58
59
60
61
}
62
63
64
65
}
das "inline uint8_t" vor der Funktion entprellung hab ich aus einem
Beispielprogramm von dieser Seite "geklaut":
http://www.mikrocontroller.net/articles/Entprellung
Jetzt lässt sich das Programm fehlerfrei übersetzen und funktioniert
auch so wie ich will.
Jetzt ist nur mein Problem, dass ich die Bedeutung von dem "inline
uint8_t" in Verbindung mit der Funktion entprellung nicht verstehe bzw
kenne. Es muss sich wohl auf den Rückgabewert der Funktion beziehen
Kann mir vielleicht jemand die Bedeutung in diesem Zusammenhang
erklären?
Gruß
Krapao schrieb:> z.B.> #include <stdint.h> // für uint8_t> ...> uint8_t entprellung(uint8_t port)
Hab ich jetzt im Nachhinein auch ausprobiert. Lässt sich zwar fehlerfrei
compilieren. Das Programm funktioniert aber dann nicht mehr wie
gewünscht, da die LED dann dauerhaft leuchtet, auch dann schon wenn ich
den Taster noch gar nicht gedrückt habe.
Gruß
Krapao schrieb:> bool entprellung(uint8_t port)
Hast recht. Das ist der Fehler.
Nehme alles zurück.
Booool (Gast) ist nicht betrunken.
#include <stdbool.h> und dann geht's.
mfg.
Frank schrieb:> Das Programm funktioniert aber dann nicht mehr wie gewünscht,
Deine Funktion ist unvollständig.
Sie handelt nur den Fall ab, wenn die Taste gedrückt wurde. Was macht
sie, wenn die Taste nicht gedrückt wurde?
bool entprellung(uint8_t port)
{
if(!(PIND & (1<<port))) {
delay_ms(10);
if(!(PIND & (1<<port)))
{ lcd_setcursor(0,1);
lcd_string("buffer");
return 1;
}
return 0;
}
return 0; //Damit sollte es gehen.
}
Thomas Eckmann schrieb:> Deine Funktion ist unvollständig.> Sie handelt nur den Fall ab, wenn die Taste gedrückt wurde. Was macht> sie, wenn die Taste nicht gedrückt wurde?>> bool entprellung(uint8_t port)> {> if(!(PIND & (1<<port))) {> delay_ms(10);>> if(!(PIND & (1<<port)))> { lcd_setcursor(0,1);> lcd_string("buffer");> return 1;>> }> return 0;> }> return 0; //Damit sollte es gehen.> }
Stimmt. Jetzt hab ich das Programm mal folgendermaßen abgeändert und
jetzt funktioniert alles wie gewünscht:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include"lcd-routines.h"
4
#include<stdbool.h>
5
6
charbuffer[20];
7
8
9
voiddelay_ms(uint16_tms)
10
{
11
while(ms>0)
12
{lcd_setcursor(0,1);
13
lcd_string("Zeitverzoegerung");
14
_delay_ms(1);
15
ms--;
16
}
17
}
18
19
20
boolentprellung(uint8_tport)
21
{
22
23
24
if(!(PIND&(1<<port)))//wenn Taster gedrückt, also PD0 auf low
25
{
26
delay_ms(10);//10ms warten, danach abfragen ob Pin PD0 immer noch auf low ist
27
28
if(!(PIND&(1<<port)))
29
{
30
return1;
31
32
}
33
return0;
34
}
35
return0;
36
}
37
38
39
40
intmain(void)
41
{
42
43
DDRD=0x00;//alle Ports als Eingang
44
DDRB=0xFF;//alle Ports als Ausgang
45
PORTB=0xFF;//alle Pins auf high => alle LEDs aus
46
47
lcd_init();
48
lcd_setcursor(0,1);
49
lcd_string("Hallo");
50
51
52
53
54
while(1)
55
{
56
if(entprellung(PD0))
57
{
58
PORTB&=~(1<<PB7);//LED7 an, wenn taster an PD0 gedrückt
59
}
60
61
62
63
}
64
65
66
67
}
Interessanterweise funktioniert das Programm nicht richtig, wenn ich das
zweite return 0 in der Funktion entprellung weglasse. Dann leuchtet
nämlich die LED auch dann schon, wenn ich noch gar nicht den Taster
gedrückt habe.
Ich kann mir dieses Phänomen nur so erklären, dass die Funktion
entprellung dann auch bei nicht gedrücktem Taster ein True-Ergebnis
zurückmeldet. Kann diese Einschätzung jemand bestätigen?
Gruß
Frank schrieb:> Interessanterweise funktioniert das Programm nicht richtig, wenn ich das> zweite return 0 in der Funktion entprellung weglasse.
Weil dann der Rückgabewert bei nicht gedrückter Taste undefiniert ist.
Schaltest du mit -Wall die Ausgabe von Compiler-Warnungen ein, wird dir
dies mit der Meldung
1
warning: control reaches end of non-void function
mitgeteilt.
Übrigens hätte bei deinem ursprünglichen Problem ein etwas aktuellerer
GCC (4.6+) folgende Fehlermeldung ausgegeben, wodurch sich deine erste
Frage wahrscheinlich erübrigt hätte:
1
../Tasterentprellung.c:18:1: error: unknown type name 'bool'
Noch etwas: Wenn eine Funktion vom Typ bool ist, sollte sie konsequen-
terweise nicht 0 oder 1, sondern false oder true zurückgeben. Diese
Konstanten sind ebenfalls in stdbool.h definiert.
Das Programm ist leider kompletter Muell.
1) eine Delay funktion ist der Beginn allem Uebels.
Denn sie wartet nicht nur, sondern macht das
Programm auch total unuebersichtlich. Das ist
die sogenannte Procedurale Programmierung.
Irgendwann weiss man nicht mehr genau wo das
Programm denn steht. Und dann wird es schwierig.
2) Man sollte sich angewoehnen in main genau an
einer Stelle zu warten, und den Rest mit einer
Zustandsmaschine zu machen. Das oben beschriebene
Problem ist hier viel einfacher, denn man weiss
wo im code Das Programm wartet, man weiss nur
den State nicht, un den kann man dann einfach
mitteilen.
3) arbeite mit einem Timer, der einen Tick vorgibt.
zB 10ms, oder aehnlich. Der Timer setzt ein Flag,
und auf das reagiert man dann im Main.