mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Taster Entprellung am Attiny 841 und Auswertung


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo
ich möchte an einem Attiny verschiedene Tasten entprellen und auswerten. 
Dazu möchte ich die Entprellung von Peter verwenden. Dabei scheint es 
ein paar Probleme zu geben. Das fängt an mit der Belegung der Tasten. 
Diese sind beim Ati 841 auf 2 Ports verteilt. Habe dazu es mal 
angepasst.

Belegung der Hardware:

// PA0 --> T1
// PB0 --> T2
// PA7 --> T3
// PA5 --> T4
// PB1 --> T5
volatile uint8_t key_state;
volatile uint8_t key_press;
volatile uint8_t key_rpt;

#define KEY_DDR    DDRA            // Datenrichtung A
#define KEY_PORT   PORTA           // Angabe Port A
#define KEY_PIN    PINA            // Angabe PIN A
#define KEY_1       0              // PA 0 - Taster 1
#define KEY_3       7              // PA 3 - Taster 3
#define KEY_4       5              // PA 5 - Taster 4

#define KEY_DDR    DDRB             // Datenrichtung B
#define KEY_PORT   PORTB            // Angabe Port B
#define KEY_PIN    PINB             // Angabe PIN B
#define KEY_2       0               // PB 0 - Taster 2
#define KEY_5       1               // PB 1 - Taster 5
               
#define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)

PUEA=0b10100001;          // R auf Taster PORT A
PUEB=0b00000011;          // R auf Taster PORT B

#define REPEAT_MASK (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
#define REPEAT_START 50        // after 500ms
#define REPEAT_NEXT 20              // every 200ms
Ist das so möglich?
LG Paul

Autor: Anton (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Hallo Paul

Paul schrieb:
> Dabei scheint es
> ein paar Probleme zu geben.

wäre sehr hilfreich, wenn Du angeben würdest, WELCHE Probleme es gibt...

Glaskugelgucken alleine hilft da nicht...


mfg

Anton

Autor: Anton (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Hallo Paul

Paul schrieb:
> Dazu möchte ich die Entprellung von Peter verwenden

wäre schön, wenn Du den GANZEN Namen (nicht nur "Peter") und den link 
für die SW von "Peter" posten würdest...

mfg

Anton

Autor: Veit D. (devil-elec)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo,

wenn du schon define verwendest, dann solltest du das konsequent 
durchziehen und die Pullup-Register demzufolge auch mittels der Namen 
konfigurieren.  :-)
Deine KEY_DDR, KEY_PORT und KEY_PIN solltest du nochmal überdenken.
Dein ALL-KEYS und MASK wirst du wohl so niemals verwenden können, weil 
die Taster auf verschiedenen Ports liegen.

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Einen Fehler habe ich schon gefunden:
volatile uint8_t key_state;
volatile uint8_t key_press;
volatile uint8_t key_rpt;

#define KEY_DDRA    DDRA            // Datenrichtung A
#define KEY_PORTA   PORTA           // Angabe Port A
#define KEY_PINA    PINA            // Angabe PIN A
#define KEY_1       0              // PA 0 - Taster 1
#define KEY_3       7              // PA 3 - Taster 3
#define KEY_4       5              // PA 5 - Taster 4

#define KEY_DDRB    DDRB             // Datenrichtung B
#define KEY_PORTB   PORTB            // Angabe Port B
#define KEY_PINB    PINB             // Angabe PIN B
#define KEY_2       0               // PB 0 - Taster 2
#define KEY_5       1               // PB 1 - Taster 5
               
#define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)

PUEA=0b10100001;          // R auf Taster PORT A
PUEB=0b00000011;          // R auf Taster PORT B

#define REPEAT_MASK (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
#define REPEAT_START 50        // after 500ms
#define REPEAT_NEXT 20              // every 200ms
Nehme den Code erst langsam in Betrieb.
Es geht dabei um die Frage, ob ich mit dem Code von Peter Danner. die 
Eingänge auf 2 Ports verteilen kann?

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Das ist schon mal ein sehr guter Hinweis. Danke

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Meinst du diese Stelle:
KEY_DDRA&=~ALL_KEYS;
KEY_PORTA|=ALL_KEYS;
KEY_DDRB&=~ALL_KEYS;
KEY_PORTB|=ALL_KEYS;

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Nächstes Problem mit dem Timer:
ISR (TIMER0_OVF_vect)        // Timer
  {
  static uint8_t ct0,ct1,rpt;
  uint8_t i;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);
  i=key_state ^~KEY_PINA;        // PINA oder PINB
  ct0=~(ct0&i);
  ct1=ct0^(ct1&i);
  i&=ct0&ct1;
  key_state^=i;
  key_press|=key_state&i;
  if((key_state & REPEAT_MASK)==0)
  rpt=REPEAT_START;
  if(--rpt==0)
    {
    rpt=REPEAT_NEXT;
    key_rpt|=key_state & REPEAT_MASK;
    }
  }
ich meine diese Zeile:
i=key_state ^~KEY_PINA;        // PINA oder PINB
Mit original Code steht nur KEY_PIN drin. Da ich jetzt PINA und PINB 
verwende klappt das nicht.

Autor: Peter D. (peda)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Paul schrieb:
> Belegung der Hardware:
>
> // PA0 --> T1
> // PB0 --> T2
> // PA7 --> T3
> // PA5 --> T4
> // PB1 --> T5

Das ist jetzt keine Raketenwissenschaft, nur ein Bit überlappt sich.
In der ISR die 5 Bits in ein Byte einsammeln:
  uint8_t i = PINA & (1<<PA0 | 1<<PA5 | 1<<PA7);
  i |= (PINB & ((1<<PB0 | 1<<PB1)) << 1;
// ...

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Danke für deine Hilfe.
Es stimmt, es ist keine Raketenwissenschaft. Habe die Erklärung vor mir 
zu liegen und gelesen. Gelesen bedeutet aber nicht es zu verstehen. Ist 
einfach zu kompliziert für mich. Scheint aber auch anderen so zu gehen.
LG Paul

Autor: roehrenvorheizer (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo,

sollten da nicht noch etliche KLammern sein?

#define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)


MfG

Autor: Theor (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
roehrenvorheizer schrieb:
> Hallo,
>
> sollten da nicht noch etliche KLammern sein?
>
> #define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
>
>
> MfG

https://de.wikibooks.org/wiki/C-Programmierung:_Liste_der_Operatoren_nach_Priorit%C3%A4t

Autor: Joachim B. (jar)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Veit D. schrieb:
> wenn du schon define verwendest, dann solltest du das konsequent
> durchziehen und die Pullup-Register demzufolge auch mittels der Namen
> konfigurieren.  :-)
> Deine KEY_DDR, KEY_PORT und KEY_PIN solltest du nochmal überdenken.
> Dein ALL-KEYS und MASK wirst du wohl so niemals verwenden können, weil
> die Taster auf verschiedenen Ports liegen.

Peter D. schrieb:
> Das ist jetzt keine Raketenwissenschaft, nur ein Bit überlappt sich.
> In der ISR die 5 Bits in ein Byte einsammeln:  uint8_t i = PINA &
> (1<<PA0 | 1<<PA5 | 1<<PA7);
>   i |= (PINB & ((1<<PB0 | 1<<PB1)) << 1;

wollte ich auch gerade vorschlagen, die verschiedenen Port A/B Bits in 
ein neues HilfsByte umzusetzen und dann ganz normal weiterarbeiten

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Sowas ähnliches wäre auch mein Vorschlag. Mach das ganze erstmal auf 
einem Port funktionsfähig und dupliziere dann die Routine für den 
anderen Port.

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
HJabe den kompletten Code. Er funktioniert ohne Fehlermeldung. Die 
Funktion ist beiden Ports möglich, hat aber ein paar komische Effekte.
#define F_CPU 8E6        // Angabe Frequenz
#include <avr/io.h>        // Einbindung Datein
#include <avr/interrupt.h>
#include <stdint.h>

volatile uint8_t key_state;
volatile uint8_t key_press;
volatile uint8_t key_rpt;

#define KEY_DDRA    DDRA           // Datenrichtung A
#define KEY_PORTA   PORTA          // Angabe Port A
#define KEY_PINA    PINA           // Angabe PIN A
#define KEY_1       0              // PA 0 - Taster 1
#define KEY_3       7              // PA 7 - Taster 3
#define KEY_4       5              // PA 5 - Taster 4

#define KEY_DDRB    DDRB           // Datenrichtung B
#define KEY_PORTB   PORTB          // Angabe Port B
#define KEY_PINB    PINB           // Angabe PIN B
#define KEY_2       0              // PB 0 - Taster 2
#define KEY_5       1              // PB 1 - Taster 5
               
#define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
#define REPEAT_MASK (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
#define REPEAT_START 50        // after 500ms
#define REPEAT_NEXT 20              // every 200ms

ISR (TIMER0_OVF_vect)        // Timer
  {
  static uint8_t ct0,ct1,rpt;
  uint8_t i;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);
  i = PINA & (1<<PINA0 | 1<<PINA5 | 1<<PINA7);
  i |= (PINB & ((1<<PINB0 | 1<<PINB1)) << 1);
  ct0=~(ct0&i);
  ct1=ct0^(ct1&i);
  i&=ct0&ct1;
  key_state^=i;
  key_press|=key_state&i;
  if((key_state & REPEAT_MASK)==0)
  rpt=REPEAT_START;
  if(--rpt==0)
    {
    rpt=REPEAT_NEXT;
    key_rpt|=key_state & REPEAT_MASK;
    }
  }

uint8_t get_key_press(uint8_t key_mask)
  {
  cli();
  key_mask &=key_press;
  key_press^=key_mask;
  sei();
  return key_mask;
  }

uint8_t get_key_rpt(uint8_t key_mask)
  {
  cli();
  key_mask &=key_rpt;
  key_rpt^=key_mask;
  sei();
  return key_mask;
  }

uint8_t get_key_short(uint8_t key_mask)
  {
  cli();
  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));
  }

void timer_init()
  {            
  TCCR0B = (1<<CS02)|(1<<CS00);                // Prescaler 1024
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
  TIMSK0 |= 1<<TOIE0;                      // Interrupt erlauben
  }

int main(void)              // Programmschleife main
  {
  timer_init();            // Timer init
  
  PUEA=0b10100001;          // R auf Taster PORT A
  PUEB=0b00000011;          // R auf Taster PORT B
  
  DDRB=0b00000100;          // Port B auf Ausgang schalten
  PORTB = (1<<PINB2);
  
  KEY_DDRA&=~ALL_KEYS;
  KEY_PORTA|=ALL_KEYS;
  KEY_DDRB&=~ALL_KEYS;
  KEY_PORTB|=ALL_KEYS;
  
  sei();
  while(1)              // Programmschleife while
    {
    if(get_key_press(1<<KEY_2))    // nur Taste press
      {                // LED an
      PORTB &= ~(1<<PINB2);    // 3+4,4+5
      }
    
    if(get_key_press(1<<KEY_3))    // nur Taste press
      {                // LED aus
      PORTB |= (1<<PINB2);
      }
    }                  // Ende while
  }                    // Ende main
Effekte sind
- die LED zur Kontrolle auf L blinkt mit unterschiedlichen Takt
- T1 und T2 reagieren nicht so wie sie sollen

Autor: Theor (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> HJabe den kompletten Code. Er funktioniert ohne Fehlermeldung. Die
> Funktion ist beiden Ports möglich, hat aber ein paar komische Effekte.
...
> #define KEY_1       0              // PA 0 - Taster 1
...
> #define KEY_2       0              // PB 0 - Taster 2

> #define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
> #define REPEAT_MASK (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)

>   i = PINA & (1<<PINA0 | 1<<PINA5 | 1<<PINA7);
>   i |= (PINB & ((1<<PINB0 | 1<<PINB1)) << 1);
...
> 
> Effekte sind

> - die LED zur Kontrolle auf L blinkt mit unterschiedlichen Takt
Das verstehe ich nicht.

> - T1 und T2 reagieren nicht so wie sie sollen
Und wie reagieren sie? Du solltest Dir analytisches Vorgehen angewöhnen. 
D.h. Verhalten detailliert beschreiben. Daraus ergibt sich meist schon 
ein Hinweis auf die Ursache.

Schau Dir den Code an, den ich aus Deinem extrahiert habe.
KEY_1 und KEY_2 haben die gleiche Bitnummer.
Nach der Verschiebeaktion (der zweite Ausdruck mit i auf der linken 
Seite) haben KEY_2 (und übrigens KEY_5) nicht mehr die Bitnummern wie in 
dem define darüber. Logisch, oder?

Das Verhalten lässt sich vermutlich so beschreiben.
"Fragst Du auf KEY_1 und/oder KEY_2 ab, so bewirken beide Tasten das 
selbe. Es gibt anscheinend, vom Programm aus gesehen, keinen Unterschied 
zwischen den beiden Tasten."

Analoges gilt für die Masken ALL_KEYS und REPEAT_MASK.

Autor: Veit D. (devil-elec)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo,

ich halte den Vorschlag mit dem vermischen der Bits beider Ports für 
gefährlich, eben weil sie sich überlappen. Am Ende kommt solcher Mist 
bei raus.
#define KEY_1       0              // PA 0 - Taster 1
#define KEY_3       7              // PA 7 - Taster 3
#define KEY_4       5              // PA 5 - Taster 4

#define KEY_2       0              // PB 0 - Taster 2
#define KEY_5       1              // PB 1 - Taster 5
               
#define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
#define REPEAT_MASK (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)

Setze die einzelnen Bits ein und schaue welcher Unsinn rauskommt.
Wie soll KEY1 und KEY2 unterschieden werden?

Damit das halbwegs vernünftig wird müssten mindestens Offsets rein, 
sodass jedes Tasterbit auf seiner nach außen benannten Tasternummer hin 
entspricht. Dann macht das wieder Sinn, nur dann. Oder jeden Port 
einzeln betrachten.

ALL_KEYS und REPEAT_MASK sind gleich. Muss das so sein?
Auch hier lauert eine Falle bei falscher Verwendung, da sie nicht 
schreibgeschützt sind, also obacht.

In C++ würde ich mir EINE Klasse erstellen und davon soviele Objekte wie 
nötig instanzieren. Das als Randnotiz.

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
#define KEY_DDRA    DDRA           // Datenrichtung A
#define KEY_PORTA   PORTA          // Angabe Port A
#define KEY_PINA    PINA           // Angabe PIN A
#define KEY_1       0              // PA 0 - Taster 1
#define KEY_3       7              // PA 7 - Taster 3
#define KEY_4       5              // PA 5 - Taster 4

#define KEY_DDRB    DDRB           // Datenrichtung B
#define KEY_PORTB   PORTB          // Angabe Port B
#define KEY_PINB    PINB           // Angabe PIN B
#define KEY_2       0              // PB 0 - Taster 2
#define KEY_5       1              // PB 1 - Taster 5
KEY_1 ist doch PORTA - PA0
KEY_2 ist doch PORTB - PB0
zugeordnet.

Veit D. schrieb:
> ALL_KEYS und REPEAT_MASK sind gleich. Muss das so sein?
> Auch hier lauert eine Falle bei falscher Verwendung, da sie nicht
> schreibgeschützt sind, also obacht.

Im original Code von Peter sind noch andere Verwendungen drin. Diese 
verwende ich (noch) nicht
Es könnte zu einer überlagerung von PA0 und PB0 kommen, könnte auch den 
Effekt mit den Tasten ergeben. Die Tasten 3,4,5 laufen ohne Probleme

Autor: Theor (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> [...]
>
> Im original Code von Peter sind noch andere Verwendungen drin. Diese
> verwende ich (noch) nicht
> Es könnte zu einer überlagerung von PA0 und PB0 kommen, könnte auch den
> Effekt mit den Tasten ergeben. Die Tasten 3,4,5 laufen ohne Probleme

Was heisst "könnte"?
Es wäre m.M.n. zweckmäßig, wenn Du den Code auf dem Papier 
nachvollziehst, die Wirkung der Tatsache, dass KEY_1 und KEY_2 durch den 
gleichen Wert ersetzt werden, beobachtest und dann Änderungen überlegst. 
Diese implementierst Du dann und  testest sie.

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Theor schrieb:
> dass KEY_1 und KEY_2 durch den
> gleichen Wert ersetzt werden

Ist das der Hauptgrund? Könnte versuchen die Hardware zu ändern.

Autor: Theor (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> Theor schrieb:
>> dass KEY_1 und KEY_2 durch den
>> gleichen Wert ersetzt werden
>
> Ist das der Hauptgrund? [...]

Das stellst Du fest, wenn Du den Code nachvollziehst.

Autor: Joachim B. (jar)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> HJabe den kompletten Code. Er funktioniert ohne Fehlermeldung. Die
> Funktion ist beiden Ports möglich, hat aber ein paar komische Effekte.

du hast das noch nicht zuende gedacht!

Peter D. schrieb:
> uint8_t i = PINA & (1<<PA0 | 1<<PA5 | 1<<PA7);
>   i |= (PINB & ((1<<PB0 | 1<<PB1)) << 1;

was psassiert mit deinen KEYS

Paul schrieb:
> #define KEY_DDR    DDRB             // Datenrichtung B
> #define KEY_PORT   PORTB            // Angabe Port B
> #define KEY_PIN    PINB             // Angabe PIN B
> #define KEY_2       0               // PB 0 - Taster 2
> #define KEY_5       1               // PB 1 - Taster 5

nach schieben
>   i |= (PINB & ((1<<PB0 | 1<<PB1)) << 1;

sie werden Bit 1 und Bit 2 welche in der Variable i ja noch frei waren.

Danach sind deine Keys aber KEY_2 ehemals 0 aber 1 durch schieben und 
KEY5 ehemals 1 aber 2 durch schieben!

Es gibt dann keine dopppelt belegten Bits mehr in Variable i

Veit D. schrieb:
> #define KEY_1       0              // PA 0 - Taster 1
> #define KEY_3       7              // PA 7 - Taster 3
> #define KEY_4       5              // PA 5 - Taster 4

NEU

> #define KEY_2       1              // PB 0 - Taster 2
> #define KEY_5       2              // PB 1 - Taster 5
>
> #define ALL_KEYS (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)
> #define REPEAT_MASK (1<<KEY_1|1<<KEY_2|1<<KEY_3|1<<KEY_4|1<<KEY_5)

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Joachim B. schrieb:
> NEU
>
>> #define KEY_2       1              // PB 0 - Taster 2
>> #define KEY_5       2              // PB 1 - Taster 5

Meinst du damit das ich die 0 --> 1 und die 1 --> 2 ändern soll?

Autor: Karl M. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> Joachim B. schrieb:
>> NEU
>>
>>> #define KEY_2       1              // PB 0 - Taster 2
>>> #define KEY_5       2              // PB 1 - Taster 5
>
> Meinst du damit das ich die 0 --> 1 und die 1 --> 2 ändern soll?

Nicht ganz.

Deine realen PinPort Definitionen werden auf eineindeutige ID gepappt.

Du musst somit die Hardware Definitionen und die notwendige PinPort 
Initialisierung von realen Zugriff über das Mapping auf die nun 
"virtuellen" Tasten, trennen.

Du schreibst, und beachte, dass Defines nicht doppelt belegt werden 
können!
Siehe: KEY_DDR, KEY_PORT und KEY_PIN
#define KEY_1       0              // PA 0 - Taster 1
#define KEY_3       7              // PA 3 - Taster 3
#define KEY_4       5              // PA 5 - Taster 4

#define KEY_2       0               // PB 0 - Taster 2
#define KEY_5       1               // PB 1 - Taster 5

Tastenmapping | realer Taster
0             | KEY_1
7             | KEY_3
5             | KEY_4
// hier bitte den Post von Peter Dannegger beachten!
1             | KEY_2
2             | KEY_5

Wenn Du also die Funktionen der Tastenenprellung nutzen möchtest,
dann sind die Mappping ID zu nutzen, bzw. der Bitmaske.
Hier einige Defines dazu:
#define MAP_KEY_1 0
#define MAP_KEY_3 7
#define MAP_KEY_4 5
#define MAP_KEY_2 1
#define MAP_KEY_5 2

Und solange Du nicht Funktionen der Tastenenprellung verstehst, wirst Du 
diese Erweiterungen nicht umsetzen können.

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Habe nachgelesen was Mapping so macht.
Die Funktion der Tasterentprellung versteh ich nicht. Auch mit einer 
Erklärung ist es zu kompliziert für mich. Wie ich feststellen konnte, 
geht es auch vielen anderen so. Mit der Anwendung klappt es besser. 
Verwende die Entprellung in verschiedenen Projekten. Alles ohne 
Probleme.
Vielleicht könnte mir jemand weiterhelfen oder ist es besser die 
Hardware zu ändern?

Autor: Karl M. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> Habe nachgelesen was Mapping so macht.
> Die Funktion der Tasterentprellung versteh ich nicht. Auch mit einer
> Erklärung ist es zu kompliziert für mich. Wie ich feststellen konnte,
> geht es auch vielen anderen so. Mit der Anwendung klappt es besser.
> Verwende die Entprellung in verschiedenen Projekten. Alles ohne
> Probleme.
> Vielleicht könnte mir jemand weiterhelfen oder ist es besser die
> Hardware zu ändern?

Dann nimm dir bitte 4 Wochen Zeit zum C lernen und dann Verstehen der 
Codeteile.

Wissen braucht halt Zeit und Übung.
Durch Fehler lernt man am meisten.
Ohne Dir, als evtl. Jugendlicher, näher treten zu wollen, es wird schon.
Bleibe am Ball!

Autor: Joachim B. (jar)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> Die Funktion der Tasterentprellung versteh ich nicht

musst du auch nicht vollständig verstehen, was du verstehen solltest

deine Tasten an PB liegen auf 0 & 1

die liest du ein auf ein Hilfsbyte

Peter D. schrieb:
> (PINB & ((1<<PB0 | 1<<PB1)) << 1;

also uint8_t hilfsbyte = (PINB & ((1<<PB0 | 1<<PB1)) << 1;

geschiftet nach links

also liegt dein KEY_2 danach auf Bit 1 und dein KEY_5 auf Bit 2

und passt in deine Lücke

Paul schrieb:
> #define KEY_1       0              // PA 0 - Taster 1
> #define KEY_3       7              // PA 3 - Taster 3
> #define KEY_4       5              // PA 5 - Taster 4

denn du benutztes ja nur 0 5 7 -> 1 2 waren frei, da liegen jetzt deine 
Tasten KEY_2 und KEY_5

musst halt nur
KEY_2 auf 1 abfragen
KEY_5 auf 2 abfragen

per #define

: Bearbeitet durch User
Autor: Karl M. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hi Joachim B.,

hatte wir schon versucht zu erläutern, hat er bisher leider nicht 
verstanden.

Evtl. schreibt jemand mal alles Komplett, dann ist es nur Copy & Paste.

Autor: Peter D. (peda)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Da der ATtiny ja eh fast nichts zu tun hat, kann man natürlich auch auf 
16 Bit erweitern, vorzugsweise mit einem typedef.
typedef uint16_t key_t;
volatile key_t key_state;
volatile key_t key_press;
volatile key_t key_rpt;
// ..
// ISR:
  key_t i = PINA | (PINB<<8);
// ..
key_t get_key_press(key_t key_mask)
Je nach typedef kann man so bis auf 64 Tasten erweitern.

Autor: Karl M. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Peter D. schrieb:
> Da der ATtiny ja eh fast nichts zu tun hat, kann man natürlich
> auch auf
> 16 Bit erweitern, vorzugsweise mit einem typedef.typedef uint16_t key_t;
> volatile key_t key_state;
> volatile key_t key_press;
> volatile key_t key_rpt;
> // ..
> // ISR:
>   key_t i = PINA | (PINB<<8);
> // ..
> key_t get_key_press(key_t key_mask)
> Je nach typedef kann man so bis auf 64 Tasten erweitern.

Super Peter,

als Ergänzung:

Die Taster an Port A: 0-7 erreicht man nun über die IDs 0-7 und
Die Taster an Port B: 0-7 erreicht man nun über die IDs 8-15 bei der 
Nutzung der Tastenenprellfunktionen.
Dies bezeichne ich dann auch als Mapping.

Deine Benennung deiner Taster KEY1 auf die realen PortPins ist dann eine 
weiteres Mapping!

Beispiel:
KEY_1 liegt auf Port A Bit 0
KEY_3 liegt auf Port A Bit 7

Um dann KEY_1 abfragen zu können, muss man welches Zuordnung verwenden?

Und etwas schwieriger, was gilt für KEY_3?

Autor: Nico W. (nico_w)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Man könnte auch das Einlesen und die Entprellroutine voneinander 
entkoppeln. Kostet ggf. ein paar Takte aber dann kann man Schließer und 
Öffner abbilden.

Autor: Karl M. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Nico W. schrieb:
> Man könnte auch das Einlesen und die Entprellroutine voneinander
> entkoppeln. Kostet ggf. ein paar Takte aber dann kann man Schließer und
> Öffner abbilden.

Warum? Das sucht der TO gar nicht.

Die Tastenentprell-Routine macht das auch automatisch!

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Mit einer Sache hast du Recht, die übung fehlt und das Verständnis für 
grosse oder komplizierte Codes. Da hilft wahrscheinlich keine 4 Wochen 
lernen. Könnte sich wahrscheinlich um Jahre handeln, falls überhaupt.
Allein der Code von Peter ist sehr komplex. Da hilft auch ein C Buch 
nicht allzu weit. Egal, mache weiter und versuche es zu verstehen. Wenn 
das nicht so klappt muss ich halt euch wieder fragen. Es ist 
wahrscheinlich nicht verkehrt wenn ihr auch etwas mehr Hilfe kommt. Ist 
sehr hilfreich wenn man einen Code hat der läuft und diesen dann 
auseinander nehmen kann um die Funktion zu begreifen und weiter 
zuentwickeln.
Egal, mache weiter und hoffe das auch mal bei mir funktioniert.
LG Paul

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Joachim B. schrieb:
> denn du benutztes ja nur 0 5 7 -> 1 2 waren frei, da liegen jetzt deine
> Tasten KEY_2 und KEY_5
>
> musst halt nur
> KEY_2 auf 1 abfragen
> KEY_5 auf 2 abfragen
>
> per #define

das mit geschiftet habe ich verstanden

Joachim B. schrieb:
> also uint8_t hilfsbyte = (PINB & ((1<<PB0 | 1<<PB1)) << 1;
>
> geschiftet nach links
>
> also liegt dein KEY_2 danach auf Bit 1 und dein KEY_5 auf Bit 2

meine Tasten liegen dann auf 7 5 2 1 0
Habe im Netz nach mapping gesucht. Es gibt die verschiedensten Begriffe 
und Anwendungen dazu. Leider führt keine Quelle zum Ziel.
Sorry, komme nicht weiter. Die gezeigten Beispiel bringen etwas Licht 
ins Dunkel, leider fehlt noch viel.

Autor: Peter D. (peda)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> Allein der Code von Peter ist sehr komplex. Da hilft auch ein C Buch
> nicht allzu weit.

Vor allem sollte man sich mal mit den Zahlensystemen und den logischen 
Operatoren beschäftigen.
Die CPU rechnet intern ausschließlich binär und ein Byte besteht aus 8 
Bit.
Logische Operatoren (AND, OR, XOR, Schieben) arbeiten immer auf 
Bitebene.
Zum besseren Verständnis kann man mit dem Windows-Taschenrechner üben.
Allerdings nicht mit der kastrierten Version von W10, sondern mit dem 
Microsoft Rechner-Plus.
Das Schieben von Konstanten erfolgt schon zur Compilezeit, kostet also 
keinen Code. Wenn dadurch ein Ausdruck besser verstehbar wird, sollte 
man es gegenüber magischen Zahlen immer vorziehen.
Auch sollte man Bitwerte nie dezimal hinschreiben. Entweder in hex oder 
binär. Oktal würde ich nicht mehr verwenden.

Autor: Theor (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> Joachim B. schrieb:
>> [...]
>> also liegt dein KEY_2 danach auf Bit 1 und dein KEY_5 auf Bit 2
>
> meine Tasten liegen dann auf 7 5 2 1 0

Wenn Du Joachims Satz nochmal betrachten willst, könnte man den Satz so 
formulieren.
"Deine Tasten liegen auf den Bits mit den Nummern 7, 5, 2, 1 und 0."

> Habe im Netz nach mapping gesucht. Es gibt die verschiedensten Begriffe
> und Anwendungen dazu. Leider führt keine Quelle zum Ziel.
> Sorry, komme nicht weiter. Die gezeigten Beispiel bringen etwas Licht
> ins Dunkel, leider fehlt noch viel.

Es geht um Zuordnungen. "Mapping" heisst in diesem Zusammenhang 
"Zuordnung".
Eine sehr häufig vorkommende Tätigkeit beim Programm- und 
Schaltungsentwurf und auch Operation in Programmen.

Zugeordnet werden einander immer mindestens zwei Elemente.
In Deinem Fall z.B. die Tasten einer Bitnummer im Port.
Aber auch Deine Tasten einer Bitnummer in der Variablen i (in dem obigen 
Code).
Wichtig ist in diesem Zusammenhang der Vergleich dieser beiden 
Zuordnungen.  (Erstmal für Dich zum (Teil-) Verständnis der Funktion).

In der Mathematik heisst eine Zuordnung "Abbildung" - eine andere 
Übersetzung von "Mapping". Kennst Du vielleicht.

Autor: Paul (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Versuche es zu verstehen.
Zuordnung bedeutet also in seiner Grundform, das ich durch ein Programm 
eine taste an einen bestimmten PIN/PORT anschliesse und damit einem 
bestimmten Bit in einem Byte zuordne.
Beispiel:
PUEA=0b10100001;
in diesem Fall ordne ich dem Register PUE A, vertreten durch das Byte, 
dem Bit 0,5,7 eine 1 zu. Dadurch schalte ich mit dem Register 
entsprechende Widerstände von Vcc ein. Dadurch wird der Wert des PINS 
auf Vcc gelegt und durch den Taster nach GND gezogen und eine eindeutige 
zuordnung vorgenommen.

Theor schrieb:
> Aber auch Deine Tasten einer Bitnummer in der Variablen i (in dem obigen
> Code).
Da ich verschiedene PIN/Porteingänge nutze (für die einzelnen Taster) 
ergibt sich das Bitmuster

Theor schrieb:
> "Deine Tasten liegen auf den Bits mit den Nummern 7, 5, 2, 1 und 0."


Theor schrieb:
> Aber auch Deine Tasten einer Bitnummer in der Variablen i (in dem obigen
> Code).

In der Variablen i sind als erstes die Bits 7 5 2 belegt.
Wenn ich eine Taste betätige auf 1 und sonst 0?
Danach wird nach links geschiftet. Bedeutet das ich die Werte von PB? um 
eine Stelle nach links schiebe. Wenn das so ist und alle Tasten gedrückt 
werden ergibt sich für die Variable i (8 Bit) der Wert 0b10100111.

Sorry, das ist für mich lautgedacht und folge den Ausführungen an 
Beispielen. Falls Fehler drin sind bitte sofort mit Kritik kommen.

Autor: Theor (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Paul schrieb:
> Versuche es zu verstehen.
> Zuordnung bedeutet also in seiner Grundform, das ich durch ein Programm
> eine taste an einen bestimmten PIN/PORT anschliesse und damit einem
> bestimmten Bit in einem Byte zuordne.

Nein. Oder allenfalls "jein" mit viel Kopfwackeln.
Zuordnung bedeutet ganz allgemein, eine Beziehung zwischen zwei Dingen.

Ich halte es nicht für nützlich an dieser Stelle allzu tief in 
philologische Überlegungen zu gehen.

Eine Zuordnung ist im wesentlichen etwas, was in Deinem Kopf oder auf 
dem Papier stattfindet. Ein abstrakter Vorgang, nichts Reales. Das diese 
Zuordnung oft auch eine physische, reale Entsprechung hat ist nicht 
notwendig, damit es sich um eine Zuordnung handelt.
Man unterscheidet mehr oder weniger streng zwischen der Zuordnung und 
der Handlung oder dem realen Objekt, dass diese Zuordnung repräsentiert.

Siehe auch: https://de.wikipedia.org/wiki/Zuordnung . Dort ist das 
lediglich sozusagen eine Idee, eine gedankliche Konstruktion. Klar?

> Beispiel:
>
> PUEA=0b10100001;
> 
> in diesem Fall ordne ich dem Register PUE A, vertreten durch das Byte,
> dem Bit 0,5,7 eine 1 zu.

Nein. Das ist eine Zuweisung in einem Programm.

Die Zuordnung entsteht entweder im Vorhinein, wenn Du einen Prozessor 
entwirfst, oder im Nachhinein, wenn Du die Wirkung dieser Anweisung 
beobachtest.

> Dadurch schalte ich mit dem Register
> entsprechende Widerstände von Vcc ein. Dadurch wird der Wert des PINS
> auf Vcc gelegt und durch den Taster nach GND gezogen und eine eindeutige
> zuordnung vorgenommen.

Nein. Siehe oben.

> Theor schrieb:
>> Aber auch Deine Tasten einer Bitnummer in der Variablen i (in dem obigen
>> Code).
> Da ich verschiedene PIN/Porteingänge nutze (für die einzelnen Taster)
> ergibt sich das Bitmuster

Ja.

> Theor schrieb:
>> "Deine Tasten liegen auf den Bits mit den Nummern 7, 5, 2, 1 und 0."
>
>
> Theor schrieb:
>> Aber auch Deine Tasten einer Bitnummer in der Variablen i (in dem obigen
>> Code).
>
> In der Variablen i sind als erstes die Bits 7 5 2 belegt.
Was meinst Du mit "belegt"?
Was ich meinte, war die Zuordnung von Tasten zu Bitnummern. Nicht 
weniger, aber auch nicht mehr. :-)

> [...]

Der Punkt ist, dass Du aus den Operationen die Zuordnungen von den 
realen Tasten zu den Bitnummern erkennen kannst. Und umgekehrt, aus der 
Zuordnung der realen Tasten zu den gewollten Bitnummern die dazu nötigen 
Operationen. Das ist alles.

Autor: Theorie (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo

Das ist zwar eine sehr schöne theoretische Abhandlung, bring the aber 
den TO keinen Schritt der Lösung näher.

Autor: Veit D. (devil-elec)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Paul schrieb:
>
> #define KEY_1       0              // PA 0 - Taster 1
> #define KEY_2       0              // PB 0 - Taster 2
> 
> KEY_1 ist doch PORTA - PA0
> KEY_2 ist doch PORTB - PB0
> zugeordnet.


Das Problem besteht gedanklich. Das KEY_1 an Port A hängt und KEY_2 an 
Port B weißt nur du. Das Programm weiß das nicht. Für das Programm ist 
KEY_1 ein Wert 0 und KEY_2 ein Wert 0. Du verwendest beide beim Bit 
schieben als Wertigkeit. Damit landen beide Bits auf dem gleichen Bit, 
nämlich Bit 0. Dadurch kannst du sie nicht unterscheiden.

Du kannst das mittels Offset wie ich sagte und Peter schon zeigte 
korrigieren. Nur mir persönlich gefällt der gesamte define und 
Korrekturwahnsinn überhaupt nicht. Das ist viel zu Fehleranfällig. 
Merkste ja selbst.

Deswegen ein Vorschlag der wenig Spielraum für Fehler hat. Ungetestet, 
kompiliert jedoch mit C Compiler. Wenn Grundprinzip verstanden wurde ist 
es ausbaufähig. Warum C keine Konstante für die Indexgröße mag weiß ich 
nicht. Vielleicht kann das jemand erklären?
#include <avr/io.h>

//const uint8_t ANZAHLTASTER = 5;  // funktioniert leider nicht "variably modified 'tasterStatus' at file scope"
#define ANZAHLTASTER 5
// Indexreihenfolge wie KEY Nummerrierung
const uint8_t tasterPortBit [ANZAHLTASTER] = {0, 0, 7, 5, 1};
volatile uint8_t const *tasterRegPIN  [ANZAHLTASTER] = {&PINA, &PINB, &PINA, &PINA, &PINB};

uint8_t tasterStatus [ANZAHLTASTER] = {0};


void updateTaster();


int main(void)
{
    // mit Pullups einmalig einlesen zur "Initialisierung"

    while (1) 
    {
        // zyklisch aufrufen
        updateTaster();
    }
}


void updateTaster()
{
    for (uint8_t i=0; i<ANZAHLTASTER; i++)
    {
        tasterStatus[i] = *tasterRegPIN[i] >> tasterPortBit[i] & 1;
    }
}

Autor: neuer PIC Freund (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Allein der Code von Peter ist sehr komplex.

Vielleicht etwas abseits zur Fragestellung, aber zur Anschauung recht 
gut:
                              KEY_PIN     i           ct0         ct1         key_state   key_press
initial values                            00000000    00000000    00000000    00000000    00000000 
i = key_state ^ ~KEY_PIN      11111111    00000000    00000000    00000000    00000000    00000000 
ct0 = ~(ct0 & i)              11111111    00000000    11111111    00000000    00000000    00000000 
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000000 
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000000 
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000000 
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000000 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000000 
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000000 
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000000 
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000000 
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000000 
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000000 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000000 
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000000 
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000000 
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000000 
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000000 
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000000 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000001    11111111    11111111    00000000    00000000 
ct0 = ~(ct0 & i)              11111110    00000001    11111110    11111111    00000000    00000000 
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111110    11111111    00000000    00000000 
i &= ct0 & ct1                11111110    00000000    11111110    11111111    00000000    00000000 
key_state ^= i                11111110    00000000    11111110    11111111    00000000    00000000 
key_press |= key_state & i    11111110    00000000    11111110    11111111    00000000    00000000 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000001    11111110    11111111    00000000    00000000 
ct0 = ~(ct0 & i)              11111110    00000001    11111111    11111111    00000000    00000000 
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111111    11111110    00000000    00000000 
i &= ct0 & ct1                11111110    00000000    11111111    11111110    00000000    00000000 
key_state ^= i                11111110    00000000    11111111    11111110    00000000    00000000 
key_press |= key_state & i    11111110    00000000    11111111    11111110    00000000    00000000 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000001    11111111    11111110    00000000    00000000 
ct0 = ~(ct0 & i)              11111110    00000001    11111110    11111110    00000000    00000000 
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111110    11111110    00000000    00000000 
i &= ct0 & ct1                11111110    00000000    11111110    11111110    00000000    00000000 
key_state ^= i                11111110    00000000    11111110    11111110    00000000    00000000 
key_press |= key_state & i    11111110    00000000    11111110    11111110    00000000    00000000 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000001    11111110    11111110    00000000    00000000 
ct0 = ~(ct0 & i)              11111110    00000001    11111111    11111110    00000000    00000000 
ct1 = ct0 ^ (ct1 & i)         11111110    00000001    11111111    11111111    00000000    00000000 
i &= ct0 & ct1                11111110    00000001    11111111    11111111    00000000    00000000 
key_state ^= i                11111110    00000001    11111111    11111111    00000001    00000000 
key_press |= key_state & i    11111110    00000001    11111111    11111111    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111110    00000000    11111111    11111111    00000001    00000001 
ct0 = ~(ct0 & i)              11111110    00000000    11111111    11111111    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111110    00000000    11111111    11111111    00000001    00000001 
i &= ct0 & ct1                11111110    00000000    11111111    11111111    00000001    00000001 
key_state ^= i                11111110    00000000    11111111    11111111    00000001    00000001 
key_press |= key_state & i    11111110    00000000    11111111    11111111    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000001    11111111    11111111    00000001    00000001 
ct0 = ~(ct0 & i)              11111111    00000001    11111110    11111111    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111110    11111111    00000001    00000001 
i &= ct0 & ct1                11111111    00000000    11111110    11111111    00000001    00000001 
key_state ^= i                11111111    00000000    11111110    11111111    00000001    00000001 
key_press |= key_state & i    11111111    00000000    11111110    11111111    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000001    11111110    11111111    00000001    00000001 
ct0 = ~(ct0 & i)              11111111    00000001    11111111    11111111    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111111    11111110    00000001    00000001 
i &= ct0 & ct1                11111111    00000000    11111111    11111110    00000001    00000001 
key_state ^= i                11111111    00000000    11111111    11111110    00000001    00000001 
key_press |= key_state & i    11111111    00000000    11111111    11111110    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000001    11111111    11111110    00000001    00000001 
ct0 = ~(ct0 & i)              11111111    00000001    11111110    11111110    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111110    11111110    00000001    00000001 
i &= ct0 & ct1                11111111    00000000    11111110    11111110    00000001    00000001 
key_state ^= i                11111111    00000000    11111110    11111110    00000001    00000001 
key_press |= key_state & i    11111111    00000000    11111110    11111110    00000001    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000001    11111110    11111110    00000001    00000001 
ct0 = ~(ct0 & i)              11111111    00000001    11111111    11111110    00000001    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000001    11111111    11111111    00000001    00000001 
i &= ct0 & ct1                11111111    00000001    11111111    11111111    00000001    00000001 
key_state ^= i                11111111    00000001    11111111    11111111    00000000    00000001 
key_press |= key_state & i    11111111    00000001    11111111    11111111    00000000    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
---intcall end -----------------
i = key_state ^ ~KEY_PIN      11111111    00000000    11111111    11111111    00000000    00000001 
ct0 = ~(ct0 & i)              11111111    00000000    11111111    11111111    00000000    00000001 
ct1 = ct0 ^ (ct1 & i)         11111111    00000000    11111111    11111111    00000000    00000001 
i &= ct0 & ct1                11111111    00000000    11111111    11111111    00000000    00000001 
key_state ^= i                11111111    00000000    11111111    11111111    00000000    00000001 
key_press |= key_state & i    11111111    00000000    11111111    11111111    00000000    00000001 
---intcall end -----------------

Setze fast nur noch Peter D. sein Code ein. Läuft. Und mal Danke an der 
Stelle.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Könnte man nicht auch:

#define Key_2 0

#define Key2_g (Key_2<<1)
#define Key5_g (Key_5<<1)

Und dann mit den geänderten defines für Key2 und Key5 weiterarbeiten?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul



Paul schrieb:
> uint8_t i;
>   TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);
>   i = PINA & (1<<PINA0 | 1<<PINA5 | 1<<PINA7);
>   i |= (PINB & ((1<<PINB0 | 1<<PINB1)) << 1);

da hast Du u.a. einen Fehler - Du musst dieses shiften mit einer anderen 
Hilfsvariablen machen:

uint8_t i;
uint8_t k;
k = PINA & (1<<PINA0 | 1<<PINA5 | 1<<PINA7);
k|= (PINB & ((1<<PINB0 | 1<<PINB1)) << 1);

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

i = key_state ^ ~k;   /* Deine neue "Hilfsvariable" */

ALL_KEYS wird eh' nur im main() verwendet - das kann man auf die 
einzelnen Ports aufspalten

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Martin
habe deinen Code eingegeben. Leider wird dabei die Taste 2 (KEY2-PB0) 
vollkommen vergessen. Egal ob ich KEY2 verwende, es funktioniert nur 
Taste 1.
Kann es sein das nur i-->k sonst das selbe ist?

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo PIC
da hast du dir ja richtig Arbeit gemacht

neuer PIC Freund schrieb im Beitrag #6033894:
> i = key_state ^ ~KEY_PIN      11111111    00000000    11111111
> 11111111    00000000    00000001

Wenn ich bisher richtig verstanden habe ist i das Abbild der Taster die 
Betätigt werden. Bei KEY_PIN unterscheidest du nur 11111111 oder 
11111110. Benutzt du in diesem Fall nur 1 Taster?
Bisher hat der Code von Peter wunderbar funktioniert, leider bisher ...

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:
> da hast Du u.a. einen Fehler - Du musst dieses shiften mit einer anderen
> Hilfsvariablen machen:

Warum denn?
k wird nach der Zuweisung zu i nie wieder benötigt, daher kannst Du auch 
gleich i nehmen.
Der Compiler merkt das eh, also wird er exakt den gleichen Code 
erzeugen.

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter
komme leider überhaupt nicht weiter. Versuche deinen Code mit Anleitung 
zu verstehen. Ist einfach eine Nummer zu gross für mich. Habe auch 
versucht den ersten Teilen zu folgen. Wird nichts.

Peter D. schrieb:
> Das ist jetzt keine Raketenwissenschaft, nur ein Bit überlappt sich.
> In der ISR die 5 Bits in ein Byte einsammeln:  uint8_t i = PINA &
> (1<<PA0 | 1<<PA5 | 1<<PA7);
>   i |= (PINB & ((1<<PB0 | 1<<PB1)) << 1;

Wie kann es sein, wenn ich in der ISR die 5 Bits in einem Byte einsammle 
ein Taster vollkommen ignoriert wird?

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter D.

Es ist richtig, dass die Hilfsvariable k nicht zwingend nötig ist, aber 
so eine " Entzerrung " des Codes ist häufig hilfreich.

Das entscheidende ist aber, dass Paul die Zeile
" i = key_state ^ ~ k"
NICHT in seinem Code hatte - oder ist diese Zeile obsolet??

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul

Wenn möglich, lege die 5 Taster auf EINEN Port, dann dürfte es 
wesentlich leichter sein, die SW zum laufen zu bringen

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:
> Wenn möglich, lege die 5 Taster auf EINEN Port, dann dürfte es
> wesentlich leichter sein, die SW zum laufen zu bringen

und wenn es nicht möglich die Tasten auf einen Port zu legen so kann man 
alle Port Bits in ein Byte shiften wie gezeigt.

Wer es selber durchdenkt findet die Lösung auch ohne die ganze 
Entprellroutine zu verstehen, wer lernen will macht dort weiter!

Die KEY Abfrage muss ja nicht zwingend die Bits an PA und PB abbilden, 
die Bits an PA und PB werden gelesen in ein Hilfsbyte geschoben und dort 
werden die Key Bits abgefragt, entprellt,

"VÖLLIG LOSGELÖST VON DEN PORTS" .........

: Bearbeitet durch User
Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joachim B.

Alles schön und gut was Du da schreibst, wenn es aber dem TO 
offensichtlich nicht weiter hilft und es eine bessere Lösung durch 
verlegen der Taster auf einen Port gibt - warum nicht diesen Weg gehen 
als an einer nicht funktionierenden SW zu verzweifeln?

Oder kannst Du ihm eine copy&Paste Lösung präsentieren??

Autor: Theor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja.

Das Auffällige ist, dass die Lösung, ausgehend von Peters Vorschlag hier 
Beitrag "Re: Taster Entprellung am Attiny 841 und Auswertung" eigentlich nur noch 
minimale Transferleistung erfordert.
Dazu ist ihm auch noch die Bedeutung einer "Zuordnung" (von Martin als 
"Mapping" in die Diskussion eingeführt, aber auch und sogar als 
Zuordnung paraphrasiert) ziemlich ausführlich und mehrfach erklärt und 
sogar das Ergebnis mitgeteilt worden.

Man kann darüber streiten, was eine "minimale" Transferleistung ist, 
aber wir sind uns vermutlich ziemlich einig, dass es lediglich darum 
geht ein Bit, durch eine Schiebeoperation und eine logische Verknüpfung 
hindurch zu verfolgen und sein resultierende Position auszumauchen.

Auch das ist ihm von Walter (wenn ich nicht irre), nach einigen 
Schleifen, mehr oder weniger auf dem Silbertablett serviert worden.

Wie schon von jemandem erwähnt, ist ein vollständiges Verständnis dieser 
vertikalen Zählergeschichte für die Problemlösung eigentlich nicht 
notwendig. Man muss "lediglich" (auch das ist diskutabel) abgrenzen 
können, wo eigentlich der Test auf eine bestimmte Taste stattfindet, und 
welche Variablen da verglichen werden. Man muss eigentlich nur eine Idee 
von Datenfluss haben und davon ein mentales Bild entwerfen können.

Nicht genug damit, hat sich neuer Pic-Freund die Mühe gemacht, jeden 
einzelnen Schritt tabellarisch auszuführen und hinzuschreiben. (Aus dem 
alten AVR-Freaks-Thread kopiert? Egal.)

Aber trotz dieser mehrfachen Versuche, Paul Denkanstöße zu geben, 
unternimmt er offenbar keine eigenen Versuche, geht nicht das Risiko von 
Fehlern ein, sondern will jeden einzelnen Schritt, ob Veränderung im 
Code oder Schlussfolgerung, von uns bestätigt haben. Es scheint mir, wie 
schon erwähnt, auch so, als wenn er von der Sache insgesamt keine 
umfassendere Vorstellung hat. Es geht immer um triviale Details, in 
denen er sich verliert, weil er nichts hat, in das er sie einordnen 
könnte.

Es wird wohl nichts weiter übrig bleiben als entweder den Code für ihn 
zu schreiben oder, in Anbetracht der Tatsache, dass er ein großes, aus 
mehreren Einzelprojekten bestehendes Vorhaben realisieren will, mit dem 
wir dann die nächsten Monate in ähnlicher Weise beschäftigt werden, (wer 
hier will das?) eine Grenze ziehen und sagen:
OK. Wir helfen Dir hier, Dir selbst zu helfen. Aber wenn Du keine 
Anstrengungen unternimmst, oder einfach nicht fähig bist, solche 
Leistungen zu vollbringen, dann ist hier Schluss.

In gewisser Weise handelt es sich vielleicht darum, dass Paul zuviel auf 
einmal will und gewisse frühere Schritte (Bitmanipulationen etc.) nicht 
oder zuwenig geübt hat. Da er nicht von unten aufbaut, steht er in einem 
Wust von Einzelheiten, die sich nicht zusammenfügen.

Auffällig ist auch, dass er nie irgendeinen Ansatz von Analyse vorträgt. 
Es geht nur immer nicht. Warum, oder was jedenfalls eine Ursache sein 
könnte , davon hat er nicht die geringste Vorstellung - oder er 
äussert sie jedenfalls nicht.

Wie siehst Du das, Paul? Könnte da was dran sein?

Vermutlich hättest Du gerne, dass man Dir den Code fertig hinschreibt. 
Aber hast Du Verständnis dafür, dass man erwartet, dass Du Dir selbst 
hilfst? Bist Du bereit, diese Anstrengung auf Dich zu nehmen? Willst Du 
lernen? Richtig hart lernen und das die ganze Zeit, während Du an Deinem 
Projekt arbeitest?

Autor: Karl M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Theor schrieb:
> Naja.
>
> Das Auffällige ist, dass die Lösung, ausgehend von Peters Vorschlag hier
> Beitrag "Re: Taster Entprellung am Attiny 841 und Auswertung" eigentlich
> nur noch  minimale Transferleistung erfordert.

Grosses Lob für die Zusammenfassung. Ja wirklich.
Ich denke alle Anregungen nun auf dem Tisch, jetzt braucht es nur noch 
Zeit, dass Paul sie verarbeitet.

Die sollten wir ihm nun geben und diesen Thread schließen.

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:
> Das entscheidende ist aber, dass Paul die Zeile
> " i = key_state ^ ~ k"
> NICHT in seinem Code hatte - oder ist diese Zeile obsolet??

Da hast Du natürlich recht, ohne diese Zeile ist der Code Nonsens.
Meine Zeilen sollten nur das Einlesen von KEY_PIN verdeutlichen und 
nicht die weitere Verarbeitung ersetzen.

Ich bin mal gespannt, wie er den weitaus komplizierteren Brocken 
bewältigt, ein zuverlässiges I2C-Protokoll zu entwickeln.

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter
das mit dem I2C Protokoll ist bereits gelöst. Habe verschiedene Teile 
mit dem Bus und einem Atmega 128 verbunden. Auch die Verbindung zwischen 
einem Ati841 und dem Atmega128 läuft bereits in beide Richtungen. Auch 
der AC und ADC vom Ati841 laufen sehr gut.
Fehlt einfach nur die Tastenentprellung. Mal heute abend schauen wie ich 
es machen kann.
Paul

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schliesst diesen Thread bitte nicht zu schnell. Gibt sicher noch Problem 
mit diesem Code.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Paul schrieb:
> Hallo Peter
> Habe verschiedene Teile
> mit dem Bus und einem Atmega 128 verbunden. Auch die Verbindung zwischen
> einem Ati841 und dem Atmega128 läuft bereits in beide Richtungen. Auch
> der AC und ADC vom Ati841 laufen sehr gut.
> Paul

Hast Du nicht erst vor kurzem noch mit dem ADC / Comparator gekämpft 
weil Du eine falsche Pin Belegung hattest? Und das funktioniert jetzt??

Und hast Du mal Taster vom Attiny841 eingelesen, per Bus an den Master 
geschickt und dieser ein Signal an den Attiny geschickt, damit dieser 
eine LED ansteuert wenn der Taster betätigt wird?
Dafür (1 Taste einlesen) musste aber das Entprellen ja schon machen 
können

Martib

Autor: Thomas S. (thschl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul,
habe jetzt nicht alles durchgelesen aber wenn du 2 Ports verwendest, 
wäre es für dich sinnvoll alles auch 2fach zu programmieren

also

#define KEY_1_A       0              // PA 0 - Taster 1
#define KEY_3_A       7              // PA 3 - Taster 3
#define KEY_4_A       5              // PA 5 - Taster 4

#define KEY_2_B       0               // PB 0 - Taster 2
#define KEY_5_B       1               // PB 1 - Taster 5

#define ALL_KEYS_A  -- fuer Port A 
#define ALL_KEYS_B  -- fuer Port B

#define REPEAT_MASK_A  -- fuer Port A 
#define REPEAT_MASK_B  -- fuer Port B 

dann entsprechend zuweisen, damit weisst du was wo benutzt wird

: Bearbeitet durch User
Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin schrieb:
> Oder kannst Du ihm eine copy&Paste Lösung präsentieren??

könnte ich, aber

Theor schrieb:
> ausgehend von Peters Vorschlag hier
> Beitrag "Re: Taster Entprellung am Attiny 841 und Auswertung" eigentlich
> nur noch
> minimale Transferleistung erfordert.

wenn Paul sich einfach mal klarmacht das er Tasten an 2 Ports 
angeschlossen abfragt

#define KEY_portA_1       0    // PA 0 - Taster 1
#define KEY_portA_3       7    // PA 3 - Taster 3
#define KEY_portA_4       5    // PA 5 - Taster 4

#define KEY_portB_2       0    // PB 0 - Taster 2
#define KEY_portB_5       1    // PB 1 - Taster 5

dabei 2 Bits an A und B die selbe Bitnummer haben
#define KEY_1       0          // PA 0 - Taster 1
#define KEY_2       0          // PB 0 - Taster 2

auch sehr unglücklich sind die verschiedensten Nummern BIT und TASTE, 
warum tut man sich das an?

Portabfrage
#define KEY_LINKS_PORTA   0    // PA 0 - Taster links
#define KEY_RECHTS_PORTA  3    // PA 3 - Taster rechts
#define KEY_ENTER_PORTA   5    // PA 5 - Taster enter

#define KEY_DOWN_PORTB    0    // PB 0 - Taster down
#define KEY_UP_PORTB      1    // PB 1 - Taster up

schon sind diese verwirrenden Nummern weg!

er diese einfach in der KEY Abfrage umbenennt

#define KEY_read_links    0  // wie Port Hilfsbyte Bit 0 - Taster links
#define KEY_read_rechts   3  // wie Port Hilfsbyte Bit 3 - Taster rechts
#define KEY_read_rechts   5  // wie Port Hilfsbyte Bit 5 - Taster enter

und in der KEY Abarbeitung eigentlich andere Bits nutzt durch shiften

#define KEY_read_down    1 // nach shiften Hilfsbyte Bit 1-Taster down
#define KEY_read_up      2 // nach shiften Hilfsbyte Bit 2-Taster up

: Bearbeitet durch User
Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das stimmt, habe bis vor kurzem mit dem ADC und AC gekämpft. Der 
entscheidende Hinweis kam von Peter. Danach lief alles ohne Flackern. 
Die Pin Belegung war soweit korrekt, hatte in einem Register etwas nicht 
eingeschaltet (Sorry, kann gerade nicht in das Programm schauen)mit dem 
negativ einschalten.
Ja, ich habe ein Signal vom Master zum Slave geschickt und eine LED 
angesteuert und einen Taster Zustand ausgelesen. Habe nur die einfache 
Version gewählt und es hat funktioniert.
Die Tasterentprellung von Peter habe ich bereits in anderen Programmen 
verwendet und dabei so ziemlich alle Version gemacht die das Programm so 
macht.
Hatte aber noch nie das die Taster auf 2 Ports verteilt sind und sich 2 
Taster stören.

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe nichts gegen lernen. Habe mir schon viel erarbeitet und angewendet. 
Dazu zählen auch teilweise recht komplizierte Teile. Manche Sachen habe 
ich allein begriffen, bei manchen Teilen habe ich um Rat gefragt. 
Teilweise sind es einfach Kleinigkeiten, manchmal sind es einfach Sachen 
die ich nicht begriffen habe. Deswegen werde ich auf jeden Fall 
weitermachen. Manche Projekte sind aus mehreren Sachen zusammengebaut 
und funktionieren super. Ist alles vertreten.
LG Paul

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joachim B.

Großes Lob und "thumbs up" :-)

Du hast recht - mit Deinem letzten Beitrag sollte Paul eigentlich (!!) 
in der Lage sein, dieses Entprellen für 2 Ports hin zu bekommen.

Wenn aber jemand nur die Grundrechnungsarten beherrscht darf er sich 
nicht wundern, wenn er bei höherer Mathematik scheitert - es sei denn, 
er ist Willens, sich weiter zu bilden ;-)

Beitrag #6036014 wurde vom Autor gelöscht.
Autor: Egonwalter M. (heiner1234)
Datum:
Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
Hallo Paul

Ich hab' mal versucht, ein (hoffenlich!) funktionsfähiges Programm zu
erstellen aus Deinen und den anderen Beiträgen.

Testen kann ich's nicht da keine HW vorhanden, ich konnte es nicht mal
compilieren, da mein AVRSTudio 418 keinen Attiny841 kennt...

Hilfe zur Selbsthilfe ist gut, aber manchmal hilft es auch ein
bestehendes Programm "auseinanderzunehmen", um es zu verstehen.
Und wenn man sieht, dass jemand wirklich nicht weiterkommt ....

Würde mich freuen, wenn's funktioniert.

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Egonwalter M. schrieb:
> Hilfe zur Selbsthilfe ist gut, aber manchmal hilft es auch ein
> bestehendes Programm "auseinanderzunehmen", um es zu verstehen.
> Und wenn man sieht, dass jemand wirklich nicht weiterkommt ....

Vielen Dank an Egonwalter M.
habe dein Programm gerade gesehen. Bin dabei es auf den Attiny zu 
bringen.
Deine Meinung kann ich vollkommen unterstützen. Wenn ein Programm ohne 
Probleme läuft hat man einen Code ohne Fehler. Dann kann man damit 
beginnen ihn auseinder zu nehmen und genau schauen wie andere es machen. 
Im ersten überblick muss ich wirlich sagen das ich staune. Es waren 
bereits Hinweise und gute Ansätze dabei, teilweise fast fertig. Hatte 
auch angefangen etwas damit zu machen. Leider habe ich auch ansatzweise 
nicht soweit gedacht.
Egal ob mich manche Leute blöd finden, bedanke ich mich trotzdem für die 
Hilfe und Geduld.
LG Paul

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe den Code jetzt auf dem Ati841 drauf. Ein paar kleine Sachen waren 
dran, habe alles gefunden und korregiert
while(1) 
      {                      // Programmschleife while
      //if(get_key_press(1<<KEY_DOWN_PORTB))  // Taster 2
       if(get_key_press(1<<KEY_LINKS_PORTA))  // Taster 1
       //if(get_key_press(1<<KEY_RECHTS_PORTA))  // Taster 3
       //if(get_key_press(1<<KEY_ENTER_PORTA))  // Taster 4
       //if(get_key_press(1<<KEY_UP_PORTB))  // Taster 5
        
        {  // nur Taste press
        /*  if(get_key_press(1<<(KEY_read_down >>1))) {   falls obige Zeile nicht fkt!! */    
        PORTB &= ~(1<<PINB2);        // 3+4,4+5// LED an
        }
      
      if(get_key_press(1<<KEY_DOWN_PORTB))  // Taster 2
      //if(get_key_press(1<<KEY_LINKS_PORTA))  // Taster 1
      //if(get_key_press(1<<KEY_RECHTS_PORTA))  // Taster 3
      //if(get_key_press(1<<KEY_ENTER_PORTA))  // Taster 4
      //if(get_key_press(1<<KEY_UP_PORTB))  // Taster 5
    
        {                    // nur Taste press  
        PORTB |= (1<<PINB2);        // LED aus
        }
      }                    // Ende while
habe zum testen die verschiedenen Kombinationen eingegeben.
Alles mit Taster 2 und/oder zu tun hat geht nicht. Bei der oberen 
Kombination kann ich mit Taster 1 ein und wieder ausschalten, wobei 
Taster 2 keine Funktion hat.

Autor: Egonwalter M. (heiner1234)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul

Lass mal die ganze Entprellsache weg und versuche mal das Programm ohne 
zu testen - also:
-  nur mit jeweils einem Taster (Taster 1 bis Taster 5) eine LED an/aus 
zuschalten und check mal, ob da Taster 2 fkt.

Funktioniert Dein Taster 2 überhaupt?

Du kannst ja - ohne Entprellroutine - mal testen: mit Taster1 eine LED 
ein, mit Taster2 diese wieder aus.

: Bearbeitet durch User
Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe mir schnell ein kleines Programm geschrieben mit dem ich die 
Ausgänge testen kann. Damit kann ich die Tasten schalte und die LED 
ein/aus. Auch die Taste 2 funktioniert damit ohne Probleme

Autor: Egonwalter M. (heiner1234)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul

Also - Taste 2 fkt problemlos, wenn die Entprellroutine NICHT 
implementiert ist ....

hm ...

aber Taste 5 fkt wiederum problemlos, wenn die Entprellroutine 
implementiert ist ... beide Tasten liegen ja auf PORTB und beide Tasten 
werden in der Entprellroutine um 1 nach links geschoben und zur 
Variablen k  addiert ...

hm ...

muss mal in mich gehen ...

probier mal mit:
KEY_read_down anstatt KEY_DOWN_PORTB in der main:
...
while(1) {            // Programmschleife while
    if(get_key_press(1<<KEY_read_down)) {

denn in der Entprellroutine verwenden wir ja:
REPEAT_MASK 
(1<<KEY_read_links|1<<KEY_read_rechts|1<<KEY_read_enter|1<<KEY_read_down 
|1<<KEY_read_up)

: Bearbeitet durch User
Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich geändert. Jetzt reagiert Taste 5 ein/aus

Autor: Egonwalter M. (heiner1234)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Taste 5 hat aber doch vorher schon reagiert...

Taste 2 reagiert also immer noch nicht?

Versteh' ich nicht ...

in der Variablen k (TIMER ISR) ist die Info, dass PINB0 und PINB1 um 1 
nach links geschoben sind:
BIT 0 = PA 0 - Taster links     Taster 1
BIT 1 = PB 0 - Taster down    Taster 2
BIT 2 = PB 1 - Taster up    Taster 5
BIT 5 = PA 5 - Taster enter    Taster 4
BIT 7 = PA 7 - Taster rechts    Taster 3

dies findet sich auch in REPEAT_MASK wieder - also "rechnet" die TIMER 
ISR mit den geshifteten Werten ...
d.h  key_state und key_press arbeitet auch mit den geshifteten Werten 
...

die "Auswertefunktionen" wie z.B get_key_press arbeitet auch mit den 
geshifteten Werten ...wenn ich dann bei diesen Funktionen als Parameter 
KEY_read_down angebe, müßte eigentlich Taster 2 derjenige sein, der die 
LED anmacht ....

: Bearbeitet durch User
Autor: Egonwalter M. (heiner1234)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul

Paul schrieb:
> Habe den Code jetzt auf dem Ati841 drauf. Ein paar kleine Sachen
> waren dran, habe alles gefunden und korregiert

was hast Du korrigiert?

zur Abfrage in der main():

BIT 0 = PA 0 - Taster links     Taster 1  KEY_LINKS_PORTA
BIT 1 = PB 0 - Taster down      Taster 2  KEY_read_down
BIT 2 = PB 1 - Taster up        Taster 5  KEY_read_up
BIT 5 = PA 5 - Taster enter     Taster 4  KEY_ENTER_PORTA
BIT 7 = PA 7 - Taster rechts    Taster 3  KEY_RECHTS_PORTA

: Bearbeitet durch User
Autor: Heiner1234 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul

In der Main musst du Taste 2 und Taste 5 wie bei der ISR behandeln

Für Taste 2 gilt dann:
If(get_key_press((1<<PB0)<<1)

PB0 ist ja Taster2, wird eingelesen und dann auch um 1 geschoben
Gilt für PB1 genauso

Müsste gehen!!

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag,
danke für eure Antworten, komme heute abend erst wieder an meinen 
Rechner. Teste es dann sofort

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.

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