www.mikrocontroller.net

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


Autor: Uwe S. (de0508)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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
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
ADC_CHANNEL_AD8362  0
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.
static volatile uint8_t timer1_compa_cntL;
static volatile uint8_t timer1_compa_cntH;

ISR(TIMER1_COMPA_vect)
{
  if (++ timer1_compa_cntL >= 100) {
    timer1_compa_cntL = 0;

    if (++ timer1_compa_cntH >= 20) {
      timer1_compa_cntH = 0;
      PORTB ^= _BV(PB1);      // Toggle PB1
    }

  } // -- if - then --
}

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 ?

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> void Setup_Timer1(void)
> {
>  ...
>  TIMSK1 |=  _BV(OCIE2A);
> }


Timer1 und OCIE2A ???

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

Autor: Uwe S. (de0508)
Datum:

Bewertung
0 lesenswert
nicht 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.

.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.