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
prototypen werden eigentlich immer in ein h (header) file geschrieben Also zB. key.c ist dan die Header Datei key.h
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 | }
|
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.