Forum: Mikrocontroller und Digitale Elektronik Timer A und B verwenden


von Mathie (Gast)


Lesenswert?

Hallo Leute,

i versuche gerade jede Sekunde den CCR Werte des Timer A mit Hilfe des 
Timer B zu erhöhen. 1 sek CCR2 z.b 10 , 2 sek ccr2 z.B 20 usw... Der 
Controller wird mit ACLK für die Erzeugung von Timer B verwendet.

Doch irgendwie funktioniert dass nicht so ganz wia man´s möchte ?
1
unsigned int volatile lichtsteuerung = 0;
2
3
//Timer A
4
  
5
  P1DIR |= BIT3;                            // P1.2 and P1.3 output
6
  P1SEL |= BIT3;                            // P1.2 and P1.3 TA1/2 otions
7
  CCR0 = 128;                               // PWM Period/2
8
  CCTL2 = OUTMOD_6;                         // CCR2 toggle/set
9
  TACTL |= TASSEL_2 + MC_3 + TAIE;          // SMCLK, up-down mode

1
//Timer B
2
  
3
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
4
  P5DIR |= BIT7;                            // Set P1.0 to output direction
5
  TBCCTL0 = CCIE;                           // TRCCR0 interrupt enabled
6
  TBCCR0 = 16000-1;
7
  TBCTL |= TBSSEL_1 + MC_1 + TAIE;           // ACLK, upmode

1
// Timer B0 interrupt service routine
2
#pragma vector=TIMERB0_VECTOR
3
__interrupt void Timer_B (void)
4
{
5
    lichtsteuerung = lichtsteuerung + 10;  //Wert erhöhen
6
    CCR2 = lichtsteuerung;
7
      
8
}


mfg Mathie

von Forennutzer (Gast)


Lesenswert?

Erfahrene Glaskugelbenutzer und Kenner der µC-Szene wissen 
wahrscheinlich sofort, von welchem Prozessor du sprichst.
Den anderen würde es vielleicht klarer, wenn du es erwähnen würdest ;-)

von Mathie (Gast)


Lesenswert?


von Mathie (Gast)


Lesenswert?

Worin könnte der Fehler sein ?
I habs nochmal probiert aber funktioniert einfach nicht. Mir kommt es so 
vor dass der Interrrupthandler nie aufgerufen wird ?

mfg

von Max G. (l0wside) Benutzerseite


Lesenswert?

Mathie schrieb:
> Worin könnte der Fehler sein ?
> I habs nochmal probiert aber funktioniert einfach nicht. Mir kommt es so
> vor dass der Interrrupthandler nie aufgerufen wird ?

Da Du P5.7 ohnehin auf Ausgang setzt, lasse doch den Ausgang mal 
toggeln, wenn die ISR aufgerufen wird. Aus Deiner Beschreibung schließe 
ich, dass P1.3 schon toggelt, aber sich das PWM-Verhältnis nicht ändert.

Außerdem fällt mir auf:
- Ich sehe keine Initialisierung der Clocks
- CCR2 hast Du anfangs nicht gesetzt - woher kommt dann das initiale 
PWM-Tastverhältnis?
- Bist Du sicher, dass die 16000-1 ein sinnvoller Wert sind? Wenn die 
Clock von Timer B mit 16 MHz läuft, wird die ISR alle Millisekunde 
aufgerufen, und Du bist in kürzester Zeit am Anschlag.

Lies doch mal nach einer Sekunde den Wert von lichtsteuerung über den 
Debugger aus. Bin gespannt auf das Ergebnis.

von Mathie (Gast)


Lesenswert?

Max G. schrieb:
> Mathie schrieb:
>> Worin könnte der Fehler sein ?
>> I habs nochmal probiert aber funktioniert einfach nicht. Mir kommt es so
>> vor dass der Interrrupthandler nie aufgerufen wird ?
>
> Da Du P5.7 ohnehin auf Ausgang setzt, lasse doch den Ausgang mal
> toggeln, wenn die ISR aufgerufen wird. Aus Deiner Beschreibung schließe
> ich, dass P1.3 schon toggelt, aber sich das PWM-Verhältnis nicht ändert.
>
> Außerdem fällt mir auf:
> - Ich sehe keine Initialisierung der Clocks
> - CCR2 hast Du anfangs nicht gesetzt - woher kommt dann das initiale
> PWM-Tastverhältnis?
> - Bist Du sicher, dass die 16000-1 ein sinnvoller Wert sind? Wenn die
> Clock von Timer B mit 16 MHz läuft, wird die ISR alle Millisekunde
> aufgerufen, und Du bist in kürzester Zeit am Anschlag.
>
> Lies doch mal nach einer Sekunde den Wert von lichtsteuerung über den
> Debugger aus. Bin gespannt auf das Ergebnis.

Heute komme ich nicht mehr zum testen , werde es morgen machen.
Der ACLK wird mit 32 kHz betrieben

besten Dank

von Max G. (l0wside) Benutzerseite


Lesenswert?

Mathie schrieb:

> Heute komme ich nicht mehr zum testen , werde es morgen machen.
> Der ACLK wird mit 32 kHz betrieben

Bist Du sicher, dass Time B auf ACLK läuft? In Deinem Code wird das 
nicht konfiguriert, aber Du hast ja auch nicht alles gepostet.

von Dennis (Gast)


Lesenswert?

Mathie schrieb:
> Mir kommt es so
> vor dass der Interrrupthandler nie aufgerufen wird ?

Hast du das GIE-Bit gesetzt?

von Mathie (Gast)


Lesenswert?

Mathie schrieb:
> TBCTL |= TBSSEL_1 + MC_1 + TAIE;           // ACLK, upmode



ja im Hauptcode ist er aktiv

TBCTL |= TBSSEL_1 + MC_1 + TAIE;           // ACLK, upmode


und den Quarz hab i extern angeschlossen

mfg Mathie

von Mathie (Gast)


Lesenswert?

TBCTL |= TBSSEL_1 + MC_1 + TAIE;           // ACLK, upmode


das ist doch di definition für den ACLK bzw extern muss noch ein Quarz 
hin.

mfg

von Max G. (l0wside) Benutzerseite


Lesenswert?

Mathie schrieb:
> TBCTL |= TBSSEL_1 + MC_1 + TAIE;           // ACLK, upmode
>
>
> das ist doch di definition für den ACLK bzw extern muss noch ein Quarz
> hin.

Ich hab´s nicht geprüft, ich glaube es Dir aber gerne. Woher kommt ACLK?

von Mathias K. (underworldgamer)


Lesenswert?

Habidere

i hons hüt nochmol usprobiert hier wäre mein ergebnis.
Hat jetzt prima funktioniert auf diese weise

Der msp430 wird mit einem uhrenquarz extern gespeist 32 kHz wäre dieser.
1
#include  "msp430x24x.h"
2
3
unsigned char lichtsteuerung = 84;
4
unsigned char lichtmax = 85;
5
unsigned char lichtmin = 10;
6
unsigned char volatile auswahl;
7
unsigned char volatile auswahlaktiv;
8
9
10
void setON()
11
{
12
  
13
  if(auswahl == 98){
14
    P1SEL &= ~BIT2;      // P5.0 is I/O
15
    P1DIR |= BIT2;      // P5.0 is Output
16
    P1DIR &= ~ BIT0;      // P5.0 is Output
17
    P1OUT |= BIT2;                //Output auf High
18
  }else{}
19
  
20
}
21
22
void setOFF(){
23
  
24
  if(auswahl == 99){
25
    P1SEL &= ~BIT2;      // P5.0 is I/O
26
    P1DIR |= BIT2;      // P5.0 is Output
27
    P1DIR &= ~ BIT0;      // P5.0 is Output
28
    P1OUT &= ~ BIT2;                //Output auf Low
29
}else{}
30
31
32
}
33
34
void initTimer(){
35
  
36
  //Timer B
37
  
38
  P5DIR |= BIT7;                            // Set P1.0 to output direction
39
  TBCCTL0 = CCIE;                           // TRCCR0 interrupt enabled
40
  TBCCR0 = 8000-1;
41
  TBCTL |= TBSSEL_1 + MC_1;                 // ACLK, upmode, clear TBR
42
  
43
44
  
45
}
46
47
void initPWM(){
48
  
49
  P1DIR |= BIT3;                            // P1.2 and P1.3 output
50
  P1SEL |= BIT3;                            // P1.2 and P1.3 TA1/2 otions
51
  CCR0 = 128;                               // PWM Period/2
52
  CCTL2 = OUTMOD_6;                         // CCR2 toggle/set
53
  CCR2 = 86;                                // CCR2 PWM duty cycle
54
  
55
//The value in CCR0, 128, defines the
56
//PWM period/2 and the values in CCR1 and CCR2 the PWM duty cycles
57
  TACTL = TASSEL_2 + MC_3;                  // SMCLK, up-down mode
58
  
59
  
60
}
61
62
63
void initRS232(){
64
  
65
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
66
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
67
  DCOCTL = CALDCO_1MHZ;
68
  
69
  
70
  P3SEL = 0xf0;                             // P3.4,5,6,7 = USCI_A0 A1 TXD/RXD
71
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
72
  UCA0BR0 = 6;                              // 1MHz 9600
73
  UCA0BR1 = 0;                              // 1MHz 9600
74
  UCA0MCTL = UCBRF3 + UCOS16;               // Modln UCBRSx=1, over sampling
75
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
76
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
77
  
78
  /////////////////////////////////////////////////////////////////////////////
79
  
80
  UCA1CTL1 |= UCSSEL_2;                     // SMCLK
81
  UCA1BR0 = 6;                              // 1MHz 9600
82
  UCA1BR1 = 0;                              // 1MHz 9600
83
  UCA1MCTL = UCBRF3 + UCOS16;               // Modln UCBRSx=1, over sampling
84
  UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
85
  UC1IE |= UCA1RXIE;                        // Enable USCI_A1 RX interrupt
86
  
87
  
88
  
89
}
90
91
92
93
void setPWM(char val){
94
  
95
  if(val >= lichtmax)
96
  { 
97
    val = 84;
98
    lichtsteuerung = val;
99
  }
100
  if(val <= lichtmin)
101
  { 
102
    val = 11;
103
    lichtsteuerung = val;
104
  }
105
  
106
  CCR2 = val;
107
              
108
}
109
110
111
112
void main(void)
113
{
114
  WDTCTL = WDTPW + WDTHOLD;            // Stop WDT
115
            
116
  initPWM();                           //Init PWM
117
  initTimer();                         //Init Timer B bei ca. 1 sec
118
  
119
  initRS232();                          //Init RS232 9600 Baud
120
  setON();                             //Beim Reset Lampe einschalten danach
121
  
122
  _BIS_SR(GIE);                        // Enter LPM3 w/ interrupt
123
 
124
 
125
while(1){
126
      
127
          
128
      switch(auswahl) {
129
      case 10:   //Licht Heller
130
            auswahlaktiv = 0;
131
            lichtsteuerung -= 8;
132
            setPWM(lichtsteuerung);
133
            auswahl = 100;
134
            break;
135
            
136
      case 20:  //Licht Dunkler
137
            auswahlaktiv = 0;
138
            lichtsteuerung += 8;
139
            setPWM(lichtsteuerung);
140
            auswahl = 100;
141
            break;
142
            
143
      case 40:  //Dunkel
144
            auswahlaktiv = 0;
145
            lichtsteuerung = 8;
146
            setPWM(lichtsteuerung);
147
            auswahl = 100;
148
            break;
149
            
150
      case 50:  //Licht Dunkler
151
            auswahlaktiv = 0;
152
            lichtsteuerung = 83;
153
            setPWM(lichtsteuerung);
154
            auswahl = 100;
155
            break;      
156
           
157
      case 30:  //lichtmodus Dimmung
158
            setPWM(lichtsteuerung);    //machts solange bis case nicht mehr 30 ist!!
159
            auswahlaktiv = 30;
160
            auswahl = 100;
161
            break;
162
            
163
     case 99: //Licht Aus
164
            setOFF();             //EVG OFF
165
            auswahl = 100;
166
            break;  
167
            
168
     case 98: //Licht ein
169
            setON();              //EVG ON
170
            auswahl = 100;
171
            break;         
172
      
173
      }          
174
  }          
175
 
176
  
177
}
178
179
//Für TX Interrupt RS232
180
 
181
#pragma vector=USCIAB0RX_VECTOR
182
__interrupt void USCI0RX_ISR(void)
183
{
184
  UCA0TXBUF = UCA0RXBUF;
185
}
186
187
//Für RX Interrupt RS232
188
189
#pragma vector=USCIAB1RX_VECTOR
190
__interrupt void USCI1RX_ISR(void)
191
{
192
  //UCA1TXBUF = UCA1RXBUF;                     // TX -> RXed character
193
  auswahl = UCA1RXBUF;
194
}
195
196
//Für Timer Dimmingmodus
197
198
199
// Timer B0 interrupt service routine
200
#pragma vector=TIMERB0_VECTOR
201
__interrupt void Timer_B (void)
202
{
203
  if(auswahlaktiv == 30){
204
      lichtsteuerung = lichtsteuerung - 5;
205
      setPWM(lichtsteuerung);
206
    if(lichtsteuerung <= 4){
207
       lichtsteuerung = 84;
208
       CCR2 = lichtsteuerung;
209
       auswahlaktiv = 100;
210
      
211
    }
212
  }
213
  
214
    P5OUT ^= BIT7;                        // Toggle P5.7
215
  
216
}

von Mathias K. (underworldgamer)


Lesenswert?

Max G. schrieb:
> Mathie schrieb:
>
>> Heute komme ich nicht mehr zum testen , werde es morgen machen.
>> Der ACLK wird mit 32 kHz betrieben
>
> Bist Du sicher, dass Time B auf ACLK läuft? In Deinem Code wird das
> nicht konfiguriert, aber Du hast ja auch nicht alles gepostet.

Hallo

siehe unten habs so geändert und jetzt funktionierts.

lg Mathias

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.