Forum: Compiler & IDEs Entprellroutine von Peter in Code einfügen, aber wie?


von Mathias O. (m-obi)


Lesenswert?

Hallo,

ich möchte gerne die Entprellroutine von Peter D. verwenden. Aber wie 
füge ich die bei mir ein. Kann man mehrere ISR in einem Code verwenden, 
weil ich hab schon eine und in der Entprellroutine ist ja auch eine?
1
// ATmega16 @ 16MHz
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
#define Taster_1 (PIND&(1<<PD2))
8
#define Taster_2 (PIND&(1<<PD3))
9
#define Taster_3 (PIND&(1<<PD4))
10
11
uint8_t var1 = 0;
12
uint8_t var2 = 0;
13
14
ISR(TIMER0_OVF_vect)
15
{  
16
  PORTA = 0xff;
17
}
18
19
20
int main(void)
21
{
22
    
23
  DDRA = 0b11111111;
24
  DDRB = 0b11111111;
25
  DDRC = 0b11111111;
26
  DDRD = 0b11100011;
27
  
28
  TCCR0 |= (1<<CS02);      // Prescaler: 256
29
  //TCCR0 |= (1<<CS00)|(1<<CS02);  // Prescaler: 1024
30
  TIMSK |= (1<<TOIE0);
31
  
32
  sei();
33
34
  while(1)
35
  {     
36
    if (Taster_1 && TCNT0 == 255)
37
    {
38
    var2++;
39
    if (var2 == 50)
40
    {
41
      var1++;
42
      var2 = 0;
43
    }
44
    }
45
    
46
    if (TCNT0 == var1) 
47
    {
48
      PORTA = 0x00;
49
    }
50
      
51
    }
52
}

von Karl H. (kbuchegg)


Lesenswert?

Mathias O. wrote:
> Hallo,
>
> ich möchte gerne die Entprellroutine von Peter D. verwenden. Aber wie
> füge ich die bei mir ein. Kann man mehrere ISR in einem Code verwenden,
> weil ich hab schon eine und in der Entprellroutine ist ja auch eine?

Du musst 2 Fälle unterscheiden:

* wenn deine Timereinstellung (Vorteiler) gravierend von der der 
Entprellerei abweicht, dann muss eines der beiden Subsysteme auf einen 
anderen Timer ausweichen. Das ist aber nur notwendig, wenn die 
Overflowzeiten gravierend voneinander abweichen.

* Wenn die Einstellungen so halbwegs zusammenpassen, und das tun sie 
eigentlich meistens bis oft, dann führst du ganz einfach die Inhalte 
deiner ISR und der 'Entprell'-ISR zusammen. Unter Umständen musst du die 
Berechnung des Preload anpassen. Ob die ISR alle 10ms oder alle 8 oder 5 
oder 15 aufgerufen wird, ist für die Entprellung relativ egal.
1
ISR(TIMER0_OVF_vect)
2
{
3
  //
4
  // der Teil, der für die Entprellung zuständig ist
5
  //
6
  static uint8_t ct0, ct1, rpt;
7
  uint8_t i;
8
 
9
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
10
 
11
  i = key_state ^ ~KEY_PIN;                       // key changed ?
12
  ct0 = ~( ct0 & i );                             // reset or count ct0
13
  ct1 = ct0 ^ (ct1 & i);                          // reset or count ct1
14
  i &= ct0 & ct1;                                 // count until roll over ?
15
  key_state ^= i;                                 // then toggle debounced state
16
  key_press |= key_state & i;                     // 0->1: key press detect
17
 
18
  if( (key_state & REPEAT_MASK) == 0 )            // check repeat function
19
     rpt = REPEAT_START;                          // start delay
20
  if( --rpt == 0 ){
21
    rpt = REPEAT_NEXT;                            // repeat delay
22
    key_rpt |= key_state & REPEAT_MASK;
23
  }
24
25
  //
26
  // und was sonst noch in dieser ISR zu geschehen hat
27
  //
28
   PORTA = 0xff;
29
}

von Mathias O. (m-obi)


Lesenswert?

Anderer Timer heißt dann Timer1?

von Micha (Gast)


Lesenswert?

>Anderer Timer heißt dann Timer1?
Oder Timer 2, oder ...
In welchem Intervall wird denn deine
1
ISR(TIMER0_OVF_vect)
aufgerufen?

von Karl H. (kbuchegg)


Lesenswert?

Micha wrote:
>>Anderer Timer heißt dann Timer1?
> Oder Timer 2, oder ...
> In welchem Intervall wird denn deine
>
1
ISR(TIMER0_OVF_vect)
> aufgerufen?

Du bist gemein :-)
Wäre ja auch zu einfach, diese Zeit einfach mal auszurechnen.

von Mathias O. (m-obi)


Lesenswert?

Wenn ich jetzt genau gerechnet habe, mit 16 MHz und einen Prescaler von 
256, habe ich 4080µs pro Intervall von 0 bis 255.

von Karl H. (kbuchegg)


Lesenswert?

Gut. Auf diesen Zahlenwert bin ich auch gekommen.
4080 µs sind knapp 4ms. Was sagt dir das zum Thema Entprellung?

Hinweis: Schmeiss den Timer Reload auf 10ms in der ISR raus und alles 
ist gut.

von Mathias O. (m-obi)


Lesenswert?

Du meinst also ich soll dies
1
TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
rausnehmen und den Rest einfach übernehmen?

Kann mir denn jemand auchmal erklären was der Code macht? Ich hab ja mal 
gelernt, Punktrechnung geht vor Strichrechnung...

von Micha (Gast)


Lesenswert?

>Du bist gemein :-)
Nö. Nur zu faul... ;-)

von Micha (Gast)


Lesenswert?

>Du meinst also ich soll dies
>TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
>rausnehmen und den Rest einfach übernehmen?
Jep.

>Kann mir denn jemand auchmal erklären was der Code macht?
Das wird in dem Thread, aus dem du den Code hast (weiter unten) erklärt.

von Karl H. (kbuchegg)


Lesenswert?

Mathias O. wrote:

> Kann mir denn jemand auchmal erklären was der Code macht? Ich hab ja mal
> gelernt, Punktrechnung geht vor Strichrechnung...

Ja.
Genau das macht er. Punkt vor Strich rechnen.
Schmeis den Taschenrechner an, setz deine Zahlenwerte ein und sieh nach 
was rauskommt. Dann überleg dir was es wohl für den nächsten Überlauf 
des Timers zeitmässig bedeuten könnte, wenn man diesen Wert in das 
Timerregister lädt und den Timer von dort wegzählen lässt.
Hinweis: Du brauchst dazu das wissen wie lange es dauert, bis der Timer 
um 1 weitergezählt hat. Und du brauchst das Wissen, das für den Timer -1 
dasselbe ist wie 254, -2 dasselbe wie 253, -3 dasselbe wie 252 etc.

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.