PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Taster entprellen?



Ferdinand
31.07.2011, 17:01
Hi
Ich versuche eine Funktion zu bauen mit der ich bauen entprellt an PORT's Abfragen kann, nun leider funktioniert mein Programm nicht und ich weis nicht warum?

Kann mir einer Tipps, geben wie ich mein Funktion testen könnte oder wo das Problem ist?

Mein Setup ist AVR Studio 4, STK500 mit Atmega644 8MHz.




/*
Funktion zum Tasten entprellen
taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))

Ich lese den PIND, PD0 ein und gebe ihn entprellt wider am PORTB aus.
Test Bort ist das STK500 mit Atmega644 8MHz.
PORTB ist auf LED's, und PORTD ist auf Taster geschaltet.

*/
#include <avr/io.h>
#include <stdint.h>
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 Hz definiert"
#define F_CPU 8000000UL /* Quarz mit 8000000 Hz */
#endif
#include <util/delay.h> /* bei alter avr-libc: #include <avr/delay.h> */

//Funktions Prototypen

uint8_t taster(uint8_t pinx, uint8_t px);


int main (void)
{

DDRB = 0xff; //PORTB Ausgang



while(1) //Hauptschleife
{

if(taster(PIND, PD0)) //Taster0 Abfragen
{


PORTB = PD0; //LED0 Einschalten
}

} //Hauptschleife Ende
return 0;

} //Main Ende


//Funktion, taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))
uint8_t taster(uint8_t pinx, uint8_t px)
{

if( pinx == (1 << px))
{
_delay_ms(10);
}

else
{
return 0;
}

if( pinx == (1 << px))
{
return pinx;
}

else
{
return 0;
}

}




Danke
by Ferdinand.

PicNick
31.07.2011, 17:34
statt:
if( pinx == (1 << px))
versuch mal
if( pinx & (1 << px))

Ferdinand
31.07.2011, 18:36
Das tut auch nicht, zudem jetzt noch Ale LED's an sind.
Ich vermute mal das liegt an DDRB = 0xff; das Ale LED's an sind.

Neuer Code


/*
Funktion zum Tasten entprellen
taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))

Ich lese den PIND, PD0 ein und gebe ihn entprellt wider am PORTB aus.
Test Bort ist das STK500 mit Atmega644 8MHz.
PORTB ist auf LED's, und PORTD ist auf Taster geschaltet.

*/
#include <avr/io.h>
#include <stdint.h>
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 Hz definiert"
#define F_CPU 8000000UL /* Quarz mit 8000000 Hz */
#endif
#include <util/delay.h> /* bei alter avr-libc: #include <avr/delay.h> */

//Funktions Prototypen

uint8_t taster(uint8_t pinx, uint8_t px);


int main (void)
{

DDRB = 0xff; //PORTB Ausgang



while(1) //Hauptschleife
{

if(taster(PIND, PD0)) //Taster0 Abfragen
{


PORTB = PD0; //LED0 Einschalten
}

} //Hauptschleife Ende
return 0;

} //Main Ende


//Funktion, taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))
uint8_t taster(uint8_t pinx, uint8_t px)
{

if( pinx & (1 << px))
{
_delay_ms(10);
}

else
{
return 0;
}

if( pinx & (1 << px))
{
return pinx;
}

else
{
return 0;
}

}


Danke
by Ferdinand.

Ferdinand
31.07.2011, 22:37
Ich habe hier (http://www.mikrocontroller.net/topic/98195) etwas gefunden.

Nun möchte ich diesen Code ausprobieren "Debounce-Makro von Peter Dannegger (http://www.mikrocontroller.net/articles/Entprellung#Debounce-Makro_von_Peter_Dannegger)" und habe ihn für diesen zwecke so abgeändert.


/*
Testapplication
*/
int main(void)
{
DDRD &= ~(1<<PD0);
PORTD |= 1<<PD0;

for(;;){
if( debounce( PIND, PD0 ) )
PORTB ^= 1<<PD0;

}
}


Ich möcht mit Taste 0 eine LED ein und aus schalten, aber es geht nicht, nun ich blick langsam auch nicht mehr durch hätte nicht gedacht das, das so schwer wird.

Danke
by Ferdinand

oberallgeier
31.07.2011, 23:25
... diesen Code ausprobieren "Debounce-Makro von Peter Dannegger (http://www.mikrocontroller.net/articles/Entprellung#Debounce-Makro_von_Peter_Dannegger)" ... aber es geht nicht ...
... Makro arbeitet in der Originalversion mit active low geschalteten Tastern ...Wie sind Deine Taster geschaltet?

Ferdinand
31.07.2011, 23:33
Da ich das STK500 verwende und ich mein das ich das schon mal Gelessen habe sind die, wen ich sie drücke auch auf GND gezogen.
Aber du hast rech es könnte daran Ligen ich werde gleich mal nachlesen.

Danke
by Ferdinand

Ferdinand
31.07.2011, 23:46
Also bei dem STK500 (http://www.atmel.com/dyn/resources/prod_documents/doc1925.pdf) sind die Taster auf GND gezogen wen ich sie drücke, habe auch nachgemessen (ging schneller als lesen :cool:)

Danke
by Ferdinand.

Ferdinand
01.08.2011, 01:31
Hey

Ich hab da noch was gefunden, http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29

Ich musste es allerdings ab Ändern weil ich ja den Atmega644 (http://www.atmel.com/dyn/resources/prod_documents/doc1925.pdf) mit 8MHz verwende, hier mein Code.



/************************************************** **********************/
/* */
/* Debouncing 8 Keys */
/* Sampling 4 Times */
/* With Repeat Function */
/* */
/* Author: Peter Dannegger */
/* danni@specs.de */
/* */
/************************************************** **********************/

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#ifndef F_CPU
#define F_CPU 8000000UL // processor clock frequency
#warning kein F_CPU definiert
#endif

#define KEY_DDR DDRD
#define KEY_PORT PORTD
#define KEY_PIN PIND
#define KEY0 0
#define KEY1 1
#define KEY2 2
#define ALL_KEYS (1<<KEY0 | 1<<KEY1 | 1<<KEY2)

#define REPEAT_MASK (1<<KEY1 | 1<<KEY2) // repeat: key1, key2
#define REPEAT_START 50 // after 500ms
#define REPEAT_NEXT 20 // every 200ms

#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED0 0
#define LED1 1
#define LED2 2

volatile uint8_t key_state; // debounced and inverted key state:
// bit = 1: key pressed
volatile uint8_t key_press; // key press detect

volatile uint8_t key_rpt; // key long press and repeat


ISR( TIMER0_OVF_vect ) // every 10ms
{
static uint8_t ct0, ct1, rpt;
uint8_t i;

TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms

i = key_state ^ ~KEY_PIN; // key changed ?
ct0 = ~( ct0 & i ); // reset or count ct0
ct1 = ct0 ^ (ct1 & i); // reset or count ct1
i &= ct0 & ct1; // count until roll over ?
key_state ^= i; // then toggle debounced state
key_press |= key_state & i; // 0->1: key press detect

if( (key_state & REPEAT_MASK) == 0 ) // check repeat function
rpt = REPEAT_START; // start delay
if( --rpt == 0 ){
rpt = REPEAT_NEXT; // repeat delay
key_rpt |= key_state & REPEAT_MASK;
}
}

///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed. Each pressed key is reported
// only once
//
uint8_t get_key_press( uint8_t key_mask )
{
cli(); // read and clear atomic !
key_mask &= key_press; // read key(s)
key_press ^= key_mask; // clear key(s)
sei();
return key_mask;
}

///////////////////////////////////////////////////////////////////
//
// check if a key has been pressed long enough such that the
// key repeat functionality kicks in. After a small setup delay
// the key is reported being pressed in subsequent calls
// to this function. This simulates the user repeatedly
// pressing and releasing the key.
//
uint8_t get_key_rpt( uint8_t key_mask )
{
cli(); // read and clear atomic !
key_mask &= key_rpt; // read key(s)
key_rpt ^= key_mask; // clear key(s)
sei();
return key_mask;
}

///////////////////////////////////////////////////////////////////
//
uint8_t get_key_short( uint8_t key_mask )
{
cli(); // read key state and key press atomic !
return get_key_press( ~key_state & key_mask );
}

///////////////////////////////////////////////////////////////////
//
uint8_t get_key_long( uint8_t key_mask )
{
return get_key_press( get_key_rpt( key_mask ));
}

int main( void )
{
LED_PORT = 0xFF;
LED_DDR = 0xFF;

// Configure debouncing routines
KEY_DDR &= ~ALL_KEYS; // configure key port for input
KEY_PORT |= ALL_KEYS; // and turn on pull up resistors

TCCR0A = (1<<CS02)|(1<<CS00); // divide by 1024
TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms
TIMSK0 |= 1<<TOIE0; // enable timer interrupt

sei();

while(1){
if( get_key_short( 1<<KEY1 ))
LED_PORT ^= 1<<LED1;

if( get_key_long( 1<<KEY1 ))
LED_PORT ^= 1<<LED2;

// single press and repeat

if( get_key_press( 1<<KEY2 ) || get_key_rpt( 1<<KEY2 )){
uint8_t i = LED_PORT;

i = (i & 0x07) | ((i << 1) & 0xF0);
if( i < 0xF0 )
i |= 0x08;
LED_PORT = i;
}
}
}


Aber wie bei dem anderen auch, leider kein Ergebnis, schade den das mit lang und kurz drücken hört sich echt cool an,
das werd ich doch wohl noch hin bekommen?

by Ferdinand.

PicNick
01.08.2011, 07:23
Neuer vorschlag:

uint8_t taster(uint8_t* pinx, uint8_t px)
{

if( *pinx & (1 << px))
{
_delay_ms(10);
}

Ferdinand
01.08.2011, 18:07
Na ja, wen ich das verwende



/*
Funktion zum Tasten entprellen
taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))

Ich lese den PIND, PD0 ein und gebe ihn entprellt wider am PORTB aus.
Test Bort ist das STK500 mit Atmega644 8MHz.
PORTB ist auf LED's, und PORTD ist auf Taster geschaltet.

*/
#include <avr/io.h>
#include <stdint.h>
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 Hz definiert"
#define F_CPU 8000000UL /* Quarz mit 8000000 Hz */
#endif
#include <util/delay.h> /* bei alter avr-libc: #include <avr/delay.h> */

//Funktions Prototypen

uint8_t taster(uint8_t* pinx, uint8_t px);


int main (void)
{

DDRB = 0xff; //PORTB Ausgang



while(1) //Hauptschleife
{

if(taster(PIND, PD0)) //Taster0 Abfragen
{


PORTB = PD0; //LED0 Einschalten
}

} //Hauptschleife Ende
return 0;

} //Main Ende


//Funktion, taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))
uint8_t taster(uint8_t* pinx, uint8_t px)
{

if( *pinx & (1 << px))
{
_delay_ms(10);
}

else
{
return 0;
}

if( *pinx & (1 << px))
{
return *pinx;
}

else
{
return 0;
}

}


Dan kommt das



Build started 1.8.2011 at 18:52:40
avr-gcc -mmcu=atmega644 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT Taster.o -MF dep/Taster.o.d -c ../Taster.c
../Taster.c:13:2: warning: #warning "F_CPU war noch nicht definiert, wird nun mit 8000000 Hz definiert"
../Taster.c: In function 'main':
../Taster.c:33: warning: passing argument 1 of 'taster' makes pointer from integer without a cast
../Taster.c:20: note: expected 'uint8_t *' but argument is of type 'uint8_t'
avr-gcc -mmcu=atmega644 -Wl,-Map=Taster.map Taster.o -o Taster.elf
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature Taster.elf Taster.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex Taster.elf Taster.eep || exit 0
avr-objdump -h -S Taster.elf > Taster.lss

AVR Memory Usage
----------------
Device: atmega644

Program: 202 bytes (0.3% Full)
(.text + .data + .bootloader)

Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)


Build succeeded with 2 Warnings...



Und ale LED's Sind An.

Danke
by Ferdinand.

Richard
02.08.2011, 03:16
Die LED verdratung ist bein STK 500 auch etwas Trikreich...daran gedacht?

https://storage.driveonweb.de/dowdoc/1867b7c1f4c11873b1525937c322ceb9.JPG

Gruß Richard

Ferdinand
02.08.2011, 12:23
Ja Du hast recht, Taster getürkt Dan logische 0, LED an Dan logische 0.

Nur wie mach ich das jetzt mit meiner Funktion.
So?


/*
Funktion zum Tasten entprellen
taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))

Ich lese den PIND, PD0 ein und gebe ihn entprellt wider am PORTB aus.
Test Bort ist das STK500 mit Atmega644 8MHz.
PORTB ist auf LED's, und PORTD ist auf Taster geschaltet.


Taster Getrükt da 0, LED 0 dan an.
*/
#include <avr/io.h>
#include <stdint.h>
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun mit 8000000 Hz definiert"
#define F_CPU 8000000UL /* Quarz mit 8000000 Hz */
#endif
#include <util/delay.h> /* bei alter avr-libc: #include <avr/delay.h> */

//Funktions Prototypen

uint8_t taster(uint8_t* pinx, uint8_t px);


int main (void)
{

DDRB = 0xff; //PORTB Ausgang
PORTB = 0xff;


while(1) //Hauptschleife
{

if(taster(PIND, PD0)) //Taster0 Abfragen
{


PORTB = ~PD0; //LED0 Einschalten
}

} //Hauptschleife Ende
return 0;

} //Main Ende


//Funktion, taster([PORTx], ([PDx]|[PDy]|[PDz]|.usw ))
uint8_t taster(uint8_t* pinx, uint8_t px)
{

if(~( *pinx & (1 << px)))
{
_delay_ms(10);
}

else
{
return 0;
}

if( ~(*pinx & (1 << px)))
{
return *pinx;
}

else
{
return 0;
}

}



Wen ich das so ändere.



while(1) //Hauptschleife
{

if(taster(PIND, PD0)) //Taster0 Abfragen
{


PORTB = ~PD0; //LED0 Einschalten
}

} //Hauptschleife Ende

dan sin ale LED's aus.

Ich habe immer noch Warnungen und kann das nicht nach Vollziehen, warum, kan mir jemand das erklären (ich mag das mit den Pointern nicht so, weil man nicht gleich durchblickt, was da steht.)



Build started 2.8.2011 at 12:25:09
avr-gcc -mmcu=atmega644 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT Taster.o -MF dep/Taster.o.d -c ../Taster.c
../Taster.c:15:2: warning: #warning "F_CPU war noch nicht definiert, wird nun mit 8000000 Hz definiert"
../Taster.c: In function 'main':
../Taster.c:35: warning: passing argument 1 of 'taster' makes pointer from integer without a cast
../Taster.c:22: note: expected 'uint8_t *' but argument is of type 'uint8_t'
avr-gcc -mmcu=atmega644 -Wl,-Map=Taster.map Taster.o -o Taster.elf
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature Taster.elf Taster.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex Taster.elf Taster.eep || exit 0
avr-objdump -h -S Taster.elf > Taster.lss

AVR Memory Usage
----------------
Device: atmega644

Program: 208 bytes (0.3% Full)
(.text + .data + .bootloader)

Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)


Build succeeded with 2 Warnings...

Mickey S.
18.08.2011, 22:27
Hi!

Hallo Community! :o)

So, Ferdinand, nun zu Deinem Anliegen...

Nimm bitte mal die Warnung bzgl. Zeile 35 ernst. Mir ist nicht klar, warum uint8_t taster(uint8_*, uint8_t) als ersten Parameter einen Pointer haben muß. Du liest ja lediglich den Inhalt, auf den pinx zeigt, aus. Falls dort aber eine Pointer-Variable hingehört, dann mußt Du beim Aufruf eine Referenz auf PIND übergeben:

Zeile 35: if(taster(&PIND, PD0)) //Taster0 Abfragen

Probier's mal damit...


Gruß,

-Mike