Forum: Mikrocontroller und Digitale Elektronik Tastenentprellung seltsames Phänomen


von East (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, bin noch recht frisch in der Programmer-Scene. Habe ein Projekt 
begonnen, um eine Alarmanlage zu realisieren. Leider scheitert die 
Programmierung schon an der Entprellung der Taster. Habe erfolgreich ein 
I2C-LCD am laufen. Weiter benutze ich ein Arduinoboard Micro 32U4. Wenn 
dem im Anhang besagten Code auf den Controller schmeisse, habe ich ohne 
das ich einen Taster betätige eine Ausgabe eines Tasters am LCD 
(willkürlich).

Das Problem habe ich bis jetzt noch nicht eingrenzen können. Zudem nutze 
ich die Entrellroutine von Peter Dannegger.

Wäre Super wenn mir jemand helfen könnte. Vielleicht bin ich auch nur 
Blind.

Gruß,

East

von Stefan F. (Gast)


Lesenswert?

> Das Problem habe ich bis jetzt noch nicht eingrenzen können.

Reduziere dein Programm auf ein Minimum, also kein LCD ansteuern, 
sondern nur eine LED.

Beispiel: Bei jedem Tastendruck soll die LED toggeln.

Wenn das nicht klappt, beschreibe, was das Programm stattdessen tut und 
poste nochmal den reduzierten Quelltext.

von Mein grosses V. (vorbild)


Lesenswert?

Ich tippe auf einen Lötfehler am externen Pullup des besagten Tasters.

von east (Gast)


Lesenswert?

Lötfehler schliesse ich definitiv aus. Da ich mit Multimeter 5V an allen 
eingänge messe. Und sobald ich diese betätige, werden alle Eingänge auf 
GND gezogen (0,61V).

Habe gerade mal nachgeschaut. Die Hochlaufschritte des Timers 0 sind bei 
meiner rechnung 7,8125 +0.5 für 10ms. Kann aber nicht sein. Wenn ich 
nachrechne um eine Konstante von 10ms (Zeitbasis) brauche, brauche ich 
bei einem 8-Bit Timer mit 8 MHZ bei Prescaler von 1024 eine TCNT von 
78,125.

Kann es sein 10e-3 keine 10ms sondern 1ms sind?

von east (Gast)


Lesenswert?

Bei einer Ansteuerung von einer LED funzt das. Problem, da sehe ich aber 
nicht von welchem Eingang das kommt.

von east (Gast)


Angehängte Dateien:

Lesenswert?

Kann es sein das die LCD Routine misst macht?

von east (Gast)


Lesenswert?

Hier die LCD I2C Routine.

von Mein grosses V. (vorbild)


Lesenswert?

east schrieb:
> Lötfehler schliesse ich definitiv aus. Da ich mit Multimeter 5V an allen
> eingänge messe. Und sobald ich diese betätige, werden alle Eingänge auf
> GND gezogen (0,61V).

Etwas ausschließen können alle, bei denen etwas nicht funktioniert, sehr 
gut. Das ist insbesondere deswegen interessant, da seltsame Phänomene 
immer vor dem PC oder der Schaltung sitzen.
Aber das ist eigentlich die falsche Aussage, denn das war eher als Wink 
mit dem Zaunpfahl gedacht. Dein Arduino hat überhaupt keine externen 
Pullups. Ich sehe in deiner Initialisierung aber auch nicht, daß die 
internen aktiviert werden. Dabei ist es zwar schleierhaft, wie du 5V 
messen kannst, aber sei's drum. Wo werden die Pullups eingeschaltet?

: Bearbeitet durch User
von East (Gast)


Lesenswert?

Die externen Pullups sind auf der Platine. Alle gegen VCC und den 
Eingängen.

von East (Gast)


Lesenswert?

Achso, die internen habe ich nicht eingeschaltet, da externe existieren. 
Wie soll ich sonst die 5V gegen den Eingang messen können?

von East (Gast)


Lesenswert?

Übrigens ist es nicht nur ein Taster sondern 8. Und wäre ein oder 
mehrere Pullups nicht richtig gelötet, würde immer nur diese auslösen. 
Es lösen aber alle sporadisch aus.

von East (Gast)


Angehängte Dateien:

Lesenswert?

Hier der Schaltplan

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

East schrieb:
> Wie soll ich sonst die 5V gegen den Eingang messen können?
Wieso misst du irgendwas gegen irgendeinen Eingang? Spannungen werden 
üblicherweise gegen GND gemessen.

East schrieb:
> Übrigens ist es nicht nur
Salamitaktik...

> Es lösen aber alle sporadisch aus.
Zeig mal 1. einen Schaltplan und 2. ein Foto von deinem Aufbau. Sonst 
ist das hier nur Stochern im Nebel...

von East (Gast)


Lesenswert?

Habe immer gegen Masse gemessen. Daher auch die gemessenen Spannungen.

von Frank (Gast)


Lesenswert?

Was soll das lcd_init() bei jedem Tastendruck?


Was soll das sein:
1
TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);      // preload for 10ms

Mich wundert dass das überhaupt übersetzt.

von Karl M. (Gast)


Lesenswert?

Hallo,

Was soll den bei Dir innerhalb der
1
uint8_t get_key_press( uint8_t key_mask, uint8_t PORTx )
2
 KEYPIN = PORTx;
bewirken ?

Ich verwende Peter Danneggers Enprellroutine auch, aber etwas anders.
1
ISR( TIM0_COMPA_vect )                          // every 10ms
2
{
3
  static uint8_t ct0 = 0xFF, ct1 = 0xFF, rpt;  // bei 1ms ist diese Zahl 16-Bit groß
4
  uint8_t i;
5
6
  i = key_state ^ ~KEY_PIN;                     // key changed ?
7
  ct0 = ~( ct0 & i );                           // reset or count ct0
8
  ct1 = ct0 ^ (ct1 & i);                        // reset or count ct1
9
  i &= ct0 & ct1;                               // count until roll over ?
10
  key_state ^= i;                               // then toggle debounced state
11
  key_press |= key_state & i;                   // 0->1: key press detect
12
13
  if( (key_state & REPEAT_MASK) == 0 )          // check repeat function
14
     rpt = REPEAT_START;                        // start delay
15
  if( --rpt == 0 ){
16
    rpt = REPEAT_NEXT;                          // repeat delay
17
    key_rpt |= key_state & REPEAT_MASK;
18
  }
19
}
1
uint8_t get_key_press( uint8_t key_mask )
2
{
3
  ATOMIC_BLOCK(ATOMIC_FORCEON){
4
    key_mask &= key_press;                      // read key(s)
5
    key_press ^= key_mask;                      // clear key(s)
6
  }
7
  return key_mask;
8
}
9
10
11
uint8_t get_key_rpt( uint8_t key_mask )
12
{
13
  ATOMIC_BLOCK(ATOMIC_FORCEON){
14
    key_mask &= key_rpt;                        // read key(s)
15
    key_rpt ^= key_mask;                        // clear key(s)
16
  }
17
  return key_mask;
18
}
19
20
21
uint8_t get_key_short( uint8_t key_mask )
22
{
23
  uint8_t i;
24
25
  ATOMIC_BLOCK(ATOMIC_FORCEON)
26
    i = get_key_press( ~key_state & key_mask );
27
  return i;
28
}
29
30
31
uint8_t get_key_long( uint8_t key_mask )
32
{
33
  return get_key_press( get_key_rpt( key_mask ));
34
}
35
36
37
uint8_t get_key_long_r( uint8_t key_mask )      // if repeat function needed
38
{
39
  return get_key_press( get_key_rpt( key_press & key_mask ));
40
}
41
42
43
uint8_t get_key_rpt_l( uint8_t key_mask )       // if long function needed
44
{
45
  return get_key_rpt( ~key_press & key_mask );
46
}

von East (Gast)


Lesenswert?

Den LCD_INIT() brauch ich, um das LCD zu clearen. Da das mit 
lcd_command(LCD_CLEAR) nicht hingehauen hatte. Ist eben halt bischen 
rumgebastelt. Daher sage ich auch, das ich noch ziemlich am Anfang 
stehe.

Das key_state und key_press auf 0 gesetzt werden, ist weil der sofort 
nach dem einschalten sonst in einem if (get_keypress()) reingeht. Warum 
habe ich auch noch nicht heraus gefunden.

von Karl M. (Gast)


Lesenswert?

Hallo Frank,

Frank schrieb:
> Was soll das sein:TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 +
> 0.5);      // preload for 10ms

Damit berechnet der Preprocessor den Timer0 Preloadwert im TimerO0verlow 
Modus.
Der Prescaler ist 1024, 10ms == 10e-3, +0.5 == aufrunden und dann
(256 - Zählerwert) berechnen.
Denn TimerOverlow zählt der Timer0 von von N bis 256 und bei 256 == 0 
wird ein Overflow Interrupt Request erzeugt.

Alles korrekt !

von Karl M. (Gast)


Lesenswert?

Karl M. schrieb:
> ISR( TIM0_COMPA_vect )

East schrieb:
> Das key_state und key_press auf 0 gesetzt werden, ist weil der sofort
> nach dem einschalten sonst in einem if (get_keypress()) reingeht. Warum
> habe ich auch noch nicht heraus gefunden.

Die Antwort steht in der ISR( TIM0_COMPA_vect ) !
Man muss halt C können.

von East (Gast)


Lesenswert?

OK. Habe den Repeat entfernt, da ich den nicht brauche um meine Tasten 
abzufragen. Habe dies auch schon in funktionierenden Projekten gesehen.

Das mit dem ATOMICBLOCK??? Ist das das selbe wie CLI()? Weil ich ja mit 
cli() alle Interrupts stoppe.

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Karl M. schrieb:
>> ISR( TIM0_COMPA_vect )
>
> East schrieb:
>> Das key_state und key_press auf 0 gesetzt werden, ist weil der sofort
>> nach dem einschalten sonst in einem if (get_keypress()) reingeht. Warum
>> habe ich auch noch nicht heraus gefunden.
>
> Die Antwort steht in der ISR( TIM0_COMPA_vect ) !
> Man muss halt C können.

Ich weiss auch das der Timmer 0 nach dem sei() in der main sofort 
startet. Aber warum löst getkeypress(), ohne ein zutun aus????

von Karl M. (Gast)


Lesenswert?


von East (Gast)


Lesenswert?

East schrieb:
> Karl M. schrieb:
>> Karl M. schrieb:
>>> ISR( TIM0_COMPA_vect )
>>
>> East schrieb:
>>> Das key_state und key_press auf 0 gesetzt werden, ist weil der sofort
>>> nach dem einschalten sonst in einem if (get_keypress()) reingeht. Warum
>>> habe ich auch noch nicht heraus gefunden.
>>
>> Die Antwort steht in der ISR( TIM0_COMPA_vect ) !
>> Man muss halt C können.
>
> Ich weiss auch das der Timmer 0 nach dem sei() in der main sofort
> startet. Aber warum löst getkeypress(), ohne ein zutun aus????

Es ist ja so, dass wenn der MC nach dem Einschalten startet, sofort im 
LCD eine Ausgabe des jeweiligen textes der Taster ausgibt. Ohne das 
dieser Betätigt wurde.

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Siehe:
>
> http://www.nongnu.org/avr-libc/user-manual/group__...

Also doch das gleiche wie cli().

von Karl M. (Gast)


Lesenswert?

Ich schreibe es ferne nochmal:

Die Antwort steht in der ISR( TIM0_COMPA_vect ) !

Beitrag "Re: Universelle Tastenabfrage"

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Hallo,
>
> Was soll den bei Dir innerhalb deruint8_t get_key_press( uint8_t
> key_mask, uint8_t PORTx )
>  KEYPIN = PORTx;bewirken ?
>

Das habe ich hinzugefügt, da ich unterschiedliche POrts benutze.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

East schrieb:
> Den LCD_INIT() brauch ich, um das LCD zu clearen.
Schaltest du auch jedesmal das Auto aus, wenn du den Gang wechseln 
willst?

> Da das mit lcd_command(LCD_CLEAR) nicht hingehauen hatte.
Dann such den Fehler. In der Praxis geht das nämlich...

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Ich schreibe es ferne nochmal:
>
> Die Antwort steht in der ISR( TIM0_COMPA_vect ) !
>
> Beitrag "Re: Universelle Tastenabfrage"

WAS??????????????? Du benutzt den COMPA_Vector??????

Aber in der Routine von PD wird doch der Overflow benutzt!?!

von Karl M. (Gast)


Lesenswert?

Ok East,

dann mache es richtig und verwende nur einen Port, dort kann man 8 Bits 
Abfragen und als Eingänge nutzen.

So wie es abgeändert wurde, wird es nicht funktionieren.

Es gibt einen Trick z.B zwei Ports zu verwenden.
Aber das passier alles nur in der Timer Interruptroutine und nur in 
der Zeile:
1
i = key_state ^ ~KEY_PIN;                     // key changed ?

East schrieb:
> Das habe ich hinzugefügt, da ich unterschiedliche POrts benutze.

von Karl M. (Gast)


Lesenswert?

Genau,

ich bin Programmierer und nutze meine Timer unterschiedlich, mal Timer0 
oder auch TimerN im Modus CTC.

East schrieb:
> WAS??????????????? Du benutzt den COMPA_Vector??????
>
> Aber in der Routine von PD wird doch der Overflow benutzt!?!

von Loddar (Gast)


Lesenswert?

East schrieb:
> Aber warum löst getkeypress(), ohne ein zutun aus????

Karl hat ja schon darauf hingewiesen:
Variablen haben es meist gerne wenn sie mit einem bestimmten Wert 
initialisiert werden.

von Frank (Gast)


Lesenswert?

Karl M. schrieb:
> Damit berechnet der Preprocessor den Timer0 Preloadwert im TimerO0verlow
> Modus.
> Der Prescaler ist 1024, 10ms == 10e-3, +0.5 == aufrunden und dann (256 -
> Zählerwert) berechnen.
> Denn TimerOverlow zählt der Timer0 von von N bis 256 und bei 256 == 0
> wird ein Overflow Interrupt Request erzeugt.
>
> Alles korrekt !

Mir geht es eher darum das vom Datentyp int16_t ein Wert abgezogen wird. 
Wusste nicht dass das geht.

East schrieb:
> Den LCD_INIT() brauch ich, um das LCD zu clearen.

Jou, du vertrödelst halt bei jedem Tastendruck ca. 20ms.

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Ok East,
>
> dann mache es richtig und verwende nur einen Port, dort kann man 8 Bits
> Abfragen und als Eingänge nutzen.
>
> So wie es abgeändert wurde, wird es nicht funktionieren.
>
> Es gibt einen Trick z.B zwei Ports zu verwenden.
> Aber das passier alles nur in der Timer Interruptroutine und nur in
> der Zeile:i = key_state ^ ~KEY_PIN;                     // key changed ?
> East schrieb:
>> Das habe ich hinzugefügt, da ich unterschiedliche POrts benutze.

Das heisst also, da ich das schon extern vorbereite bekommt der Timer 
ein problem bei den setzen der unterschiedlichen PORTS???

Also so ist besser???

i=kay_state ^~((KEY_PINB & (1 << PB1)|(KEY_PIND &(1 <<PD2))

von East (Gast)


Lesenswert?

Frank schrieb:
> Karl M. schrieb:
>> Damit berechnet der Preprocessor den Timer0 Preloadwert im TimerO0verlow
>> Modus.
>> Der Prescaler ist 1024, 10ms == 10e-3, +0.5 == aufrunden und dann (256 -
>> Zählerwert) berechnen.
>> Denn TimerOverlow zählt der Timer0 von von N bis 256 und bei 256 == 0
>> wird ein Overflow Interrupt Request erzeugt.
>>
>> Alles korrekt !
>
> Mir geht es eher darum das vom Datentyp int16_t ein Wert abgezogen wird.
> Wusste nicht dass das geht.
>
> East schrieb:
>> Den LCD_INIT() brauch ich, um das LCD zu clearen.
>
> Jou, du vertrödelst halt bei jedem Tastendruck ca. 20ms.

Also doch die scheiss _delay_ms(15) in der LCD Routine..

Misst.

von East (Gast)


Lesenswert?

Sorry für die Wortwahl. :)

von East (Gast)


Lesenswert?

Heisst aber, das ich innerhalb einer Tasterabfrage nichts auf meinem LCD 
anzeigen darf. Ist ziemlich doof.

von East (Gast)


Lesenswert?

East schrieb:
> Frank schrieb:
>> Karl M. schrieb:
>>> Damit berechnet der Preprocessor den Timer0 Preloadwert im TimerO0verlow
>>> Modus.
>>> Der Prescaler ist 1024, 10ms == 10e-3, +0.5 == aufrunden und dann (256 -
>>> Zählerwert) berechnen.
>>> Denn TimerOverlow zählt der Timer0 von von N bis 256 und bei 256 == 0
>>> wird ein Overflow Interrupt Request erzeugt.
>>>
>>> Alles korrekt !
>>
>> Mir geht es eher darum das vom Datentyp int16_t ein Wert abgezogen wird.
>> Wusste nicht dass das geht.
>>

OK. Habe auch zuerst gedacht, aber dann wieder verworfen. Also uint8t == 
256.

256 - (F_CPU /1024 *10e-3 +0.5)

von Karl M. (Gast)


Lesenswert?

Hall East,

ich hatte Dir den original Beitrag/ Thread von Peter Dannegger (peda) 
zitiert. Den solltest Du lesen und verstehen.

Die Routinen von Peter sind nur für das Entprellen eines 8bit Ports 
ausgelegt !

Also nutze erst mal nur einen Port mit seinen max. 8 Bits als Einfänge.
Wenn Du dass am laufen bekommst, versuche den Code in der Timer 
Interrupt Service Routine komplett zu verstehen.
Dann sollte Dir ein Licht aufgehen.

East schrieb:
> Also so ist besser???
>
> i=kay_state ^~((KEY_PINB & (1 << PB1)|(KEY_PIND &(1 <<PD2))

von East (Gast)


Lesenswert?

East schrieb:
> Frank schrieb:
>> Karl M. schrieb:
>>> Damit berechnet der Preprocessor den Timer0 Preloadwert im TimerO0verlow
>>> Modus.
>>> Der Prescaler ist 1024, 10ms == 10e-3, +0.5 == aufrunden und dann (256 -
>>> Zählerwert) berechnen.
>>> Denn TimerOverlow zählt der Timer0 von von N bis 256 und bei 256 == 0
>>> wird ein Overflow Interrupt Request erzeugt.
>>>
>>> Alles korrekt !
>>
>> Mir geht es eher darum das vom Datentyp int16_t ein Wert abgezogen wird.
>> Wusste nicht dass das geht.
>>
>> East schrieb:
>>> Den LCD_INIT() brauch ich, um das LCD zu clearen.
>>
>> Jou, du vertrödelst halt bei jedem Tastendruck ca. 20ms.
>
> Also doch die scheiss _delay_ms(15) in der LCD Routine..
>
> Misst.

Könnte ich das eventuell umgehen? zb:

if(Getkeypress()){ z=1<;}

if (z !=0 ){ lcd_printlc(1,7("PD4"));}

von Karl M. (Gast)


Lesenswert?

Also eher so:
1
TCNT0 = (uint8_t)((int16_t)(0) - (int16_t)(F_CPU / 1024 * 10e-3 + 0.5) );

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Hall East,
>
> ich hatte Dir den original Beitrag/ Thread von Peter Dannegger (peda)
> zitiert. Den solltest Du lesen und verstehen.
>
> Die Routinen von Peter sind nur für das Entprellen eines 8bit Ports
> ausgelegt !
>
> Also nutze erst mal nur einen Port mit seinen max. 8 Bits als Einfänge.
> Wenn Du dass am laufen bekommst, versuche den Code in der Timer
> Interrupt Service Routine komplett zu verstehen.
> Dann sollte Dir ein Licht aufgehen.
>


OK. Das wede ich wohl erstmal machen müssen. Vielen Dank für deine 
Mühen.

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Also eher so:
> TCNT0 = (uint8_t)((int16_t)(0) - (int16_t)(F_CPU / 1024 * 10e-3 + 0.5)
> );

Wie wird den (uint8_t) von (uint16_t) ohne einen operator unterschieden?
Glaube verstehe das noch nicht.

von Karl M. (Gast)


Lesenswert?

Sube bitte mal nach C CAST für (uint8_t) und (int16_t).

Und schaue dir bitte die unterschiedlichen Zahlentypen auf einen Atmel 
AVR µC an.

von East (Gast)


Lesenswert?

Vielen Dank. Jetzt klappt es. Muss noch ein bischen die Routine von PD 
verstehen.

von Stefan F. (Gast)


Lesenswert?

Mal was anderes: Wenn du nach jedem Tastendruck etwas auf dem Display 
ausgibst, und das mehr als 10ms dauert, dann brauchst du gar keinen Code 
zur Entprellung.

von Karl M. (Gast)


Lesenswert?

Stefan,

ich sehe, dass Du das Problem noch nicht erkannt hast, mit Delay kann 
man keine Tasten entprellen und auch noch Ereignisse generieren !

Der Code von Peter liefert dem Anwender ja verschiedene Ereignisse, das 
Entprellen von Drücken und Loslassen ist dann eher nur ein Nebeneffekt.

Stefan U. schrieb:
> Mal was anderes: Wenn du nach jedem Tastendruck etwas auf dem Display
> ausgibst, und das mehr als 10ms dauert, dann brauchst du gar keinen Code
> zur Entprellung.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Mal was anderes: Wenn du nach jedem Tastendruck etwas auf dem Display
> ausgibst, und das mehr als 10ms dauert, dann brauchst du gar keinen Code
> zur Entprellung.
Dafür reagierst du dann aber auch auf kurze EMV-Spikes und Störungen, 
wenn sie zur rechten Zeit kommen  :-o

Oder andersrum: ein _delay_ms() deutet meist auf einen strukturellen 
Fehler im Programm hin. Denn es ist aktive Rechenzeitverschwendung. Und 
auch die Ausgabe auf ein Display muss nicht warten. Sie muss nur 
kontrollieren, ob die vorige Aktion schon fertig ist...

: Bearbeitet durch Moderator
von Stefan F. (Gast)


Lesenswert?

Ich bin vom ursprünglich geposteten Code main() ausgegangen. Da wird 
nach jedem Tastendruck irgendwas auf dem LCD ausgegeben. Wenn das 10ms 
dauert und ich danach auf das Loslassen der Taste warte (das hatte ich 
vergessen, zu schreiben), brauche ich keine Entsprellung mehr. Die 
ergibt sich aus der zeit, die die Displayausgabe dauert.

von Stefan F. (Gast)


Lesenswert?

> Dafür reagierst du dann aber auch auf kurze EMV-Spikes und Störungen

Das tut der ursprünglich gepostete Code auch.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Das tut der ursprünglich gepostete Code auch.
Also gleich weit und gleich schlecht...

von Karl M. (Gast)


Lesenswert?

Zur Korrektur, nicht nach Tastendrücken sondern auf einen 
Tasten-Ereignis wird reagiert.
D.h. mit dem original Code ist der Zustandwechsel schon über 4x 10ms 
konstant, danach wird das Ereignis festgestellt.
Da die gesamte Tastenverarbeitung über den Timer0 Interrupt läuft, ist 
es egal, ob man im Hauptprogramm ein LCD bedient auch wartet.

von East (Gast)


Lesenswert?

Lothar M. schrieb:
> Stefan U. schrieb:
>> Mal was anderes: Wenn du nach jedem Tastendruck etwas auf dem Display
>> ausgibst, und das mehr als 10ms dauert, dann brauchst du gar keinen Code
>> zur Entprellung.
> Dafür reagierst du dann aber auch auf kurze EMV-Spikes und Störungen,
> wenn sie zur rechten Zeit kommen  :-o
>
> Oder andersrum: ein _delay_ms() deutet meist auf einen strukturellen
> Fehler im Programm hin. Denn es ist aktive Rechenzeitverschwendung. Und
> auch die Ausgabe auf ein Display muss nicht warten. Sie muss nur
> kontrollieren, ob die vorige Aktion schon fertig ist...

Mag schon sein, das ein _delay_xx darauf hindeutet, dass zeit 
verschwendet wird. Trotz alle dem gibt es gerade bei LCD Routinen im ein 
Delay, um zb die Ausgabe an ein HD44780 anzupassen. Bis Dato habe ich 
noch keine Routine für LCD gesehen die kein _delay_xx benutzt.

von East (Gast)


Lesenswert?

Was natürlich fraglich ist, warum LCD_CLEAR nicht funktioniert. Da ich 
den Code hier aus dem Forum habe, habe ich angenommen dass der auch 
lauffähig ist.

von East (Gast)


Lesenswert?

Karl M. schrieb:
> Hall East,
>
> ich hatte Dir den original Beitrag/ Thread von Peter Dannegger (peda)
> zitiert. Den solltest Du lesen und verstehen.
>
> Die Routinen von Peter sind nur für das Entprellen eines 8bit Ports
> ausgelegt !
>
> Also nutze erst mal nur einen Port mit seinen max. 8 Bits als Einfänge.
> Wenn Du dass am laufen bekommst, versuche den Code in der Timer
> Interrupt Service Routine komplett zu verstehen.
> Dann sollte Dir ein Licht aufgehen.

Glaube habe es verstanden. Und auch meinen Fehler gefunden. Da die 
Routine einen Port mit allen 8 Bits kontrolliert, wurde so wie ich 
vermute durch meine Änderung, etwas Überschnitten. Wenn der Timer bei 
einem überlauf ein Taster (Eingang) über Getkeypress registriert hat und 
auswertet, habe ich durch meine Änderung einen beim nächsten überlauf 
neuen Port übertragen.

Da liegt glaube ich der Fehler. Dort wurden dann von zwei 
Unterschiedlichen Ports, Pins vermischt und führten so zur gegnseitigen 
Prellung.

von East (Gast)


Angehängte Dateien:

Lesenswert?

Hier nochmal der geänderte Test Code.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.