Forum: Mikrocontroller und Digitale Elektronik Entprellen Flankenerkennung


von kopr (Gast)


Lesenswert?

habe schon einige alte Beiträge zu diesem thema gelesen. bin Anfänger 
wie sich sicherlich versteht.
Das kritische scheint zu sein:
Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms.
für kurze Laufzeiten benötigt man evtl ein delay, bei langen laufzeiten 
wird ein Drücken verschluckt.

Es war aber für mich persönlich die am einfachsten zu verstehende 
routine, zumal ich kein AVR habe und es mich überfordert, die anderen 
routinen auf meine Plattform anzupassen.

Was würdet ihr mir empfehlen?

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


Lesenswert?

kopr schrieb:
> Was würdet ihr mir empfehlen?
Nimm die bekannten Routinen von PeDa.
Versuche zu verstehen, was die machen und lerne daraus.

von kopr (Gast)


Lesenswert?

Bitte entschuldigt die Rechtschreibung. Habe das grade mit einem Anflug 
von Emotionen geschrieben

von kopr (Gast)


Lesenswert?

Lothar M. schrieb:
> Nimm die bekannten Routinen von PeDa.
> Versuche zu verstehen, was die machen und lerne daraus.

da scheiterts nicht nur am Verständnis, sondern eben auch daran, dass 
ich nicht weiß, wie ich den Code an meine Plattfrom anzupassen habe

von c-hater (Gast)


Lesenswert?

kopr schrieb:

> Was würdet ihr mir empfehlen?

Dein Verständnis durch Lernen hinreichend zu verbessern, so dass du in 
den Status gelangst, auch die bewährten "komplizierten" Entprellroutinen 
zu verstehen. Die sind nämlich letztlich auch ziemlich trivial...

> zumal ich kein AVR habe und es mich überfordert, die anderen
> routinen auf meine Plattform anzupassen.

Wenn du nicht einmal diesen trivialen Scheiß an eine andere Plattform 
anpassen kannst, bist du halt einfach noch nichtmal andeutungsweise ein 
Programmierer.

Du kannst das entweder durch LERNEN ändern oder dir einfach ein Hobby 
suchen, für das deine Kompetenzen ausreichen. Briefmarkensammeln z.B. 
soll sehr enspannend sein. Aber: Es gibt auch dort viel zu lernen...

von kopr (Gast)


Lesenswert?

bin grade auf Folgendes gestoßen:L

Beitrag "Entprellen für Anfänger"

fürs Auge auf jeden Fall angenehmer. tut mir lied, wenn euch das zu 
simpel gestrickt ist. Jetzt kommt der Punkt mit dem Anpassen

von kopr (Gast)


Lesenswert?

c-hater schrieb:
> durch LERNEN ändern

ich möchte grade lernen, wie ich das anpasse =) dieses eine Mal mit 
einer Abkürzung an zig Büchern vorbei...

von Carl D. (jcw2)


Lesenswert?

kopr schrieb:
> c-hater schrieb:
>> durch LERNEN ändern
>
> ich möchte grade lernen, wie ich das anpasse =) dieses eine Mal mit
> einer Abkürzung an zig Büchern vorbei...

Benutz PeDas Routine in C. Dann must du keine Neuimplementierung machen, 
wenn du mal die HW-Plattform wechselst.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Was ist denn das für eine geheimnisvolle Plattform? Anstatt da so ein 
Wischiwaschi zu schreiben, hättest du ganz emotionslos mal schreiben 
können, worum es geht.
Eins ist klar, die einzige Anpassung betrifft die I/O des verwendeten 
Controllers.

von c-hater (Gast)


Lesenswert?

kopr schrieb:

> ich möchte grade lernen, wie ich das anpasse =) dieses eine Mal mit
> einer Abkürzung an zig Büchern vorbei...

Für Lernen gibt es leider keine Abkürzungen. Das muß man immer selbst 
tun. Ob man dafür 'zig Bücher braucht oder nicht, ist individuell 
verschieden. Aber nach meiner Erfahrung sind zur Übertragung von 
logischen Konzepten keine Massen an Büchern nötig. Eventuell nötiges 
Faktenwissen kann allerdings nur aus Büchern kommen (oder vergleichbaren 
Medien).

von kopr (Gast)


Lesenswert?

Matthias S. schrieb:
> Was ist denn das für eine geheimnisvolle Plattform?

msp 430

Matthias S. schrieb:
> Eins ist klar, die einzige Anpassung betrifft die I/O des verwendeten
> Controllers.
1
#include <avr/io.h>
2
#define F_CPU 9.6e6
3
#include <util/delay.h>

was ist mit den includes. ist in den Definitionen etwas drin, was ich 
brauche? Habe beim MSP entsprechend andere Defintionen. Was gibts da zu 
beachten?

von Thomas (Gast)


Lesenswert?

c-hater schrieb:
> Für Lernen gibt es leider keine Abkürzungen. Das muß man immer selbst
> tun. Ob man dafür 'zig Bücher braucht oder nicht, ist individuell
> verschieden. Aber nach meiner Erfahrung sind zur Übertragung von
> logischen Konzepten keine Massen an Büchern nötig. Eventuell nötiges
> Faktenwissen kann allerdings nur aus Büchern kommen (oder vergleichbaren
> Medien).

ah ja, da ist ja unser frisch geouteter Doktor

von Joachim B. (jar)


Lesenswert?

kopr schrieb:
> dass
> ich nicht weiß, wie ich den Code an meine Plattfrom anzupassen habe

wir wissen ja noch nicht mal deine Plattform!

Beim ESP32 kann ich durchaus einen 10ms Timerinterrupt einrichten und 
dann PeDdas Sourcecode in C nehmen.

Aber wie immer gilt step by step lernen und MACHEN

: Bearbeitet durch User
von Thomas (Gast)


Lesenswert?

Joachim B. schrieb:
> wir wissen ja noch nicht mal deine Plattform!

hab doch geschrieben, es ist ein msp430

von kopr (Gast)


Lesenswert?

Thomas schrieb:
> Joachim B. schrieb:
>> wir wissen ja noch nicht mal deine Plattform!
>
> hab doch geschrieben, es ist ein msp430

genau ein Msp 430. Hattest du die Frage nach den Definitionen gesehen

von c-hater (Gast)


Lesenswert?

Thomas schrieb:

> ah ja, da ist ja unser frisch geouteter Doktor

Das war ein Fake-Posting, da segelte jemand unter falscher Flagge. Nach 
der Logik des Textes könnte es Herr Drexler gewesen sein, allerdings 
halte ich den nicht für auch nur annähernd blöd genug, sich eine 
derartige Blöße zu geben. Es wird also ein böswilliger Störer gewesen 
sein, sowas diese unsägliche MaWin-Imitation, die immer mal wieder 
auftaucht.

Also ganz klar: Ich habe keinen Doktortitel. Ich hätte das im Thread 
selber klargestellt, wenn nicht irgendeiner der "weisen" Moderatoren 
beschlossen hätte, ihn zu schliessen, als es gerade begann, spannend zu 
werden...

von Joachim B. (jar)


Lesenswert?

Thomas schrieb:
> hab doch geschrieben, es ist ein msp430

kopr schrieb:
> genau ein Msp 430

2 Namen, ein User?

egal

Timernutzung, sieht dem AVR und ESP verdammt ähnlich, also kein 
Hexenwerk!
https://www.medit.hia.rwth-aachen.de/fileadmin/MSP430Buch/msp_html_buchse15.html

und auch mit Beispiele in C was PeDas C-Code einfügen einfach macht,
also erst mal eine LED anschalten, ein Port einlesen usw.

von Thomas (Gast)


Lesenswert?

sry Leute, sollte "hat" geschrieben heißen

von kopr (Gast)


Lesenswert?

Joachim B. schrieb:
> imernutzung

was hat der Debounce-Makro mit Timernutzung zu tun?

von kopr (Gast)


Lesenswert?

timernutzung etc sollte beim MSP kein problem sein

von Axel S. (a-za-z0-9)


Lesenswert?

kopr schrieb:
> habe schon einige alte Beiträge zu diesem thema gelesen. bin Anfänger
> wie sich sicherlich versteht.

Ich verstehe nur, daß du ein Troll sein willst.
Immerhin hast du den Wochentag korrekt gewählt.
+1

> Das kritische scheint zu sein:
> Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms.

Nein.

> für kurze Laufzeiten benötigt man evtl ein delay

Nein.

> bei langen laufzeiten wird ein Drücken verschluckt.

Nein.

> Es war aber für mich persönlich die am einfachsten zu verstehende
> routine, zumal ich kein AVR habe und es mich überfordert, die anderen
> routinen auf meine Plattform anzupassen.

Du sprichst in Rätseln. Was willst du gelesen haben?

> Was würdet ihr mir empfehlen?

Die Tür zu schließen. Von außen. Leise.

"Vielen Dank für die Beachtung aller Sicherheitsmaßnahmen!"

von A. S. (Gast)


Lesenswert?

kopr schrieb:
> Was würdet ihr mir empfehlen?

Schreib mal, was Du hast und kannst.

Wenn Du z.B.
- eine Taste auslesen kannst
- einen SysTicker oder eine zyklische Funktion hast
- nur den Druck (als die erste Flanke) erkennen willst

dann geht es relativ einfach gebastelt:
1
/* Block, der zyklisch, z.B. jede ms aufgerufen wird */
2
extern int key1Active(void); /* 1 wenn gedrückt, sonst 0 */
3
#define PRELLZYKLEN 20 /* entsprechend 2, wenn alle 10ms */
4
static int key1busy;
5
6
    if(key1Active())
7
    {
8
        if(!key1busy)  /* kurz für key1busy==0 */
9
        {
10
            /* neuer Tastendruck, hier Deinen Code einfügen */
11
            ...
12
        }    
13
        key1busy=PRELLZYKLEN;
14
    }
15
    else
16
    {
17
        if(key1busy>0) {key1busy--;}
18
    }
19
20
/* alternativ mit SysTicker, mit Aufruf öfter als Prellzeit */
21
extern int key1Active(void); 
22
extern unsigned int SysTicker; /* erhöht sich um 1 jede MS */
23
24
#define PRELLZEIT 20 
25
static int key1busy;
26
static unsigned int keyTime; 
27
28
    if(key1Active())
29
    {
30
        if(!key1busy) 
31
        {
32
            /* neuer Tastendruck, hier Deinen Code einfügen */
33
            ...
34
        }
35
        key1busy=1;
36
        keyTime=SysTicker;
37
    }
38
    else
39
    {
40
        if(SysTicker-keyTime > PRELLZEIT) {key1busy=0;}
41
    }
Der Code ist nicht schön, nicht getestet, sollte aber prinzipiell und 
ohne Verzögerung funktionieren. Er entprellt, filtert aber keine 
Störungen (Spikes) heraus. Zudem braucht er für jede Taste entsprechende 
Variablen. Das spielt am Anfang aber alles keine Rolle. Wenn PeDas Code 
0,01% an Platz und Zeit braucht, braucht dieser <0,1%.

von kopr (Gast)


Lesenswert?

A. S. schrieb:
> dann geht es relativ einfach gebastelt:

danke ! ich habe zu wenig Ahnung um das zu beurteilen: ist das eine 
angemessene Lösung?

von kopr (Gast)


Lesenswert?

A. S. schrieb:
> einen SysTicker oder eine zyklische Funktion hast

in meinem Fall würde ich diese Funktion durch einen Timer immer wieder 
aufrufen lassen. Ich weiß nämlich nicht, wie die Programmlaufzeiten bei 
mir sind

von kopr (Gast)


Lesenswert?

1
extern int key1Active(void);

wie kann ich das auf eins setzten?
ich dachte erst an soetwas:
1
extern int key1Active(void)
2
{
3
 if (P2IFG & T_Setzen)
4
   key1Active=1;
5
  else
6
  {_NOP();}
7
  
8
}
bekomme ich fehlermeldungen

von kopr (Gast)


Lesenswert?

1
extern int key1Active(void)
2
{
3
 if (P2IFG & T_SET)
4
   return 1;
5
  else
6
  {_NOP();}
7
  
8
}

von A. S. (Gast)


Lesenswert?

kopr schrieb:
>
1
> extern int key1Active(void)
2
> {
3
>  if (P2IFG & T_SET)
4
>    return 1;
5
>   else
6
>   {_NOP();}
7
> 
8
> }
9
>

else return 0;

Mein Beispiel ist ok, aber wenn Du nicht gerade von Pascal kommst, frag 
ruhig öfter nach.

von kopr (Gast)


Lesenswert?

das ist mein Code. es funktioniert nicht. Bevor ich return 0 eingefügt 
habe, hat er das Drücken des Tasters erkannt
1
#include "msp430f5529.h"            // Einbinden der Definitionen
2
#define  LED_X     0x01     // LED (rot) an P1.0
3
#define PRELLZYKLEN 20 /* entsprechend 2, wenn alle 10ms */
4
#define  T_SET     0x02     // Taster an P2.1
5
6
 extern void INIT_UART1(void);
7
 extern void TX_String(unsigned char *cx);
8
static int key1busy;
9
extern int key1Active(void); /* 1 wenn gedrückt, sonst 0 */
10
int main( void )
11
{
12
    WDTCTL = WDTPW + WDTHOLD;   // WatchDogTimer abschalten
13
   INIT_UART1 ();
14
 // -- INIT_Port1
15
  P1SEL &= ~(LED_X);            // Beide sind BIN-IO       
16
  P1DIR |= LED_X;               // LED    = BIN-OUT
17
  P1OUT &= ~(LED_X);            // LED_X = AUS (weil H-aktiv)
18
      // INIT_Port_2
19
    P2SEL  &= ~(T_SET);           // Funktion ist BIN-IO
20
    P2DIR  &= ~(T_SET);           // Taster ist BIN-IN
21
    P2IES  |= T_SET;              // Int. bei neg. Flanke (H-->L)
22
    P2IE   |= (T_SET);           // Beim System.Start noch nicht frei gegeben
23
    P2IFG  &= ~(T_SET);           // Alte Fl. Ereignis löschen
24
    //
25
    P2REN |= T_SET;               // Intern.Widerstand = aktiv
26
    P2OUT |= T_SET;               // Als PullUp eingestellt
27
    
28
  TB0CTL = TBCLR;
29
  TB0CTL = TBSSEL_2 + ID_0 + MC_1;
30
  TB0CCR0 = 10480;    // 10 ms
31
  TB0CCTL0 = CCIE;
32
 
33
_BIS_SR(GIE); 
34
35
  while(1) {_NOP();} 
36
}
37
38
39
#pragma vector = TIMER0_B0_VECTOR
40
__interrupt void TimerB0_0_ISR ()
41
{
42
  /* Block, der zyklisch, z.B. jede ms aufgerufen wird */
43
44
45
    if(key1Active())
46
    {
47
        if(!key1busy)  /* kurz für key1busy==0 */
48
        {
49
            /* neuer Tastendruck, hier Deinen Code einfügen */
50
             TX_String("\nLED\n");
51
             P1OUT ^= (LED_X);
52
        }    
53
        key1busy=PRELLZYKLEN;
54
    }
55
    else
56
    {
57
        if(key1busy>0) {key1busy--;}
58
    }
59
}
60
61
extern int key1Active(void)
62
{
63
 if (P2IFG & T_SET)
64
   return 1;
65
  else
66
  {
67
   return 0;
68
  }
69
}

von kopr (Gast)


Lesenswert?

meine Frage ist auch, ob es in ordnung ist, ein Drücken durch die 
Int.-Flag abzufragen. Alternativ stünde ja die Flankenerkennung zur 
Verfügung

von Joachim B. (jar)


Lesenswert?

kopr schrieb:
> b es in ordnung ist, ein Drücken durch die
> Int.-Flag abzufragen

nicht wenn Taster prellen und das tun die Meisten, die arme CPU kommt ja 
aus den IRQ kaum noch raus wenn diese andauernd durch prellende Taster 
im µs bis ms Takt eintrudeln! Wann soll dann die CPU ihren echten 
Aufgaben nachgehen wenn immer Fehlalarme kommen?

Lese endlich mal Tastenentprellung im Timer IRQ von Dannegger!

: Bearbeitet durch User
von kopr (Gast)


Lesenswert?

Joachim B. schrieb:
> nicht wenn Taster prellen und das tun die Meisten, die arme CPU kommt ja
> aus den IRQ kaum noch raus wenn diese andauernd durch prellende Taster
> im µs bis ms Takt eintrudeln! Wann soll dann die CPU ihren echten
> Aufgaben nachgehen wenn immer Fehlalarme kommen?

wie hat sich A. S. (achs) das dann vorgtestellt?

Joachim B. schrieb:
> Lese endlich mal Tastenentprellung im Timer IRQ von Dannegger!

habe ich. ich würde debounce-makro auf meine Plattform anpassen. Kannst 
du mir dabei helfen?

kopr schrieb:
> Matthias S. schrieb:
>> Eins ist klar, die einzige Anpassung betrifft die I/O des verwendeten
>> Controllers.#include <avr/io.h>
> #define F_CPU 9.6e6
> #include <util/delay.h>
> was ist mit den includes. ist in den Definitionen etwas drin, was ich
> brauche? Habe beim MSP entsprechend andere Defintionen. Was gibts da zu
> beachten?

das war meine erste Frage

von A. S. (Gast)


Lesenswert?

Du darfst den Code nicht im Interrupt laufen lassen!

Der Code gehört in die while-schleife im main!

Im Interrupt (z.b. jede ms) nur den systicker++.

(Und ich vergaß: systicker mit volatile)

von A. S. (Gast)


Lesenswert?

Also:

kopr schrieb:
> while(1) {_NOP();}
> }

stattdessen, wenn in einer Datei:
1
static int key1Active(void); 
2
static volatile unsigned int SysTicker; 
3
#define PRELLZEIT 20 /* bzw (20/x), wenn die Interruptroutine alle x ms aufgerufen wird. */
4
...
5
6
int main(void)
7
{
8
    ...
9
    //while(1) {_NOP();}
10
    while(1) 
11
    {
12
    /* alternativ mit SysTicker, mit Aufruf öfter als Prellzeit */
13
    static int key1busy;
14
    static unsigned int keyTime; 
15
16
        if(key1Active())
17
        {
18
            if(!key1busy) 
19
            {
20
                /* neuer Tastendruck, hier Deinen Code einfügen */
21
                TX_String("\nLED\n");
22
                P1OUT ^= (LED_X);
23
            }
24
            key1busy=1;
25
            keyTime=SysTicker;
26
        }
27
        else
28
        {
29
            if(SysTicker-keyTime > PRELLZEIT) {key1busy=0;}
30
        } 
31
        ...  
32
        /* weiterer Code, der zyklisch notwendig ist ... */ 
33
    }
34
}
35
36
#pragma vector = TIMER0_B0_VECTOR
37
__interrupt void TimerB0_0_ISR ()
38
{
39
    SysTicker++;
40
}
41
42
static int key1Active(void)
43
{
44
    if (P2IFG & T_SET) {return 1;}
45
    return 0;
46
}

Und gerade wenn Du blutiger Anfänger bist, und verschiedene Fragen hast, 
dann poste doch bitte unter einem Namen. Hätten wir gewusst, dass die 
TX_String geschichte von Dir ist, wäre niemand auf die Idee gekommen, 
dass Du PeDas Code verstehen kannst.

Anmerkung: key1Active kannst Du auch ganz weglassen und direkt 
einsetzen:
1
//  if(key1Active())
2
    if(P2IFG & T_SET)

von kopr (Gast)


Lesenswert?

danke dass du dir die Mühe gemacht hast. die Routine funktioniert bei 
leider nicht. Weder toggelt die LED, noch werden die Strings ausgegeben.

A. S. schrieb:
> static int key1Active(void)
> {
>     if (P2IFG & T_SET) {return 1;}
>     return 0;
> }

hab dort auch vorsichtshalber ein
1
 P2IFG &= ~(T_SET);                          // Flanken Ereignis löschen
eingefügt

von Stefan F. (Gast)


Lesenswert?

Wieso ist eigentlich Taster-Entprellung plötzlich das Thema Nummer eins 
hier? Für mich steht der Troll-Alarm bereits auf 80%.

von A. S. (Gast)


Lesenswert?

kopr schrieb:
> danke dass du dir die Mühe gemacht hast. die Routine funktioniert bei
> leider nicht. Weder toggelt die LED, noch werden die Strings ausgegeben.


Funktioniert der Code denn vorher? Oder wenn Du die Funktionen so 
aufrufst?

Was funktioniert denn, und was nicht? Wenn Du nur die LED hast, dann 
mache z.B. folgendes:

Statt Tastenauswertung ein sinnvolles Bit vom SysTicker (mit welcher 
Rate läuft er bei Dir denn jetzt, weisst Du das schon?)
1
static int key1Active(void)
2
{
3
    if(SysTicker & 1024) {return 1;}
4
    return 0;
5
}
Wenn dann die LED sekündlich toggelt, dann laufen zumindest SysTicker 
und die Auswertung. Wenn die LED nur alle 10s toggelt, dann passe das 
entsprechend an

Und gebe den String einmal vor "while(1)" aus, dann weisst Du, ob Du da 
versehentlich irgendwas zerschossen hast.

Und kennst Du die Funktion TX_String? Wenn die blockierend läuft, dann 
hätte die nie in einer Interruptroutine sein dürfen. Daher nochmal:

A. S. schrieb:
> Schreib mal, was Du hast und kannst.


kopr schrieb:
> hab dort auch vorsichtshalber ein
>  P2IFG &= ~(T_SET);                          // Flanken Ereignis löschen
> eingefügt

und warum hast Du das vorher nicht gebraucht? Dieser Teil kommt von Dir, 
nicht von mir. Poste mal den ganzen Code. Gerne als Anhang.

von kopr (Gast)


Lesenswert?

1
#include "msp430f5529.h"            // Einbinden der Definitionen
2
#define  LED_X     0x01     // LED (rot) an P1.0
3
#define PRELLZYKLEN 20 /* entsprechend 2, wenn alle 10ms */
4
#define  T_SET     0x02     // Taster an P2.1
5
6
 extern void INIT_UART1(void);
7
 extern void TX_String(unsigned char *cx);
8
static int key1busy;
9
extern int key1Active(void); /* 1 wenn gedrückt, sonst 0 */
10
int main( void )
11
{
12
    WDTCTL = WDTPW + WDTHOLD;   // WatchDogTimer abschalten
13
   INIT_UART1 ();
14
 // -- INIT_Port1
15
  P1SEL &= ~(LED_X);            // Beide sind BIN-IO       
16
  P1DIR |= LED_X;               // LED    = BIN-OUT
17
  P1OUT &= ~(LED_X);            // LED_X = AUS (weil H-aktiv)
18
      // INIT_Port_2
19
    P2SEL  &= ~(T_SET);           // Funktion ist BIN-IO
20
    P2DIR  &= ~(T_SET);           // Taster ist BIN-IN
21
    P2IES  |= T_SET;              // Int. bei neg. Flanke (H-->L)
22
    P2IE   |= (T_SET);           // Beim System.Start noch nicht frei gegeben
23
    P2IFG  &= ~(T_SET);           // Alte Fl. Ereignis löschen
24
    //
25
    P2REN |= T_SET;               // Intern.Widerstand = aktiv
26
    P2OUT |= T_SET;               // Als PullUp eingestellt
27
    
28
  TB0CTL = TBCLR;
29
  TB0CTL = TBSSEL_2 + ID_0 + MC_1;
30
  TB0CCR0 = 10480;    // 10 ms
31
  TB0CCTL0 = CCIE;
32
 
33
_BIS_SR(GIE); 
34
35
  while(1) {_NOP();} 
36
}
37
38
39
#pragma vector = TIMER0_B0_VECTOR
40
__interrupt void TimerB0_0_ISR ()
41
{
42
  /* Block, der zyklisch, z.B. jede ms aufgerufen wird */
43
44
45
    if(key1Active())
46
    {
47
        if(!key1busy)  /* kurz für key1busy==0 */
48
        {
49
            /* neuer Tastendruck, hier Deinen Code einfügen */
50
             TX_String("\nLED\n");
51
             P1OUT ^= (LED_X);
52
        }    
53
        key1busy=PRELLZYKLEN;
54
    }
55
    else
56
    {
57
        if(key1busy>0) {key1busy--;}
58
    }
59
}
60
61
extern int key1Active(void)
62
{
63
 if (P2IFG & T_SET)
64
   return 1;
65
  else
66
  {
67
   _NOP();
68
  }
69
}
der code hat das Drücken des tasters erkannt

von kopr (Gast)


Lesenswert?

A. S. schrieb:
> Und gebe den String einmal vor "while(1)" aus, dann weisst Du, ob Du da
> versehentlich irgendwas zerschossen hast.

habe ich, das passt

A. S. schrieb:
> Statt Tastenauswertung ein sinnvolles Bit vom SysTicker (mit welcher
> Rate läuft er bei Dir denn jetzt, weisst Du das schon?)

ist damit die 25 MHz der CPU gemeint?

A. S. schrieb:
> Wenn dann die LED sekündlich toggelt, dann laufen zumindest SysTicker
> und die Auswertung. Wenn die LED nur alle 10s toggelt, dann passe das
> entsprechend an

toggelt garnicht

A. S. schrieb:
> Und kennst Du die Funktion TX_String? Wenn die blockierend läuft, dann
> hätte die nie in einer Interruptroutine sein dürfen. Daher nochmal:

hatte in anderen Programmen kein Problem mit String in ISR

von kopr (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Wieso ist eigentlich Taster-Entprellung plötzlich das Thema Nummer eins
> hier? Für mich steht der Troll-Alarm bereits auf 80%.

meinst du deswegen:
Beitrag "Debounce-Makro von Peter Dannegger - MSP430"

ist kein Troll, schade das du mir da nicht hilfst. Hätte Hilfe bitter 
nötig

von A. S. (Gast)


Lesenswert?

kopr schrieb:
> der code hat das Drücken des tasters erkannt

Und wie sieht Dein Code aus, der nicht funktioniert?

Übrigens, das _NOP hat hier keine Funktion. Du kannst den else Zweig 
weglassen. Dann siehst Du auch, dass die Funktion ohne Tastendruck 
nichts zurückliefert (kein return hat), was

a) immer eine Warnung geben sollte (hast Du noch mehr Warnungen?)
b) beliebigen Müll zurückgeben kann.

kopr schrieb:
> extern int key1Active(void)
> {
>  if (P2IFG & T_SET)
>    return 1;
>   else
>   {
>    _NOP();
>   }
> }

von Stefan F. (Gast)


Lesenswert?

kopr schrieb:
> schade das du mir da nicht hilfst

Ich halte mich da lieber raus, weil ich Peters Code noch nie brauchte. 
Noch programmiere solche Sachen selber.

von kopr (Gast)


Angehängte Dateien:

Lesenswert?

A. S. schrieb:
> a) immer eine Warnung geben sollte (hast Du noch mehr Warnungen?)

ne habe keine Warnungen, mit return 0 hat der den Taster nicht mehr 
erkannt. Echt komisch.

Im Anhang der Code, der nicht funktioniert

von kopr (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> ch halte mich da lieber raus, weil ich Peters Code noch nie brauchte.
> Noch programmiere solche Sachen selber.

naja, es geht um die Frage, wie ich den Code von der einen Plattform auf 
die andere Übertrage. Mir macht das Schwierigkeiten

von Stefan F. (Gast)


Lesenswert?

kopr schrieb:
> ne habe keine Warnungen

Dann aktiviere die mal. Du wirst sie brauchen.

von A. S. (Gast)


Lesenswert?

kopr schrieb:
> ne habe keine Warnungen, mit return 0 hat der den Taster nicht mehr
> erkannt. Echt komisch.
>
> Im Anhang der Code, der nicht funktioniert

Nein, nicht komisch. Da sind mehrere Stellen, die einfach Müll sind. 
Sowohl in Deinem ersten, als auch in diesem Code. Von daher ist es sehr 
wahrscheinlich, dass er auch nicht tut, was er soll. Schalte Warnungen 
ein.

kopr schrieb:
> extern int key1Active(void)
> {
>  if (P2IFG & T_SET)
>    return 1;
>   else
>   {
>    _NOP();
>   }
> }

Hier passiert müll. Vermutlich liefert der Tastendruck nicht "T_SET" 
gesetzt, weil er z.B. an Pin3 ist und nicht Pin1. Dein Code funktioniert 
nämlich dann trotzdem. Ein return 0 repariert diesen Fehler. Aber wenn 
der Fehler das Feature war...

> if (P2IFG & T_SET) {return 1;  P2IFG &= ~(T_SET); }  // Flanken Ereignis löschen
Verstehst Du, was da passieren soll? Versuche das selbst zu ergründen 
und schalte die Warnungen ein, bis Du das verstehst. Das sind wirkliche 
Grundlagen, da ist Tastenentprellung Hightech gegen.

Und Frage Dich, was an der Routine anders ist, dass Du es im 
funktionierenden Code nicht gebraucht hast.

Bringe die Tastenauswertung zum laufen, dann wird der Rest 
funktionieren. Notfalls schalte die LED ein, wenn die Taste gedrückt 
ist, und aus, wenn sie es nicht ist
1
int key1Active(void)
2
{
3
    if (P2IFG & T_SET)
4
    {
5
        P1OUT |= (LED_X);
6
        P2IFG &= ~(T_SET); /* falls notwendig */ 
7
        return 1;
8
    }
9
    else
10
    {
11
        P1OUT &= ~(LED_X);
12
    }
13
    return 0;
14
}

von kopr (Gast)


Lesenswert?

ja ich habe eine warnung ohne return haha. Aber in dem Code (Anhang) 
sind keine Warnungen

von kopr (Gast)


Lesenswert?

okay ich überarbeite alles

von kopr (Gast)


Lesenswert?

1
#include "msp430f5529.h"            // Einbinden der Definitionen
2
#define  LED_X     0x01     // LED (rot) an P1.0
3
#define PRELLZYKLEN 20 /* entsprechend 2, wenn alle 10ms */
4
#define  T_SET     0x02     // Taster an P2.1
5
6
 extern void INIT_UART1(void);
7
 extern void TX_String(unsigned char *cx);
8
static int key1busy;
9
extern int key1Active(void); /* 1 wenn gedrückt, sonst 0 */
10
int main( void )
11
{
12
    WDTCTL = WDTPW + WDTHOLD;   // WatchDogTimer abschalten
13
   INIT_UART1 ();
14
 // -- INIT_Port1
15
  P1SEL &= ~(LED_X);            // Beide sind BIN-IO       
16
  P1DIR |= LED_X;               // LED    = BIN-OUT
17
  P1OUT &= ~(LED_X);            // LED_X = AUS (weil H-aktiv)
18
      // INIT_Port_2
19
    P2SEL  &= ~(T_SET);           // Funktion ist BIN-IO
20
    P2DIR  &= ~(T_SET);           // Taster ist BIN-IN
21
    P2IES  |= T_SET;              // Int. bei neg. Flanke (H-->L)
22
    P2IE   |= (T_SET);           // Beim System.Start noch nicht frei gegeben
23
    P2IFG  &= ~(T_SET);           // Alte Fl. Ereignis löschen
24
    //
25
    P2REN |= T_SET;               // Intern.Widerstand = aktiv
26
    P2OUT |= T_SET;               // Als PullUp eingestellt
27
    
28
  TB0CTL = TBCLR;
29
  TB0CTL = TBSSEL_2 + ID_0 + MC_1;
30
  TB0CCR0 = 10480;    // 10 ms
31
  TB0CCTL0 = CCIE;
32
 
33
_BIS_SR(GIE); 
34
35
  while(1) {_NOP();} 
36
}
37
38
39
#pragma vector = TIMER0_B0_VECTOR
40
__interrupt void TimerB0_0_ISR ()
41
{
42
  /* Block, der zyklisch, z.B. jede ms aufgerufen wird */
43
44
45
    if(key1Active())
46
    {
47
        if(!key1busy)  /* kurz für key1busy==0 */
48
        {
49
            /* neuer Tastendruck, hier Deinen Code einfügen */
50
             TX_String("\nLED\n");
51
             P1OUT ^= (LED_X);
52
        }    
53
        key1busy=PRELLZYKLEN;
54
    }
55
    else
56
    {
57
        if(key1busy>0) {key1busy--;}
58
    }
59
}
60
61
extern int key1Active(void)
62
{
63
 if ((P2IN & 0x02) == 1)
64
   return 1;
65
  else
66
  {
67
   return 0;
68
  }
69
}

die Flanke wurde in anderen programmen immer gefunden, also kann es 
nicht daran liegen. Es funktioniert immer noch nicht

von A. S. (Gast)


Lesenswert?

kopr schrieb:
> if ((P2IN & 0x02) == 1)

Die Zeile ist auch falsch.
Entweder
if ((P2IN & 0x02) == 0x02)

Oder

if ((P2IN & 0x02))

von kopr (Gast)


Lesenswert?

A. S. schrieb:
>> if ((P2IN & 0x02) == 1)

oder

A. S. schrieb:
> if ((P2IN & 0x02))

wo ist der Unterschied?

von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

kopr schrieb:
> habe ich. ich würde debounce-makro auf meine Plattform anpassen. Kannst
> du mir dabei helfen?

fange erst mal an das eine LED leuchtet
Dann sehe zu das dein IRQ Programm alle 10ms aufgerufen wird!

Baustelle, arbeite gerade daran, aber das lief in anderen Programmen 
schon.

Es fehlt noch Port einlesen, Variablen zur Timerzählung, jede IRQ 
Zählung löst in der main loop eine andere Aktion aus.

Etwas musst du dir auch schon selber erarbeiten, es ist dein Chip und 
Beispiel Script zum Timmer für diesen nannte ich schon.

von kopr (Gast)


Lesenswert?

vielen Dank Joachim, ich habe inzwischen eine funktionierende, eigene 
Routine

von kopr (Gast)


Lesenswert?

kopr schrieb:
> A. S. schrieb:
>>> if ((P2IN & 0x02) == 1)
>
> oder
>
> A. S. schrieb:
>> if ((P2IN & 0x02))
>
> wo ist der Unterschied

auch das hat sich geklärt

von Joachim B. (jar)


Lesenswert?

kopr schrieb:
> vielen Dank Joachim, ich habe inzwischen eine funktionierende, eigene
> Routine

auch OK
jeder wie er mag!

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.