<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=84.136.193.26</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=84.136.193.26"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/84.136.193.26"/>
	<updated>2026-04-10T23:20:50Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=31855</id>
		<title>Entprellung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=31855"/>
		<updated>2008-10-15T17:29:46Z</updated>

		<summary type="html">&lt;p&gt;84.136.193.26: /* Flankenerkennung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mechanische Schalter &amp;quot;prellen&amp;quot; beim Ein- und Ausschalten. Vereinfacht dargestellt sieht eine von einem Schalter oder Taster geschaltete Spannung beim Schalten wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Entprellen.png]]&lt;br /&gt;
&lt;br /&gt;
Für die Auswertung dieses unsauberen Signals gibt es verschiedene Ansätze:&lt;br /&gt;
&lt;br /&gt;
== Hardwareentprellung ==&lt;br /&gt;
&lt;br /&gt;
Tastenentprellung lässt sich in Hardware durch einen [[Filter|Tiefpassfilter]] mit nachgeschaltetem [[Schmitt-Trigger]] realisieren.&lt;br /&gt;
&lt;br /&gt;
Eine andere Hardware-Lösung ist die Verwendung eines Umschaltkontaktes und eines RS-Flipflops, das aus zwei NAND-Gattern gebildet wird. Der Schalter sollte vom Typ &amp;quot;nicht kurzschließend&amp;quot; sein.&lt;br /&gt;
&lt;br /&gt;
[[Bild:taster_entprellen_rs.png|framed|left|&#039;&#039;&#039;Taster entprellen mit NAND-RS FlipFlop&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung eines Mikrocontrollers kann man sich die zusätzliche Hardware sparen, da die Entprellung genau so gut in Software funktioniert.&lt;br /&gt;
&lt;br /&gt;
== Softwareentprellung ==&lt;br /&gt;
=== Flankenerkennung ===   &lt;br /&gt;
Bei einem Taster gibt es insgesamt 4 Zustände:   &lt;br /&gt;
&lt;br /&gt;
* 1. war nicht gedrückt und ist nicht gedrückt   &lt;br /&gt;
* 2. war nicht gedrückt und ist gedrückt (steigende Flanke)   &lt;br /&gt;
* 3. war gedrückt und ist immer noch gedrückt   &lt;br /&gt;
* 4. war gedrückt und ist nicht mehr gedrückt (fallende Flanke)   &lt;br /&gt;
    &lt;br /&gt;
Diese einzelnen Zustände lassen sich jetzt bequem abfragen/durchlaufen. Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms.   &lt;br /&gt;
    &lt;br /&gt;
Die Taster werden hierbei als Active-Low angeschlossen um die interen Pull-Ups zu nutzen.   &lt;br /&gt;
    &lt;br /&gt;
Diese Routine gibt für den Zustand &amp;quot;steigende Flanke&amp;quot; den Wert &amp;quot;1&amp;quot; zurück, sonst &amp;quot;0&amp;quot;&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;c&amp;gt;   &lt;br /&gt;
#define TASTERPORT PINC   &lt;br /&gt;
#define TASTERBIT PINC1   &lt;br /&gt;
   &lt;br /&gt;
char taster(void)   &lt;br /&gt;
{   &lt;br /&gt;
  static unsigned char zustand;   &lt;br /&gt;
  char rw = 0;   &lt;br /&gt;
   &lt;br /&gt;
  if(zustand == 0 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp;&amp;amp; (1&amp;lt;&amp;lt;TASTERBIT))) //Taster wird gedrueckt (steigende Flanke)   &lt;br /&gt;
  {   &lt;br /&gt;
    zustand = 1;   &lt;br /&gt;
    rw = 1;   &lt;br /&gt;
  }   &lt;br /&gt;
  else if (zustand == 1 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp;&amp;amp; (1&amp;lt;&amp;lt;TASTERBIT))) //Taster wird gehalten   &lt;br /&gt;
  {   &lt;br /&gt;
    zustand = 2;   &lt;br /&gt;
    rw = 0;   &lt;br /&gt;
  }&lt;br /&gt;
  else if (zustand == 2 &amp;amp;&amp;amp; (TASTERPORT &amp;amp;&amp;amp; (1&amp;lt;&amp;lt;TASTERBIT))) //Taster wird losgelassen (fallende Flanke)&lt;br /&gt;
  {&lt;br /&gt;
    zustand = 3;&lt;br /&gt;
    rw = 0;&lt;br /&gt;
  }&lt;br /&gt;
  else if (zustand == 3 &amp;amp;&amp;amp; (TASTERPORT &amp;amp;&amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))	//Taster losgelassen&lt;br /&gt;
  {&lt;br /&gt;
    zustand = 0;&lt;br /&gt;
    rw = 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return rw;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Warteschleifen-Verfahren ===&lt;br /&gt;
&lt;br /&gt;
Siehe [[AVR-GCC-Tutorial#.28Tasten-.29Entprellung|Abschnitt (Tasten-)Entprellung im AVR-GCC-Tutorial]].&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;DEBOUNCE&#039;&#039; Befehl in dem BASIC-Dialekt BASCOM für AVR ist ebenfalls nach dem Warteschleifen-Verfahren programmiert. Die Wartezeit beträgt defaultmässig 25 ms, kann aber vom Anwender überschrieben werden. Vgl.  [http://avrhelp.mcselec.com/bascom-avr.html?DEBOUNCE BASCOM Online-Manual zu DEBOUNCE].&lt;br /&gt;
&lt;br /&gt;
Der Nachteil dieses Verfahrens ist, dass der Controller durch die Warteschleife blockiert wird. Günstiger ist die Implementierung mit einem Timer-Interrupt.&lt;br /&gt;
&lt;br /&gt;
==== Warteschleifenvariante mit Maske und Pointer (nach Christian Riggenbach) ====&lt;br /&gt;
&lt;br /&gt;
Hier eine weitere Funktion um Taster zu entprellen. Durch den zusätzlichen Code kann eine Entprellzeit von durchschnittlich 1-3ms (mindestens 8*150us = 1ms) erreicht werden. Grundsätzlich prüft die Funktion den Pegel der Pins auf einem bestimmten Port. Wenn die/der Pegel 8 mal konstant war, wird die Schleife verlassen. Diese Funktion kann sehr gut gebraucht werden, um in einer Endlosschleife Taster anzufragen, da sie, wie erwähnt, eine kurze Wartezeit hat.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void entprellung( uint8_t *port, uint8_t maske ) {&lt;br /&gt;
  uint8_t   port_puffer;&lt;br /&gt;
  uint8_t   entprellungs_puffer;&lt;br /&gt;
&lt;br /&gt;
  for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {&lt;br /&gt;
    entprellungs_puffer&amp;lt;&amp;lt;=1;&lt;br /&gt;
    port_puffer = *port;&lt;br /&gt;
    _delay_us(150);&lt;br /&gt;
    if( (*port &amp;amp; maske) == (port_puffer &amp;amp; maske) )&lt;br /&gt;
      entprellungs_puffer |= 0x01;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Funktion wird wie folgt aufgerufen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
entprellung( (uint8_t*)&amp;amp;PINB, (1&amp;lt;&amp;lt;PINB2) );&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Als Maske kann ein beliebiger Wert übergeben werden. Sie verhindert, dass nicht verwendete Taster die Entprellzeit negativ beeinflussen.&lt;br /&gt;
Der Cast (uint8_t*) wird gebraucht um den gcc &amp;quot;ruhigzustellen&amp;quot;, sprich er verhindert eine Compiler-Warnung.&lt;br /&gt;
&lt;br /&gt;
=== Interrupt-Verfahren (nach Peter Dannegger) ===&lt;br /&gt;
&lt;br /&gt;
==== Grundroutine (AVR Assembler) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-20435.html#new Forum] &lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* besonders kurzer Code&lt;br /&gt;
* schnell&lt;br /&gt;
* sicher (4-fach-Abtastung) &lt;br /&gt;
&lt;br /&gt;
Außerdem können 8 Tasten gleichzeitig bearbeitet werden, es dürfen also&lt;br /&gt;
alle exakt zur selben Zeit gedrückt werden. Andere Routinen können z.B. nur eine Taste verarbeiten, d.h. die zuerst oder zuletzt gedrückte gewinnt oder es kommt Unsinn heraus.&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Einlese- und Entprellroutine ist nur 8 Instruktionen&lt;br /&gt;
kurz. Der entprellte Tastenzustand ist im Register &amp;quot;key_state&amp;quot;. Mit nur 2 weiteren Instruktionen wird dann der Wechsel von Taste offen zu&lt;br /&gt;
Taste gedrückt erkannt und im Register &amp;quot;key_press&amp;quot; abgelegt. Im Beispielcode werden dann damit 8 LEDs ein- und ausgeschaltet. Jede Taste entspricht einem Bit in den Registern, d.h. die Verarbeitung erfolgt bitweise mit logischen Operationen. Zum Verständnis empfiehlt es sich daher, die Logikgleichungen mit Gattern für ein Bit = eine Taste aufzumalen. Die Register kann man sich als Flip-Flops denken, die mit der Entprellzeit als Takt arbeiten. D.h. man kann das auch so z.B. in einem GAL22V10 realisieren.&lt;br /&gt;
&lt;br /&gt;
Als Kommentar sind neben den einzelnen Instruktionen alle 8 möglichen&lt;br /&gt;
Kombinationen der 3 Signale dargestellt.&lt;br /&gt;
&lt;br /&gt;
Beispielcode für AVR (Assembler):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;c:\avr\inc\1200def.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
.def  save_sreg         = r0&lt;br /&gt;
.def  iwr0              = r1&lt;br /&gt;
.def  iwr1              = r2&lt;br /&gt;
&lt;br /&gt;
.def  key_old           = r3&lt;br /&gt;
.def  key_state         = r4&lt;br /&gt;
.def  key_press         = r5&lt;br /&gt;
&lt;br /&gt;
.def  leds              = r16&lt;br /&gt;
.def  wr0               = r17&lt;br /&gt;
&lt;br /&gt;
.equ  key_port          = pind&lt;br /&gt;
.equ  led_port          = portb&lt;br /&gt;
&lt;br /&gt;
      rjmp   init&lt;br /&gt;
.org OVF0addr		;timer interrupt 24ms&lt;br /&gt;
      in     save_sreg, SREG&lt;br /&gt;
get8key:                               ;/old      state     iwr1      iwr0&lt;br /&gt;
      mov    iwr0, key_old             ;00110011  10101010            00110011&lt;br /&gt;
      in     key_old, key_port         ;11110000&lt;br /&gt;
      eor    iwr0, key_old             ;                              11000011&lt;br /&gt;
      com    key_old                   ;00001111&lt;br /&gt;
      mov    iwr1, key_state           ;                    10101010&lt;br /&gt;
      or     key_state, iwr0           ;          11101011&lt;br /&gt;
      and    iwr0, key_old             ;                              00000011&lt;br /&gt;
      eor    key_state, iwr0           ;          11101000&lt;br /&gt;
      and    iwr1, iwr0                ;                    00000010&lt;br /&gt;
      or     key_press, iwr1           ;store key press detect&lt;br /&gt;
;&lt;br /&gt;
;			insert other timer functions here&lt;br /&gt;
;&lt;br /&gt;
      out    SREG, save_sreg&lt;br /&gt;
      reti&lt;br /&gt;
;-------------------------------------------------------------------------&lt;br /&gt;
init:&lt;br /&gt;
      ldi    wr0, 0xFF&lt;br /&gt;
      out    ddrb, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;CS02 | 1&amp;lt;&amp;lt;CS00    ;divide by 1024 * 256&lt;br /&gt;
      out    TCCR0, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;TOIE0             ;enable timer interrupt&lt;br /&gt;
      out    TIMSK, wr0&lt;br /&gt;
&lt;br /&gt;
      clr    key_old&lt;br /&gt;
      clr    key_state&lt;br /&gt;
      clr    key_press&lt;br /&gt;
      ldi    leds, 0xFF&lt;br /&gt;
main: cli&lt;br /&gt;
      eor    leds, key_press           ;toggle LEDs&lt;br /&gt;
      clr    key_press                 ;clear, if key press action done&lt;br /&gt;
      sei&lt;br /&gt;
      out    led_port, leds&lt;br /&gt;
      rjmp   main&lt;br /&gt;
;-------------------------------------------------------------&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Komfortroutine (C für AVR) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-310276.html Forum]&lt;br /&gt;
&lt;br /&gt;
Funktionsprinzip wie oben plus zusätzliche Features:  &lt;br /&gt;
* Kann Tasten sparen durch unterschiedliche Aktionen bei kurzem oder langem Drücken&lt;br /&gt;
* Wiederholfunktion, z.B. für die Eingabe von Werten&lt;br /&gt;
&lt;br /&gt;
Das Programm ist für avr-gcc/avr-libc geschrieben, kann aber mit ein paar Anpassungen auch mit anderen Compilern und Mikrocontrollern verwendet werden. Eine Portierung für den AT91SAM7 findet man [http://www.google.com/codesearch?q=show:ac2viP-2E2Y:pzkOO5QRsoc:RPICuprYy-A&amp;amp;sa=N&amp;amp;cd=1&amp;amp;ct=rc&amp;amp;cs_p=svn://mikrocontroller.net/mp3dec/trunk&amp;amp;cs_f=keys.c#a0 hier] (aus dem Projekt [[ARM MP3/AAC Player]]).&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*                      Debouncing 8 Keys                               */&lt;br /&gt;
/*                      Sampling 4 Times                                */&lt;br /&gt;
/*                      With Repeat Function                            */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*              Author: Peter Dannegger                                 */&lt;br /&gt;
/*                      danni@specs.de                                  */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU           1000000                   // processor clock frequency&lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
#define KEY_DDR         DDRB&lt;br /&gt;
#define KEY_PORT        PORTB&lt;br /&gt;
#define KEY_PIN         PINB&lt;br /&gt;
#define KEY0            0&lt;br /&gt;
#define KEY1            1&lt;br /&gt;
#define KEY2            2&lt;br /&gt;
#define ALL_KEYS        (1&amp;lt;&amp;lt;KEY0 | 1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)&lt;br /&gt;
 &lt;br /&gt;
#define REPEAT_MASK     (1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)       // repeat: key1, key2&lt;br /&gt;
#define REPEAT_START    50                        // after 500ms&lt;br /&gt;
#define REPEAT_NEXT     20                        // every 200ms&lt;br /&gt;
&lt;br /&gt;
#define LED_DDR         DDRA&lt;br /&gt;
#define LED_PORT        PORTA&lt;br /&gt;
#define LED0            0&lt;br /&gt;
#define LED1            1&lt;br /&gt;
#define LED2            2&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_state;                                // debounced and inverted key state:&lt;br /&gt;
                                                  // bit = 1: key pressed&lt;br /&gt;
volatile uint8_t key_press;                                // key press detect&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_rpt;                                  // key long press and repeat&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
ISR( TIMER0_OVF_vect )                            // every 10ms&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t ct0, ct1, rpt;&lt;br /&gt;
  uint8_t i;&lt;br /&gt;
 &lt;br /&gt;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms&lt;br /&gt;
 &lt;br /&gt;
  i = key_state ^ ~KEY_PIN;                       // key changed ?&lt;br /&gt;
  ct0 = ~( ct0 &amp;amp; i );                             // reset or count ct0&lt;br /&gt;
  ct1 = ct0 ^ (ct1 &amp;amp; i);                          // reset or count ct1&lt;br /&gt;
  i &amp;amp;= ct0 &amp;amp; ct1;                                 // count until roll over ?&lt;br /&gt;
  key_state ^= i;                                 // then toggle debounced state&lt;br /&gt;
  key_press |= key_state &amp;amp; i;                     // 0-&amp;gt;1: key press detect&lt;br /&gt;
 &lt;br /&gt;
  if( (key_state &amp;amp; REPEAT_MASK) == 0 )            // check repeat function&lt;br /&gt;
     rpt = REPEAT_START;                          // start delay&lt;br /&gt;
  if( --rpt == 0 ){&lt;br /&gt;
    rpt = REPEAT_NEXT;                            // repeat delay&lt;br /&gt;
    key_rpt |= key_state &amp;amp; REPEAT_MASK;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed. Each pressed key is reported&lt;br /&gt;
// only once&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_press( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_press;                          // read key(s)&lt;br /&gt;
  key_press ^= key_mask;                          // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed long enough such that the&lt;br /&gt;
// key repeat functionality kicks in. After a small setup delay&lt;br /&gt;
// the key is reported beeing pressed in subsequent calls&lt;br /&gt;
// to this function. This simulates the user repeatedly&lt;br /&gt;
// pressing and releasing the key.&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_rpt( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_rpt;                            // read key(s)&lt;br /&gt;
  key_rpt ^= key_mask;                            // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_short( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read key state and key press atomic !&lt;br /&gt;
  return get_key_press( ~key_state &amp;amp; key_mask );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_long( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  return get_key_press( get_key_rpt( key_mask ));&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
  KEY_DDR &amp;amp;= ~ALL_KEYS;                // konfigure key port for input&lt;br /&gt;
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors&lt;br /&gt;
&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;CS02)|(1&amp;lt;&amp;lt;CS00);			// divide by 1024&lt;br /&gt;
  TIMSK = 1&amp;lt;&amp;lt;TOIE0;				// enable timer interrupt&lt;br /&gt;
 &lt;br /&gt;
  LED_PORT = 0xFF;&lt;br /&gt;
  LED_DDR =                      // long press: task 2&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_short( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED1;&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_long( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED2;&lt;br /&gt;
 &lt;br /&gt;
                                                  // single press and repeat&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 )){&lt;br /&gt;
      uint8_t i = LED_PORT;&lt;br /&gt;
 &lt;br /&gt;
      i = (i &amp;amp; 0x07) | ((i &amp;lt;&amp;lt; 1) &amp;amp; 0xF0);&lt;br /&gt;
      if( i &amp;lt; 0xF0 )&lt;br /&gt;
        i |= 0x08;&lt;br /&gt;
      LED_PORT = i;      &lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das single-press-und-repeat Beispiel geht nicht in jeder Beschaltung, folgendes Beispiel sollte universeller sein (einzelne LED an/aus):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
                                                 // single press and repeat&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 )){&lt;br /&gt;
    &lt;br /&gt;
	LED_PORT ^=0x08;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [[AVR-Tutorial: Tasten]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#.28Tasten-.29Entprellung|AVR-GCC-Tutorial Tastenentprellung]]&lt;br /&gt;
* http://www.mikrocontroller.net/forum/read-4-20435.html (AVR Assembler)&lt;br /&gt;
* http://www.mikrocontroller.net/forum/read-1-140056.html#140946 (AVR-ASM 1 Taste)&lt;br /&gt;
* http://www.ganssle.com/debouncing.pdf A guide to debouncing (engl.), praktische Erläuterungen zum Entprellen in Soft- und Hardware&lt;br /&gt;
* http://www.mikrocontroller.net/forum/read-1-242461.html&lt;br /&gt;
* http://www.mikrocontroller.net/topic/94829&lt;br /&gt;
* http://www.mikrocontroller.net/topic/18764#135843&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;/div&gt;</summary>
		<author><name>84.136.193.26</name></author>
	</entry>
</feed>