Forum: Mikrocontroller und Digitale Elektronik ATmega48 Initialisierung der timer1 + timer2 stören sich


von Squat *. (squat)


Lesenswert?

Hallo,

ich habe folgendes Problem. Ich stelle bei ATmega48 den Timer1 und 
Timer2 ein und lasse diese dann durchlaufen, jeodch funktioniert nur der 
Programmteil vom Timer2. Wenn ich diesen jedoch nicht einstelle, läuft 
der zuvor eingestellte Timer1.
1
//TIMER1 initialize - prescale:64
2
// WGM: 0) Normal, TOP=0xFFFF
3
// desired value: 100mSec
4
// actual value: 100,000mSec (0,0%)
5
void timer1_init(void)
6
{
7
 TCCR1B = 0x00; //stop
8
 TCNT1H = 0xCF; //setup
9
 TCNT1L = 0x2C;
10
 OCR1AH = 0x30;
11
 OCR1AL = 0xD4;
12
 OCR1BH = 0x30;
13
 OCR1BL = 0xD4;
14
 ICR1H  = 0x30;
15
 ICR1L  = 0xD4;
16
 TCCR1A = 0x00;
17
 TCCR1B = 0x03; //start Timer
18
}
19
20
21
//TIMER2 initialize - prescale:1
22
// WGM: CTC
23
// desired value: 10uSec
24
// actual value: 10,125uSec (1,2%)
25
void timer2_init(void)
26
{
27
 TCCR2B = 0x00; //stop
28
 ASSR  = 0x00; //set async mode
29
 TCNT2 = 0xB0; //setup
30
 OCR2A = 0x50;
31
 OCR2B = 0x00;
32
 TCCR2A = 0x02; 
33
 TCCR2B = 0x01; //start
34
}

Irgendwie verstelle ich wohl beim Timer2 die Einstellung vom Timer1. 
Zumindest scheint es mir so, da beide unabhängig von einander laufen.

Vielleicht fällt jemandem was auf und kann mir somit weiter helfen.

von Squat *. (squat)


Lesenswert?

Gerade habe ich nochmal was ausprobiert und festgestellt, dass wohl doch 
nichts verstellt ist, jedoch die Timer sich trotzdem irgendwie stören.

Ich habe den Interrupt vom Timer2 mal entfernt.
1
TIMSK1 = 0x01; //timer 1 interrupt sources
2
TIMSK2 = 0x00; //timer 2 interrupt sources
Dann lief wieder der Programmteil vom Timer1.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Squat *** schrieb:
> jeodch funktioniert nur der Programmteil vom Timer2. Wenn ich diesen
> jedoch nicht einstelle, läuft der zuvor eingestellte Timer1.

Wie hast du das festgestellt?

Gruß,
Magnetus

von Squat *. (squat)


Lesenswert?

Ich habe unterschiedliche Funktione ausgeführt, diese laufen über jeden 
der Timer (Lauflicht, Analog-Digital-Wandlung, Blicklicht etc.) Jedoch 
immer nur über den einen oder den anderen Timer.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Zeig mal dein Programm.

von Squat *. (squat)


Lesenswert?

Jetzt wolte ich Dir gerade das Programm verkürzt zusammenpacken (in eine 
Datei). Leider funktionieren jetzt beide Timer.

Jetzt habe ich die Schritte nachvollzogen und bin auf das Problem 
gestoßen.

Ich habe in dem 10usec (Timer2) eine Funktion ausgeführt, die drei 
Servos auf Softwarebasis ansteuert. Dies hat auch wunderbar 
funkerioniert, jedoch wollten aus diesem Grund die anderen Funktionen 
des Timer1 irgendwie nicht ausgeführt werden.

Ich werde mal versuchen, das Programm so hier darzustellen und hoffe, 
dass mir jemand eine andere Lösung für die Servoansteuerung bzw. das 
ausführen der Funktion mitteilen kann.

Bitte entschuldigt, wenn es etwas unübersichtlich ist. Ich lerne immer 
noch dazu.
1
//ICC-AVR application builder : 13.04.2010 16:15:44
2
// Target : m48
3
// Crystal: 8.0000Mhz
4
5
#include <iom48v.h>
6
#include <macros.h>
7
8
9
unsigned int RulInt = 9;
10
unsigned int WarnInt = 49;
11
12
unsigned int f_1sec;
13
unsigned char f_100ms;
14
15
16
//------------------------------------------------------------------------------
17
             // Port-Zuweisung
18
//------------------------------------------------------------------------------
19
20
/* PORT B */
21
//#define  PB7
22
//#define  PB6
23
#define jump2 PB5
24
#define jump1 PB4
25
#define servo3 PB3
26
#define servo2 PB2
27
#define servo1 PB1
28
#define pin_taster PB0
29
30
/* PORT C */
31
#define poti1 PC7
32
#define reset PC6
33
#define pinnchen PC5
34
//#define  PC4
35
//#define  PC3
36
#define sound1 PC2
37
#define poti3 PC1
38
#define poti2 PC0
39
40
/* PORT D */
41
#define ziel_led PD7
42
#define pump1 PD6
43
#define pump2 PD5
44
#define R_LED4 PD4
45
#define R_LED3 PD3
46
#define R_LED2 PD2
47
#define sound2 PD1
48
#define R_LED1 PD0
49
50
51
52
void port_init(void)
53
{
54
 PORTB = 0xF1;
55
 DDRB  = 0x0E;
56
 PORTC = 0x43; 
57
 DDRC  = 0xBC;
58
 PORTD = 0x00;
59
 DDRD  = 0xFF;
60
}
61
//TIMER1 initialize - prescale:64
62
// WGM: 0) Normal, TOP=0xFFFF
63
// desired value: 100mSec
64
// actual value: 100,000mSec (0,0%)
65
void timer1_init(void)
66
{
67
 TCCR1B = 0x00; //stop
68
 TCNT1H = 0xCF; //setup
69
 TCNT1L = 0x2C;
70
 OCR1AH = 0x30;
71
 OCR1AL = 0xD4;
72
 OCR1BH = 0x30;
73
 OCR1BL = 0xD4;
74
 ICR1H  = 0x30;
75
 ICR1L  = 0xD4;
76
 TCCR1A = 0x00;
77
 TCCR1B = 0x03; //start Timer
78
}
79
#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
80
void timer1_ovf_isr(void)
81
{
82
 static unsigned int t1;
83
 //TIMER1 has overflowed
84
 TCNT1H = 0xCF; //reload counter high value
85
 TCNT1L = 0x2C; //reload counter low value
86
  if(t1) {t1=9; f_1sec=1;}
87
    else   --t1;
88
89
}
90
91
92
//----------------------------------------------------------------------------//
93
         // Servo
94
//----------------------------------------------------------------------------//
95
96
// Bei dieser Funktion werden jeweils 2000x 10usec gezählt um 20milisec für das PPM-Signal zu erzeugen.
97
98
volatile unsigned char servo1pos; //(98,7 =1msec bis 197,5 = 2msec)
99
volatile unsigned char servo2pos; //(98,7 =1msec bis 197,5 = 2msec)
100
volatile unsigned char servo3pos; //(98,7 =1msec bis 197,5 = 2msec)
101
102
void servoweg(void)
103
 {
104
static int count1;
105
static int count2;
106
static int count3;
107
//----Servo 1-----------------------------------------------------------------//
108
109
  if(count1>servo1pos) {PORTB &= ~(1<<servo1);}
110
  else PORTB|=(1<<servo1);
111
  
112
  if(count1<2000+servo1pos)count1++;
113
  else count1=0;
114
//----Servo 2-----------------------------------------------------------------//
115
  
116
  servo2pos = 20;
117
  if(count2>servo2pos) {PORTB&=~(1<<servo2);}
118
  else PORTB|=(1<<servo2);
119
120
  if(count2<2000+servo2pos)count2++;
121
  else count2=0;
122
//----Servo 3-----------------------------------------------------------------//
123
                
124
  if(count3>servo3pos)PORTB&=~(1<<servo3);
125
  else PORTB|=(1<<servo3);
126
  
127
  if(count3<2000+servo3pos)count3++;
128
  else count3=0;
129
  
130
131
}
132
133
//TIMER2 initialize - prescale:1
134
// WGM: Normal
135
// desired value: 10uSec
136
// actual value: 10,000uSec (0,0%)
137
void timer2_init(void)
138
{
139
 TCCR2B = 0x00; //stop
140
 ASSR  = 0x00; //set async mode
141
 TCNT2 = 0xB0; //setup
142
 OCR2A = 0x50;
143
 OCR2B = 0x00;
144
 TCCR2A = 0x00; 
145
 TCCR2B = 0x01; //start
146
}
147
#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
148
void timer2_ovf_isr(void)
149
{
150
 static unsigned int t2;
151
 TCNT2 = 0xB0; //reload counter value
152
153
 //servoweg();                                          //HIER IST DER ÜBELTÄTER
154
 
155
 if(t2) {t2=9; f_100ms=1;}
156
    else   --t2;
157
}
158
//ADC initialize
159
// Conversion time: 6uS
160
void adc_init(void)
161
{
162
 ADCSRA = 0x00; //disable adc
163
 ADMUX = 0x00;  //select adc input 0
164
 ACSR  = 0x80;
165
 ADCSRB = 0x00;
166
 ADCSRA = 0x01;
167
}
168
169
unsigned char taster = 0;
170
//----------------------------------------------------------------------------//
171
         // Tasterabfrage
172
//----------------------------------------------------------------------------//
173
void funkt_tast(void)
174
{
175
 static char rw = 0;
176
    if(taster == 0 && !(PINB & (1<<pin_taster)))   //Taster wird gedrueckt (steigende Flanke)
177
    {
178
        taster = 1;
179
        rw = 1;
180
    }
181
    else if (taster == 1 && !(PINB & (1<<pin_taster)))   //Taster wird gehalten
182
    {
183
         taster = 2;
184
         rw = 0;
185
    }
186
    else if (taster == 2 && (PINB & (1<<pin_taster)))   //Taster wird losgelassen (fallende Flanke)
187
    {
188
        taster = 3;
189
        rw = 0;
190
    }
191
    else if (taster == 3 && (PINB & (1<<pin_taster)))   //Taster losgelassen
192
    {
193
        taster = 0;
194
        rw = 0;
195
    }
196
197
   
198
   
199
}
200
unsigned char i = 0;
201
202
unsigned int result;
203
unsigned int poti_1;
204
unsigned int poti_2;
205
unsigned int poti_3;
206
unsigned int batt;
207
208
209
//----------------------------------------------------------------------------//
210
       //         AD-Wandlung
211
//----------------------------------------------------------------------------//
212
 void ad(void)
213
 {
214
       // Dummy-Readout
215
       ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);  // ADC aktivieren, Frequenzvorteiler: setzen auf 64 (8 MHz / 64 = 125 kHz) und ADC aktivieren            
216
       ADMUX |= (1<<REFS0) | (1<<REFS1);        // interne Referenzspannung nutzen 
217
       ADCSRA |= (1<<ADSC);               // eine ADC-Wandlung
218
       while(!(ADCSRA & (1<<ADIF)));          // auf Abschluss der Konvertierung warten (ADIF-bit)
219
       result = ADC;                    // ADC muss einmal gelesen werden,
220
                                        // sonst wird Ergebnis der nächsten Wandlung
221
                                        // nicht übernommen.
222
       
223
       //ADC-Messung mit arithmetischen Mittel aus 4 Messungen
224
       result = 0;
225
       for (i=0;i<4;i++)
226
            {
227
          ADCSRA |= (1<<ADSC);             // Messung ausfuehren
228
        while ( ADCSRA & (1<<ADSC) );        // Konvertierung abwarten
229
        result += ADC;                     // aufaddieren zur Mittelwertbildung (ADC auslesen der zwei Bits
230
        }
231
        ADCSRA &= ~(1<<ADEN);               // ADC ausschalten
232
        
233
        result /= 4;                 // 
234
        
235
236
}
237
238
//----------------------------------------------------------------------------//
239
       //         AD-Wandlung für Poti 1-3 und Batterie
240
//----------------------------------------------------------------------------//
241
 void adc(void)
242
 {
243
 //Poti 1
244
 ADMUX = 0x00;// Kanal waehlen (ADC0)
245
 ad();
246
 result /= 4;//auf 8 Bit reduzieren
247
 poti_1 = result;
248
 OCR0A = poti_1;
249
 // Poti 2
250
 ADMUX = 0x01;// Kanal waehlen (ADC1)
251
 ad();
252
 result /= 4;//auf 8 Bit reduzieren
253
 poti_2 = result;
254
 OCR0B = poti_2;
255
  //Poti 3
256
 ADMUX = 0x07;// Kanal waehlen (ADC7)
257
 ad();
258
 result /= 4;//auf 8 Bit reduzieren
259
 poti_3 = result;
260
 OCR0A = poti_3;
261
 
262
  //Batteriespannung
263
 ADMUX = 0x02;// Kanal waehlen (ADC2) 
264
 ad();
265
 batt = result;
266
 
267
268
 
269
}
270
 
271
272
 //----------------------------------------------------------------------------//
273
       //         Akkuwarnung
274
//----------------------------------------------------------------------------//
275
 
276
void warn(void)
277
{
278
static unsigned int delay;
279
        if (delay>WarnInt)
280
      {
281
      delay=0;
282
      adc();
283
      if (poti_3>40)//if (batt < 500) Momentan noch auf einem Poti gelegt
284
      {PORTC ^= (1<<pinnchen);}
285
      else {PORTC |= (1<<pinnchen);}
286
      }
287
      else delay++;
288
}
289
290
//----------------------------------------------------------------------------//
291
       //         RundUmLicht
292
//----------------------------------------------------------------------------//
293
unsigned char blink_state = 0;
294
unsigned char countLED = 0;
295
void rul(void)
296
{
297
  switch (blink_state)
298
 {
299
300
  case 0: // R_LED1 ein
301
  {
302
   PORTD &= ~((1<<R_LED2) | (1<<R_LED3) | (1<<R_LED4));
303
   PORTD |= (1<<R_LED1);
304
   break;  
305
  }
306
  case 1: // R_LED2 ein
307
  {
308
   PORTD &= ~((1<<R_LED1) | (1<<R_LED3) | (1<<R_LED4));
309
   PORTD |= (1<<R_LED2);
310
   break;  
311
  }  
312
  case 2: // R_LED3 ein
313
  {
314
   PORTD &= ~((1<<R_LED1) | (1<<R_LED2) | (1<<R_LED4));
315
   PORTD |= (1<<R_LED3);
316
   break;  
317
  }  
318
  case 3: // R_LED4 ein
319
  {
320
   PORTD &= ~((1<<R_LED1) | (1<<R_LED2) | (1<<R_LED3));
321
   PORTD |= (1<<R_LED4);
322
   break; 
323
  } 
324
 }
325
countLED++;
326
if (countLED>RulInt) //Hier stellt man die Drehzahl der Rundumleuchte ein
327
{
328
countLED=0;
329
blink_state++;
330
}
331
if (blink_state>3) {blink_state=0;     // Lauflicht neustarten
332
   }
333
}
334
335
336
////////////////////////////////////////////////////////////////////////////////
337
// Hauptprogramm
338
////////////////////////////////////////////////////////////////////////////////
339
void main(void)
340
{
341
 //stop errant interrupts until set up
342
 CLI(); //disable all interrupts
343
 port_init();
344
 timer1_init();
345
 timer2_init();
346
 adc_init();
347
348
 MCUCR = 0x00;
349
 EICRA = 0x00; //extended ext ints
350
 EIMSK = 0x00;
351
 
352
 TIMSK0 = 0x00; //timer 0 interrupt sources
353
 TIMSK1 = 0x01; //timer 1 interrupt sources
354
 TIMSK2 = 0x01; //timer 2 interrupt sources
355
 
356
 PCMSK0 = 0x00; //pin change mask 0 
357
 PCMSK1 = 0x00; //pin change mask 1 
358
 PCMSK2 = 0x00; //pin change mask 2
359
 PCICR = 0x00; //pin change enable 
360
 PRR = 0x00; //power controller
361
 SEI(); //re-enable interrupts
362
 //all peripherals are now initialized
363
   
364
 while(1)
365
  {
366
    if(f_1sec)
367
    {
368
  f_1sec=0;
369
  rul();              // RundUmLicht
370
  }
371
    if(f_100ms)
372
    {
373
  f_100ms=0;
374
  adc();           // AD-Wandlung aller 4 Kanäle (3x Poti, 1x Batteriespannung)
375
  warn();         // Unterspannungswarnung
376
    funkt_tast();     // Taster
377
   if (taster == 1)  PORTD |= (1<<ziel_led); // LED an
378
  if (taster == 0)  PORTD &= ~(1<<ziel_led);// LED aus
379
  }
380
  }return;
381
}

von Ich (Gast)


Lesenswert?

Poste doch sowas bitte als Anhang!

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.