mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Neuling mit AVR-Ctrl - Tasten entprellen


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: MasterFX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
while(key_status() == 1)
....

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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).

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...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!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: MasterFX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)
     ...
}

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, das reichte als Denkansatz. Habs nun hinbekommen, wenigstens
etwas :-D

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.