Forum: Mikrocontroller und Digitale Elektronik Entprellung Taster


von Isildur (Gast)


Lesenswert?

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

von Max H. (hartl192)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

Isildur schrieb:
> Der Code sieht in etwa wie folgt aus:
> unsigned char debounce(IoPortId port, unsigned int bits)

Da hilft nur wegschmeißen und was funktionierendes nehmen 
(Timerinterrupt).

von Isildur (Gast)


Lesenswert?

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
}

von Karl H. (kbuchegg)


Lesenswert?

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?

von Isildur (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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.

von Isildur (Gast)


Lesenswert?

> 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!

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.