Forum: Mikrocontroller und Digitale Elektronik Erhöhte Frequenz der T0-Compare-Ints durch T2-Int-Flag?


von Kai H. (jabba80)


Lesenswert?

Hallo...

ich bastel grade an meinem ATMEGA16 and habe mit einem sehr seltsamen 
Phänomen zu kämfen:

Timer0 läuft im CTC-Mode
Timer1 auf beidem Kanälem im PWM-Mode
Timer2 ebenfalls PWM-Mode

Code:
-----
1
#include "cpu.h"
2
#define DefaultWerte(p)    (((EEPromRead(p*2))*256)+(EEPromRead((p*2)+1)))
3
4
void Init_CPU( void ) 
5
{
6
    /*--- Initialise Pins ---*/
7
  DDRA=0xff;
8
  DDRB=0xBB;
9
  DDRC=0xff;
10
  DDRD=0xf3;
11
}
12
13
void initTimers(void){
14
    //-Timer 0 für Timer-Nutzung initialisieren-------------------------------//
15
  OCR0=0xb4;          // OCR0 als Komparator
16
  setbit(TIMSK,OCIE0);    // Interrupt bei Komperator-Match (jede 1/20 sek)
17
    clearbit(TCCR0,WGM00);  // CTC-mode
18
      setbit(TCCR0,WGM01);   // top=OCR0
19
      setbit(TCCR0,CS02);   // clock select clk/1024
20
    clearbit(TCCR0,CS01);  
21
      setbit(TCCR0,CS00);  
22
  clearbit(TCCR0,COM01);  //Normal port operation, OC0 disconnected.
23
    clearbit(TCCR0,COM00);
24
  //------------------------------------------------------------------------//
25
 
26
  //-Timer 1 für PWM-Nutzung initialisieren---------------------------------//
27
      setbit(TCCR1B,WGM13); // mode 15, Fast-PWM
28
      setbit(TCCR1B,WGM12); // update at bottom, tov1 flag set on bottom
29
      setbit(TCCR1A,WGM11); // top = ICR1
30
  clearbit(TCCR1A,WGM10);
31
    clearbit(TCCR1B,CS12);  // Prescaler auf 64
32
      setbit(TCCR1B,CS11);
33
    clearbit(TCCR1B,CS10);
34
    ICR1 = 0x017F;      // TOP = 383 entspr. ~1200Hz
35
  //----------------------------------//
36
    // OC1A als PWM-Port setzen (LCD-KONTRAST)
37
      setbit(TCCR1A,COM1A1); //non-inverting PWM-Mode
38
    clearbit(TCCR1A,COM1A0);  
39
    OCR1A = 383 - (DefaultWerte(8)*(383/100));  //Vergleichswert steuert Spannung am Ausgang
40
    //----------------------------------//
41
    // OC1B als PWM-Port setzen (LCD-Illum)
42
      setbit(TCCR1A,COM1B1);  // non-inverting PWM-Mode
43
    clearbit(TCCR1A,COM1B0);  
44
    OCR1B = (DefaultWerte(8)*(383/100));  //Vergleichswert steuert Spannung am Ausgang
45
  //------------------------------------------------------------------------//
46
    
47
    
48
    //-Timer 2 für PWM-Nutzung initialisieren---------------------------------//
49
      setbit(TCCR2,WGM20);   // fast pwm
50
      setbit(TCCR2,WGM21);   // top=0xff
51
    clearbit(TCCR2,CS22);   // clock select clk/8
52
      setbit(TCCR2,CS21);    // clock select clk/8
53
    clearbit(TCCR2,CS20);    // clock select clk/8
54
    //----------------------------------//
55
  // OC2 als PWM-Port setzen (PWM-Output-Mode)
56
    setbit(TCCR2,COM21);
57
    clearbit(TCCR2,COM20);
58
    OCR2   = ((DefaultWerte(8)*255)/100); //Vergleichswert steuert Spannung am Ausgang
59
                      //Initial aus EEprom!
60
  //------------------------------------------------------------------------//  
61
}
62
63
/* Timer2 zwischen PWM-Mode für analogen Ausgang und Toggle-Mode für 
64
 * DSI-Signal umschalten*/
65
void switchTimer2(unsigned char mode){
66
  switch (mode){
67
    case 0:          // ------PWM-Mode------
68
      clearbit(TCCR2,CS22);   // Clock=0
69
      clearbit(TCCR2,CS21);    // -> Timer off
70
        clearbit(TCCR2,CS20);    // 
71
        setbit(TCCR2,WGM20);   // fast pwm
72
        setbit(TCCR2,WGM21);   // top=0xff -> ~1900Hz
73
        setbit(TCCR2,COM21);  // non-inverting-mode
74
      clearbit(TCCR2,COM20);
75
      OCR2 = ((DefaultWerte(8)*255)/100); //Vergleichswert steuert Spannung am Ausgang
76
      clearbit(TIMSK,OCIE2);
77
      clearbit(TCCR2,CS22);   // clock select clk/8
78
        setbit(TCCR2,CS21);    // clock select clk/8
79
        clearbit(TCCR2,CS20);    // clock select clk/8
80
    break;
81
82
    case 1:          //-------DSI-Mode------
83
      clearbit(TCCR2,CS22);   // Clock=0
84
      clearbit(TCCR2,CS21);    // -> Timer off
85
        clearbit(TCCR2,CS20);    // 
86
      clearbit(TCCR2,WGM20);   // CTC-timer-mode
87
        setbit(TCCR2,WGM21);   // top=OCR2 -> 833us
88
      clearbit(TCCR2,COM21);  // OC2 disconnected, normal Port-Operation
89
      clearbit(TCCR2,COM20);
90
      clearbit(PORTD,PD7);
91
      OCR2 = 0x30;
92
        setbit(TIMSK,OCIE2);
93
        setbit(TCCR2,CS22);   // clock select clk/64
94
      clearbit(TCCR2,CS21);    // clock select clk/64
95
        clearbit(TCCR2,CS20);    // clock select clk/64
96
97
    default:
98
      break;
99
  }
100
}

Das läuft soweit ganz gut, jedoch will ich jetzt zur laufzeit Timer2 
umkonfigurieren und in den CTC-Mode schalten (siehe 'switchTimer2()' im 
Code). Wenn das passiert, dann bekomme ich auch Compare-Ints vom T2, 
jedoch erhöht sich die Frequenz der Compare-Ints von T0 erheblich, so 
dass sie von dort ausgeführten Entprell-Anweisungen für meine 3 Taster 
am Gerät ihren Effekt verlieren.

Wie kommt das? Weiß jemand rat??
Komme echt nichtmehr weiter..... würde mich über jeden Rat freuen!

Gruß
Kai

von Johannes M. (johnny-m)


Lesenswert?

Wenn Du nur Register von Timer 2 änderst, gibt es keinen Grund, warum 
sich bei Timer 0 irgendwas ändern sollte. Da das nur ein Teil des Codes 
ist, kann man dazu nicht mehr sagen.

Und bitte gewöhne Dir schnellstens die Schreibweise mit setbit / 
clearbit wieder ab! Die Makros kann man benutzen, wenn man mal ein 
einzelnes Bit in einem Register setzen oder löschen will, aber bei der 
Initialisierung ist das Murks hoch 10! Zumal der µC dann auch jedes Bit 
einzeln setzt, was erstens den Code aufbläht und außerdem zu lustigen 
Nebeneffekten führen kann.

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.