Hallo, habe mir neulich ein AVR-Ctrl (mit ATmega32) beschafft, um als Neuling in C ein bisschen experimentieren zu können. Habe mir dann eine kleine Routine geschrieben, mit welcher ich das Prellen der Tasten verhinder (sicher gibt es elegantere und kleinere Lösungen, aber als Neuling war ich mal froh das es zumindest funktionierte). Als es nun ging wollte ich die Routine in eine eigene Header packen, damit ich es leicht in andere Programme einbinden kann. Hier scheitere ich aber. Das AVR-Studio 4.12 wirft mir folgende Fehlermeldungen an den Kopf, die ich einfach nicht wegbekomme: rm -rf debounce.o keys.o debounce.elf dep/* debounce.hex debounce.eep Build succeeded with 0 Warnings... avr-gcc.exe -mmcu=atmega32 -Wall -gdwarf-2 -DF_CPU=16000000UL -O0 -fsigned-char -MD -MP -MT debounce.o -MF dep/debounce.o.d -c ../debounce.c avr-gcc.exe -mmcu=atmega32 -Wall -gdwarf-2 -DF_CPU=16000000UL -O0 -fsigned-char -MD -MP -MT keys.o -MF dep/keys.o.d -c ../keys.c ../keys.c: In function `read_key': ../keys.c:25: warning: comparison between pointer and integer ../keys.c:30: error: invalid lvalue in assignment ../keys.c:31: warning: `return' with a value, in function returning void ../keys.c:42: error: invalid lvalue in assignment ../keys.c:43: warning: `return' with a value, in function returning void ../keys.c:47: error: invalid lvalue in assignment ../keys.c:48: warning: `return' with a value, in function returning void make: *** [keys.o] Error 1 Build failed with 3 errors and 4 warnings... ___________________________________________________________________ Anbei mal mein Hauptprogramm (debounce.c): #include <avr/io.h> #include <avr/delay.h> #include <stdint.h> #include <inttypes.h> #include "keys.h" // Beinhaltet Entprell-Routine /*********************************************************************** **************** * * Das Hauptprogramm * ************************************************************************ ***************/ int main(void) { PORTA = 0x00; // Ausgabe-Zustand von Port A DDRA = 0x00; // Port A als Eingang PORTB = 0x00; // Ausgabe-Zustand von Port B DDRB = 0xFF; // Port B als Ausgang int f; // Variable für einen kleinen Zähler f = 1; // Startwert für den Zähler festlegen while(1) { read_key(KEY2); // Frage KEY2 ab PORTB = f; // Gebe aktuellen Wert von f auf PORTB aus if (key_status == 1) // Wenn KEY2 eine logische 1 liefert: f++; // dann mache f+1 } } _________________________________________________________________ Und hier noch die key.c (Entprell-Routine): #include <stdint.h> #include <avr/io.h> #include <avr/delay.h> #include "keys.h" /*********************************************************************** ** * * Die Entprellroutine * ************************************************************************ */ void read_key(int key) { while( key_status == 1 ) // Verhindern von Wiederholungen { if bit_is_clear( PINA,key ) // Warte bis Taster wieder losgelassen wurde { _delay_ms(50); // Verzögere key_status = 0; // Status auf logisch 0 setzen return (key_status); // Wert übergeben } } if( key_status == 0) // Wenn nich gedrückt { if bit_is_set( PINA,key ) // Warte bis Taster gedrückt ist { _delay_ms(50); // Verzögere if bit_is_set( PINA,key) // Wenn immer noch gedrückt: { key_status = 1; // Status auf logisch 1 setzen return (key_status); // Wert übergeben } else // Wenn nicht mehr gedrückt war { key_status = 0; // Status auf logisch 0 setzen return (key_status); // Wert übergeben } } } } _________________________________________________________________ Und zu letzt die zugehörige Header (key.h): /*********************************************************************** * ***** Beispiel: ***** ***** Um z.B. KEY2 abzufragen, schreibe: read_key(KEY2) ***** ***** Anschließend wird der Taster eingelesen. ***** ***** Wenn key_status anschließend 1 ist, wurde der Taster ***** ***** gedrückt, andernfalls ist key_status 0. ***** ***** ***** ************************************************************************ / #include <inttypes.h> /*********************************************************************** * ***** ***** ***** Definitionen der Taster des AVR-CTRL's ***** ***** ***** ************************************************************************ / #define KEY1 PA7 // Schwarzer Taster (1.) #define KEY2 PA6 // Schwarzer Taster (2.) #define KEY3 PA5 // Blauer Taster (3.) #define KEY4 PA4 // Blauer Taster (4.) #define KEY5 PA3 // Roter Taster (5.) /*********************************************************************** * * Funktion: extern void read_key(int key) * Beschreibung: Einen Taster abfragen ************************************************************************ / extern void read_key(int key); /*********************************************************************** * * Funktion: extern void key_status(int) * Beschreibung: Eingelesenen Status abfragen ************************************************************************ / extern void key_status(int); __________________________________________________________________ Die Kommentare habe ich mal bewusst stehen lassen. Mir ist klar das es nicht die schönste Routine der Welt ist, würde mich aber trotzdem freuen, wenn mir jemand helfen könnte das zum Laufen zu bekommen. Vielen Dank!
Hallo, erstmal die Zeile:
>>keys.c:31: warning: `return' with a value, in function returning
void
GCC schreibt schon ziemlich gut was du falsch machst. Die Funktion
"void read_key(int key)" ist eine void-Funktion, daher sie gibt
keinen Wert zurück (zumindest erwartet gcc das. Du machst aber in 3
Zeilen "return (key_status)". So wie es aussieht ist key_status
nirgends deklariert, daher ist die Variable unbekannt und GCC bemängelt
dies auch. Aber du hast stattdessen eine funktion "extern void
key_status(int)". die kannst du natürlich nicht wie eine Variable
behandeln. Sondern du müsstest schreiben
1 | while(key_status() == 1) |
2 | ....
|
> PORTB = f;
Das könnte auch Probleme geben. f ist als int deklariert (16 Bit),
PORTB hat aber nur 8 Bit. Ich weiß jetzt nicht, ob der Compiler das
vernünftig hinbiegt, aber eine Variable, die einem 8-Bit-Register
zugewiesen wird sollte auch nur mit 8 Bit deklariert werden (also als
(unsigned) char oder uint8_t).
BTW: Die delay-Funktionen aus der delay.h sind begrenzt, was die maximalen Wartezeiten angeht. Du arbeitest anscheinend mit 16 MHz. Dann kann die _delay_ms()-Routine auch nur 16,384 ms maximale Verzögerung (262,14ms/f_CPU[in MHz]). _delay_ms(50) haut jedenfalls nicht hin!
...Und vor allem (und das ist der 'Error'): Du versuchst, der FUNKTION key_status (die unten als extern void key_status(int) deklariert ist) einen Wert zuzuweisen. Das geht sowieso nicht!
Das mit PORTB = f funktioniert, danke trotzdem für den Hinweis. @ MasterFX Tut mir leid aber ich verstehs nicht ganz, liegt wohl daran, dass ich noch nicht sehr viel Erfahrung hab. Habe eben etwas herumprobiert, aber die Zeile while(key_status() == 1) meinst du doch dann für die Abfrage im Hauptprogramm, oder? Wie soll ich denn die Funktion bzw. die Header umbauen, damit die Übergabe klappt? Währ nett wenn du mir nen Beispiel bringen könntest, oder sonst jemand. Danke!
...Und vor allem (und das ist der 'Error'): Du versuchst, der FUNKTION key_status (die unten als extern void key_status(int) deklariert ist) einen Wert zuzuweisen. Das geht sowieso nicht! _____________ Wie muss ich es denn dann machen? Mache sowas zum ersten mal.
Die Funktion erwartet einen int als Parameter. Wenn Du einen Wert von 1 oder 0 an Deine Funktion übergeben willst, dann muss es heißen key_status(1); oder eben key_status(0);. Mehr kann ich dazu nicht sagen, da ich die Funktion key_status nicht kenne. Ach ja: wenn Du erstmalig mit µCs arbeitest, solltest Du versuchen, gleich von Anfang an einen Fehler zu vermeiden, den viele Leute machen, die bisher PCs programmiert haben. Variablen sollten immer nur so groß sein, wie nötig. Ein µC hat nunmal nicht die Speicherressourcen eines PC. Also wenn nur 8 Bit gebraucht werden, auch nur ne 8-Bit-Variable nehmen (ist gegenüber einem int ein gespartes Byte).
Hast Du eigentlich ein C-Buch? Wenn nicht, bitte besorge Dir eins bevor Du weitermachst. In Deinem Programm sind so viele elementare Fehler drin (v.a. was den Umgang mit Funktionen angeht), dass das hier im Forum sicher den Rahmen sprengen würde. Bitte beschäftige Dich eigehender damit! Trotzdem viel Spaß beim basteln!
Ja, irgentwie ist das alles ein bissl seltsam bei dir. Z.B. fragst du im Hauptprogramm den KEY2 ab (read_key(KEY2)). Ist zwar schön und gut, aber du speicherst den Wert ja gar nicht ab. Danach machst du dann "if (key_status == 1)", die variable key_status gibt es aber nicht. Eher sinnvoller wäre sowas wie: [c] int main(void){ char key_status; ... key_status = read_key(KEY2); if(key_status == 1) ... }
Danke, das reichte als Denkansatz. Habs nun hinbekommen, wenigstens etwas :-D
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.