Entprellung Taster

Gast #3877529
Hallo ich würde gerne für einen PIC32 die Tasten enptrellen.
Als Beispielcode habe ich mir den COde aus dem Forum rausgesucht. Dieser 
ist eigentlich auch verständlich. Weiterhin habe ich versucht diesen auf 
den PIC anzugelichen. Der Code sieht in etwa wie folgt aus:
1
unsigned char debounce(IoPortId port, unsigned int bits)
2
{
3
    DelayMs(50);
4
    DelayMs(50);
5
    if(!PORTReadBits(port, bits))
6
    {
7
        if(PORTReadBits(port, bits))
8
        {
9
            DelayMs(50);
10
            DelayMs(50);
11
            return 1;
12
        }
13
    }
14
    return 0;
15
}

Das funktioniert leider noch nicht wie gewünscht.
Wenn ich den Taster über if(!PORTReadBits(IOPORT_C, BIT_3)) anfrage 
funktioniert es hingegen tadellos!

Falls Jemand schon mit dem PIC gearbeitet hat oder wem direkt etwas am 
Code auffällt wäre ich dankbar
Isildur schrieb:
> if(!PORTReadBits(port, bits))
>     {
>         if(PORTReadBits(port, bits))
>         {
Hier hast du nur ein Zeitfenster von wenigen µs, das du mit deiner 
steigenden Flanke treffen musst damit sie erkannt wird.
Wird die Funktion eigentlich periodisch aufgerufen?

Ist es ein Taster mit Pullup oder Pulldown?
Gast
Ich hab versucht beim PIC 32 die Delay_ms über TIMRE zu realisieren 
(nach BeispielCode): Wenn ich den Timer bis 39062 hochzählen lasse 
sollte ich 1 s haben, wenn ich folglich nur bis 39 hochzähle 1ms!

Selbst wenn ich 1s versuche über eine toogelnde LED zu referenzieren, 
blinkt diese deutlich schneller.

Hat Jemand Erfahrung mit Delay Routinen für den PIC 32 oder kann kemand 
was zu der Realisierung mit Timer unten sagen?
1
// Configure the Timer 1 interrupt handler
2
void __ISR(_TIMER_1_VECTOR, ipl2) Timer1Handler(void)
3
{
4
    // Clear the interrupt flag
5
    INTClearFlag(INT_T1);
6
    period_elapsed++;
7
    if (period_elapsed == delay_period)
8
    {
9
        delay_over = 1;
10
        CloseTimer1();
11
    }
12

13
     // Toggle LEDs on the Explorer-16
14
//    mPORTDToggleBits(BIT_2 | BIT_1 | BIT_0);
15
}
16

17

18

19
void start_Timer()
20
{
21

22
    // Configure Timer 1 using PBCLK as input, 1:256 prescaler
23
    // Period matches the Timer 1 frequency, so the interrupt handler
24
    // will trigger every one second...
25
    // Timer1Clock = 80 MHz / (256*8) = Fosc / (PB_Div*Prescale) = 39062 Hz -> 39062 wird Interrupt pro Sek. ausgeführt
26
    // (10MHz PBCLK / 256 = 39,062KHz Timer 1 clock)
27
    // 39062 für 1 s
28
    // Periode = 39 für 1 ms
29
    OpenTimer1(T1_ON | T1_SOURCE_INT | T1_PS_1_256, 39);
30

31
    // Set up the timer interrupt with a priority of 2
32
    INTEnable(INT_T1, INT_ENABLED);
33
    INTSetVectorPriority(INT_TIMER_1_VECTOR, INT_PRIORITY_LEVEL_2);
34
    INTSetVectorSubPriority(INT_TIMER_1_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
35

36
    // Enable multi-vector interrupts
37
    INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
38
    INTEnableInterrupts();
39

40

41
}
42

43
void delay_ms(unsigned char ms)
44
{
45
    delay_period = ms;
46
    period_elapsed = 0;
47
    delay_over = 0;
48
    start_Timer();
49
    while (!delay_over)
50
    {
51
        Nop(); // do nothing
52
    }
53
}
Isildur schrieb:

> Selbst wenn ich 1s versuche über eine toogelnde LED zu referenzieren,
> blinkt diese deutlich schneller.

Kannst du dieses 'deutlich' schneller mal etwas quantifizieren?
2 mal, 5 mal, 8 mal, 16 mal?

Wenn du das nicht gut schätzen kannst, dann geh halt mal länger als 1s 
und zähl mit der Uhr in der Hand, wieviele Blinker du in zb 30 Sekunden 
siehst.


>     // Timer1Clock = 80 MHz / (256*8) = Fosc / (PB_Div*Prescale) = 39062
> Hz -> 39062 wird Interrupt pro Sek. ausgeführt

Ohne jetzt mit so ein PIC jemals etwas zu tun gehabt zu haben, aber die 
8 kann ich im Code zb nicht entdecken. Sind die eine Konstante?
Ist dein 'deutlich schneller' zb ein Faktor 8?
Gast
Sie haben Recht, der Kommentar
1
// Timer1Clock = 80 MHz / (256*8) = Fosc / (PB_Div*Prescale) = 39062 Hz -> 39062 wird Interrupt pro Sek. ausgeführt

ist fehlerhaft. Die 8 hat damit nichts zu tun. Der Takt müsste sich über 
10 MHz / 256 berechnen. -> Daher bis 39062 hochzählen für 1s, zumindest 
in der Theorie. Problem ist, wenn ich dieses Wert beispielsweise 
ver60fache "flackert" die LED immer noch mit derselben Frequenz. 
Vermutlich hat sich noch ein Fehler in den Timer Einstellungen 
eingeschlichen
Isildur schrieb:
> Der Code sieht in etwa wie folgt aus:

Sowas ist ein ganz grobes Foul.
Code zu dem man Fragen hat, darf nie in etwa sein.
Wie soll Dir denn jemand helfen, wenn Du ungetesteten Fantasiecode 
einstellst?


Isildur schrieb:
> Ich hab versucht beim PIC 32 die Delay_ms über TIMRE zu realisieren

Dadurch wird die Routine auch nicht besser. Das Problem sind die 
100..200ms Zwangspause bei jedem Aufruf, das ist und bleibt Quark.
Gast
> Dadurch wird die Routine auch nicht besser. Das Problem sind die
> 100..200ms Zwangspause bei jedem Aufruf, das ist und bleibt Quark.

Ok, das hilft mir schon einmal. Die Idee hab ich ja hier aus dem Forum 
und sogar schon einmal mit einem Atmel erfolgreich realisiert. Deswegen 
war ich verwundert, dass ich bei den PICs scheinbar auf Schwierigkeiten 
stoße und daraus geschlossen, dass der Fehler bei der Delay Funktion 
liegt und nicht bei der eigentlichen Funktionsrealisierung!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.