Forum: Projekte & Code Problem: ADC-Wandlung legt Timer ISR Routine lahm


von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein Problem das ich durch einkreisen und viele Test auf die ISR 
Timer1 gekommen. Vorher lieferte ein Test mit Timer2 auch dieses 
Problem.

Problem
Die ISR Läuft nur bis zum erstmaligen Aufruf von
1
adc_readchannel(ADC_CHANNEL_AD8362);
Korrekt und der Pin PB1 'wackelt' alle 1 Sekunde.

Verwendet wird ein atMega88 mit 8MHz R/C Oszillator, gcc-Version 4.3.4 
(GCC) unter Linux auf einem fertigem System/ Platine mit LCD Display.
An zwei den beiden ADC Eingängen
1
ADC_CHANNEL_AD8362  0
2
ADC_CHANNEL_VIN    1

werden nur die Betriebsspannung mit einem 1/11 Spannungsteiler gemessen 
und der AD8362 abgefragt.
Das läuft auch wunderbar.

Die "Timer"

Timer0 läuft im CTC Modus mit 125kHz
und erzeugt - abhängig von OCR0A - über TIMER0_COMPA einen Ton an PB0.

Timer 1 läuft in Fast PWM 8-Bit Modus mit 1MHz und
erzeugt eine Frequenz an PB2 über COM1B1=1 und COM1B0=0.
Die Frequenz ist eigentlich egal, sie wird nur für einen -5V 
Spannungswandler benötigt. Er liefert im Leerlauf -4,8V.

Über den TIMER1_COMPA Interrrupt wird testweise eine LED an PB1 alle 
0,5sek an und aus geschaltet und darüber wird das Problem analysiert.

Die ISR für TIMER1_COMPA zählt über zwei Schleifen bis 2000 = 100 * 20.

Hier das Codesegment, alle Programmteile sind auch im Anhang zu finden.
1
static volatile uint8_t timer1_compa_cntL;
2
static volatile uint8_t timer1_compa_cntH;
3
4
ISR(TIMER1_COMPA_vect)
5
{
6
  if (++ timer1_compa_cntL >= 100) {
7
    timer1_compa_cntL = 0;
8
9
    if (++ timer1_compa_cntH >= 20) {
10
      timer1_compa_cntH = 0;
11
      PORTB ^= _BV(PB1);      // Toggle PB1
12
    }
13
14
  } // -- if - then --
15
}

In der "main()" wird die ADC-Lesefunktion aufgerufen und sie liest 3x 
10Bit Werte und bildet einen Mittelwert daraus.

Nach dem ersten Aufruf läuft die obige ISR nicht mehr und es gibt sogar 
bei 16 Bit Vars auch Überläufe !
Deshalb hier auch eine 8-Bit Darstellung des 2000er Zählers.

Sehr eigenartig !

Wer hat eine Idee ?

von Werner B. (werner-b)


Lesenswert?

> void Setup_Timer1(void)
> {
>  ...
>  TIMSK1 |=  _BV(OCIE2A);
> }


Timer1 und OCIE2A ???

P.S. Was hat die Frage in der Codesammlung zu suchen?

von Uwe S. (de0508)


Lesenswert?

Guten Morgen Werner,

sorry wenn das der falsche Bereich ist, wo sollte man sonst Fragen 
dürfen?.

Ja richtig gesehen, das

(c)TIMSK1 |=  _BV(OCIE2A);(/c)

ist ein Kopierfehler, liefert aber den richtigen Code, da OCIE2A = 
OCIE1A ist und als Define in C die selben Zahlen sind.

.

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.