Forum: Compiler & IDEs taster abfrage


von andreas (Gast)


Lesenswert?

guten tag,
ich benutze die
taster-Entprell-Routine von Peter Dannegger die auch super Funktioniert.
Nun hab ich das Problem, ich hab eine eigene selbstgeschrieben Funktion 
in einer externen C-Datei die auch eingebunden ist, wenn ich in dieser 
Funktion
die Taster-Abfrage reinschreibe bekomm ich Folgende Warnings angezeigt:
implicit declaration of funktion 'get_key_short'
implicit declaration of funktion 'get_key_press'
implicit declaration of funktion 'get_key_rpt'

Die Warnung besagt, daß eine Funktion verwendet wird, für welche der
Compiler den Prototyp raten muss.

Bloss wie mach ich den Prototyp für diese Funktion zugänglich.
mfg

von Ben S. (theben)


Lesenswert?

prototypen werden eigentlich immer in ein h (header) file geschrieben
Also zB. key.c ist dan die Header Datei key.h

von andreas (Gast)


Lesenswert?

vielleicht könnte mir jemand von ihnen einen Tip geben
wie ich die warnings beseitigen kann.
mfg


in meiner led.h steht:
extern void ledan(void);

in meiner led.c steht:
void ledan(void)
{
   if ( get_key_short( 1<<key1 )){
    PORTC |=  (1 << PC3);
    }
   if ( get_key_short( 1<<key1 )){
    PORTC &= ~(1 << PC3);
    }
}
1
/************************************************************************/
2
/*                                                                      */
3
/*                      Debouncing 8 Keys                               */
4
/*                      Sampling 4 Times                                */
5
/*                      With Repeat Function                            */
6
/*                                                                      */
7
/*              Author: Peter Dannegger                                 */
8
/*                      danni@specs.de                                  */
9
/*                                                                      */
10
/************************************************************************/
11
 
12
#include <stdint.h>
13
#include <avr/io.h>
14
#include <avr/interrupt.h>
15
16
#include "led.h"
17
18
 
19
#ifndef F_CPU
20
#define F_CPU           1000000                   // processor clock frequency
21
#warning kein F_CPU definiert
22
#endif
23
 
24
#define KEY_DDR         DDRB
25
#define KEY_PORT        PORTB
26
#define KEY_PIN         PINB
27
#define KEY0            0
28
#define KEY1            1
29
#define KEY2            2
30
#define ALL_KEYS        (1<<KEY0 | 1<<KEY1 | 1<<KEY2)
31
 
32
#define REPEAT_MASK     (1<<KEY1 | 1<<KEY2)       // repeat: key1, key2
33
#define REPEAT_START    50                        // after 500ms
34
#define REPEAT_NEXT     20                        // every 200ms
35
 
36
#define LED_DDR         DDRA
37
#define LED_PORT        PORTA
38
#define LED0            0
39
#define LED1            1
40
#define LED2            2
41
 
42
volatile uint8_t key_state;                                // debounced and inverted key state:
43
                                                  // bit = 1: key pressed
44
volatile uint8_t key_press;                                // key press detect
45
 
46
volatile uint8_t key_rpt;                                  // key long press and repeat
47
 
48
 
49
ISR( TIMER0_OVF_vect )                            // every 10ms
50
{
51
  static uint8_t ct0, ct1, rpt;
52
  uint8_t i;
53
 
54
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
55
 
56
  i = key_state ^ ~KEY_PIN;                       // key changed ?
57
  ct0 = ~( ct0 & i );                             // reset or count ct0
58
  ct1 = ct0 ^ (ct1 & i);                          // reset or count ct1
59
  i &= ct0 & ct1;                                 // count until roll over ?
60
  key_state ^= i;                                 // then toggle debounced state
61
  key_press |= key_state & i;                     // 0->1: key press detect
62
 
63
  if( (key_state & REPEAT_MASK) == 0 )            // check repeat function
64
     rpt = REPEAT_START;                          // start delay
65
  if( --rpt == 0 ){
66
    rpt = REPEAT_NEXT;                            // repeat delay
67
    key_rpt |= key_state & REPEAT_MASK;
68
  }
69
}
70
 
71
///////////////////////////////////////////////////////////////////
72
//
73
// check if a key has been pressed. Each pressed key is reported
74
// only once
75
//
76
uint8_t get_key_press( uint8_t key_mask )
77
{
78
  cli();                                          // read and clear atomic !
79
  key_mask &= key_press;                          // read key(s)
80
  key_press ^= key_mask;                          // clear key(s)
81
  sei();
82
  return key_mask;
83
}
84
 
85
///////////////////////////////////////////////////////////////////
86
//
87
// check if a key has been pressed long enough such that the
88
// key repeat functionality kicks in. After a small setup delay
89
// the key is reported being pressed in subsequent calls
90
// to this function. This simulates the user repeatedly
91
// pressing and releasing the key.
92
//
93
uint8_t get_key_rpt( uint8_t key_mask )
94
{
95
  cli();                                          // read and clear atomic !
96
  key_mask &= key_rpt;                            // read key(s)
97
  key_rpt ^= key_mask;                            // clear key(s)
98
  sei();
99
  return key_mask;
100
}
101
 
102
///////////////////////////////////////////////////////////////////
103
//
104
uint8_t get_key_short( uint8_t key_mask )
105
{
106
  cli();                                          // read key state and key press atomic !
107
  return get_key_press( ~key_state & key_mask );
108
}
109
 
110
///////////////////////////////////////////////////////////////////
111
//
112
uint8_t get_key_long( uint8_t key_mask )
113
{
114
  return get_key_press( get_key_rpt( key_mask ));
115
}
116
 
117
int main( void )
118
{
119
      
120
 
121
  // Configure debouncing routines
122
  KEY_DDR &= ~ALL_KEYS;                // configure key port for input
123
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
124
 
125
  TCCR0 = (1<<CS02)|(1<<CS00);         // divide by 1024
126
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
127
  TIMSK |= 1<<TOIE0;                   // enable timer interrupt
128
 
129
  sei();
130
 
131
  while(1){
132
    ledan();
133
    }
134
  }
135
}

von Karl H. (kbuchegg)


Lesenswert?

andreas schrieb:
> vielleicht könnte mir jemand von ihnen einen Tip geben
> wie ich die warnings beseitigen kann.

Du brauchst ein Header File, in dem du die Protoypen der Funktionen 
reinmachst. So wie man das bei allen Funktionen macht, die in einem 
anderen C-File existieren und von wo ganz woanders aufgerufen werden 
sollen.

key.h
*****
1
uint8_t get_key_press( uint8_t key_mask );
2
uint8_t get_key_rpt( uint8_t key_mask );
3
uint8_t get_key_short( uint8_t key_mask );
4
uint8_t get_key_long( uint8_t key_mask );


Und dieses Header File inkludierst du dann in main.c (zur Sicherheit) 
und in allen anderen C-Files, die die Funktionen benutzen möchten.

Hast du doch mit den Funktionen aus led.c auch nicht anders gemacht. Du 
hast dir eine led.h gemacht, in der die entsprechenden 
Funktionsprototypen enthalten sind.

Bei deinem bisherigen Vorgehen war das nicht notwendig, weil die 
Funktionen in main.c enthalten waren und vor der ersten Verwendung 
definiert wurden. In dem Fall gilt dann die Funktionsdefinition als ihr 
eigener Prototyp und daher brauchte man für einen Aufruf in main.c keine 
expliziten Protoypen. Aber jetzt sollen sie von woanders aufgerufen 
werden und daher sind dann Protoypen dafür notwendig. So gesehen sind 
die Funktionen in main.c um nichts anders als jede andere Funktion in 
irgendeinem sonstigen File, welches zum Projekt gehört, auch.

von Karl H. (kbuchegg)


Lesenswert?

PS:

Das hier
1
void ledan(void)
2
{
3
   if ( get_key_short( 1<<key1 )){
4
    PORTC |=  (1 << PC3);
5
    }
6
   if ( get_key_short( 1<<key1 )){
7
    PORTC &= ~(1 << PC3);
8
    }
9
}
wird so nicht funktionieren. So schnell und so exakt bist du als Mensch 
nicht, dass du exakt einen Tastendruck zwischen die beiden (identischen) 
Abfragen platzieren kannst.

Wenn du mit einem Tastendruck eine LED umschalten willst, dann musst du 
das etwas anders angehen.
Wundert mich jetzt aber, denn genau das gleiche Problem hast du ja auch, 
wenn alles, also auch die LED Funktion, in der main.c enthalten wäre.

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
Noch kein Account? Hier anmelden.