Forum: Mikrocontroller und Digitale Elektronik Problem mit Schieberegister und steigende Flanke


von Markus P. (sebastianwurst)


Angehängte Dateien:

Lesenswert?

Hi,
ich kriege was nicht hin und brauch Eure Hilfe !!!
Also ich habe hier zwei Schieberegister 74HCT165 (s.Anhang) und frage 
die so ab:
(Das funktioniert auch)
In der main:
1
    PORTC |= (1<<PC4);
2
3
    // Mit PL alle Eingänge in das Register schieben.
4
5
    // PL auf High
6
    PORTC |= (1<<PC5);
7
    // PL auf Low
8
    PORTC &= ~(1<<PC5);
9
    // PL auf High
10
    PORTC |= (1<<PC5);
11
12
      
13
14
    for(m=15;m>=0;m--)
15
    {
16
          
17
      if (PINA & (1<<PINA0)) 
18
      { 
19
      Eingang[m] = false;
20
      } 
21
      else 
22
      {
23
      Eingang[m] = true;
24
        
25
      }  
26
27
      // Clock auf High
28
      PORTC |= (1<<PC4);
29
      // Clock auf Low
30
      PORTC &= ~(1<<PC4);
31
      // Clock auf High
32
      PORTC |= (1<<PC4);    
33
    }

Jetzt will ich mit der Funktion vom Karl-Heinz (paar Beiträge vorher) 
eine steigende Flanke generieren:
Wird initialisiert, also über der main...
1
void R_TRIG_Taster(bool bit,int bitnr, bool array[])
2
{
3
  if( array[bitnr] != bit)  // Es gibt einen Unterschied, als muss es eine Flanke 
4
  {                         // gegeben haben
5
    if( bit )               //   war es 0->1  ?
6
      array[bitnr] = true;  //     Ja:  steigende Flanke
7
    else                    //   nein: es war 1->0, fallende Flanke
8
      array[bitnr] = false;
9
  }
10
  else                      // es gibt keine Veränderung, Taster gedrückt
11
                            // oder losgelassen
12
    array[bitnr] = false;   
13
}


Aufrufen tu ich in der main noch dieses:
1
R_TRIG_Taster(Eingang[4],4, arraytest);
2
3
if (arraytest[4])
4
{
5
usart_write_str("--xxx--");
6
}

Aber warum wird die Ausgabe auf UART immer öfters gemacht ?
Ich Taste kurz auf den Taster, also wird so ca. 10-12 mal die 
"---xxx---" ausgegeben. Was mache ich denn da noch falsch, denn ich will 
da nur ein R_TRIG also steigende Flanke von haben.... Ich würde mich 
über jede Hilfe sehr freuen!

von Markus P. (sebastianwurst)


Lesenswert?

Hat vielleicht einer ein Tip für mich ????

von Peter R. (peterfido)


Lesenswert?

Das der Taster prellt ist ausgeschlossen?

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


Lesenswert?

Markus P. schrieb:
> Jetzt will ich mit der Funktion vom Karl-Heinz (paar Beiträge vorher)
Toller Link...  :-/
Meine Links sehen anders aus, da kann man draufclicken...

Zu deinem Problem wurde schon alles gesagt.
Du brauchst eine Tasterentprellung.

BTW und zum Nachdenken:
wie ist eigentlich dein Datentyp bool definiert?

von ... (Gast)


Lesenswert?

Lothar Miller schrieb:
> Du brauchst eine Tasterentprellung.

Du kann deinen µC natürlich einfach ein bisschen ablenken, nachdem er 
einen Tastendruck erkannt hat. Gibt ihm eine Warteschleife zum 
Abarbeiten. Wenn du ihn damit vielleicht 100 ms eingelullt hast, dürfte 
sich dein Tastenkontakt wieder von dem Schreck des "gedrückt-werdens" 
erholt haben und der µC darf wieder gucken.

von Peter D. (peda)


Lesenswert?

... schrieb:
> Du kann deinen µC natürlich einfach ein bisschen ablenken, nachdem er
> einen Tastendruck erkannt hat.

Was bedeutet, man muß sich immer wieder um das Entprellen kümmern, wenn 
sich die Mainloop-Durchlaufzeit ändert.

Besser, man nimmt einen Timerinterrupt zum Tasten einlesen und muß sich 
nie wieder damit abquälen. Das Main kriegt die entprellte Taste auf dem 
Silbertablett geliefert.
Weiterer Vorteil, es können bis zu 8 Tasten entprellt werden, ohne das 
der Aufwand (RAM, CPU-Last) steigt.
Noch mehr Vorteile, es können lang-, kurz-Erkennung, Repeat usw. 
einfachst hinzugefügt werden.


Peter

von Karl H. (kbuchegg)


Lesenswert?

Markus P. schrieb:
> Hat vielleicht einer ein Tip für mich ????

Entprellen wurde ja schon angesprochen.

Aber wart mal. Deine ganze Funktion ist Unsinn. Du kannst nicht in einem 
einzigen Array dir den Zustand eines Eingangs merken UND gleichzeitig ob 
dort eine Flanke aufgetreten ist. Das sind zwei verschiedene 
Informationen, die du nicht in einem einzigen bool speichern kannst. 
Jetzt ist mir auch klar, warum mir die Funktion ursprünglich so spanisch 
vorkam.

Gib deinen Variablen vernünfige Bezeichnungen NACH IHREM 
VERWENDUNGSZWECK und nicht nach ihrem Datentyp. Eine Variable namens 
Array sagt dir nichts. Nenn es zb Tastenzustand dann fängt dein Code 
plötzlich an selbsterklärend zu werden.



Peter hat recht. Spar dir den ganzen Aufwand und adaptier seine 
Timer-Lösung.

von Markus P. (sebastianwurst)


Lesenswert?

Peter Dannegger schrieb:
> ... schrieb:
>> Du kann deinen µC natürlich einfach ein bisschen ablenken, nachdem er
>> einen Tastendruck erkannt hat.
>
> Was bedeutet, man muß sich immer wieder um das Entprellen kümmern, wenn
> sich die Mainloop-Durchlaufzeit ändert.
>
> Besser, man nimmt einen Timerinterrupt zum Tasten einlesen und muß sich
> nie wieder damit abquälen. Das Main kriegt die entprellte Taste auf dem
> Silbertablett geliefert.
> Weiterer Vorteil, es können bis zu 8 Tasten entprellt werden, ohne das
> der Aufwand (RAM, CPU-Last) steigt.
> Noch mehr Vorteile, es können lang-, kurz-Erkennung, Repeat usw.
> einfachst hinzugefügt werden.
>
>
> Peter


Hi, erstmal vielen Dank für die Antworten. An Peter, wie kann ich den 
mit der Timerinterrupt am besten Entprellen ohne das ich dein Code gross 
umschreiben muss: http://www.mikrocontroller.net/articles/Entprellung
Weil ich habe die Eingänge (60Stück) ja über ein Schieberegister 
aufgebaut?

von Markus P. (sebastianwurst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Markus P. schrieb:
>> Hat vielleicht einer ein Tip für mich ????
>
> Entprellen wurde ja schon angesprochen.
>
> Aber wart mal. Deine ganze Funktion ist Unsinn. Du kannst nicht in einem
> einzigen Array dir den Zustand eines Eingangs merken UND gleichzeitig ob
> dort eine Flanke aufgetreten ist. Das sind zwei verschiedene
> Informationen, die du nicht in einem einzigen bool speichern kannst.
> Jetzt ist mir auch klar, warum mir die Funktion ursprünglich so spanisch
> vorkam.
>

Aber Karl-Heinz das tut die Funktion doch auch nicht.
In dem Array speichere ich mir doch nur eine Steigende Flanke die ich 
nachher im Program abfragen will:
1
void R_TRIG_Taster(bool bit,int bitnr, bool array[])
2
{
3
  if( array[bitnr] != bit)  // Es gibt einen Unterschied, als muss es eine Flanke 
4
  {                         // gegeben haben
5
    if( bit )               //   war es 0->1  ?
6
      array[bitnr] = true;  //     Ja:  steigende Flanke
7
    else                    //   nein: es war 1->0, fallende Flanke
8
      array[bitnr] = false;
9
  }
10
  else                      // es gibt keine Veränderung, Taster gedrückt
11
                            // oder losgelassen
12
    array[bitnr] = false;   
13
}

Du hast natürlich Recht mit den Variablennamen, war halt ein Test ....
1
R_TRIG_Taster(Eingang[4],4, arraytest);
2
3
if (arraytest[4])
4
{
5
usart_write_str("--xxx--");
6
}

von Peter D. (peda)


Lesenswert?

Markus P. schrieb:
> An Peter, wie kann ich den
> mit der Timerinterrupt am besten Entprellen ohne das ich dein Code gross
> umschreiben muss

Lege alle 4 nötigen Variablen in ein struct und das dann als Array mit 8 
Elementen.
Und dann lege die SPI-Taktrate so, daß sich ein günstiges 
Entprellinterval ergibt, den Timer brauchst Du dann nicht mehr.
Im SPI-Interrupt wird dann jedes empfangene Byte entprellt.
Nimmst Du die UART im SPI-Mode, kann man immer 2 Bytes auf einen Rutsch 
einlesen, das halbiert die Interruptlast.

Den Main-Funktionen mußt Du neben der Bitmaske noch die Arraynummer 
übergeben.

Theoretisch kann der AVR-GCC zwar 64Bit, das ist aber praktisch nicht 
brauchbar. Es bewirkt einen riesen Code-Wust und CPU-Zeitverbrauch.
Laut den GCC-Gurus kann ja jeder leicht die optimierte Funktionen 
einbauen.
Ich weiß aber nur, wie die optimierten Funktionen in Assembler aussehen 
könnten.


Peter

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.