mikrocontroller.net

Forum: Compiler & IDEs ISRs stören sich gegenseitig


Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo :)

Ich versuche derzeit eine SW PWM zu realisieren. Dabei stoße ich jedoch
auf folgendes Problem.

Ein Timer arbeitet die PWM ab, der andere verändert die gewünschten
Helligkeitswerte. Das Ganze soll später noch erweitert werden, daher
habe ich das so gelöst. Hier mal der Code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>

#define CPU_SPEED 1000000

#define PWM_CH0 0
#define PWM_CH1 1
#define PWM_CH2 2

#define PWM_PORT PORTB
#define PWM_PORT_DIRECTION DDRB

volatile uint8_t currentValueInRun = 0; // This is the number of the
cycle inside one frame
volatile uint8_t currentBrightness[3]; // This is the brightness of the
channels
volatile uint8_t currentColourRun = 0;
volatile uint8_t colourChangeTime = 1;

struct {
   unsigned char stateTimerEnabled:1; // 1 Bit für bStatus_1
   unsigned char stateSwitchEnabled:1; // 1 Bit für bStatus_2
} status;


void enablePWM(void)
{
  // Set PWM_PORT AS OUTPUT (0 is Output, 1 is input)
  PWM_PORT_DIRECTION &= ~ ((1 << PWM_CH0) | (1 << PWM_CH1) | (1 <<
PWM_CH2));
  PWM_PORT = 0x00; // Set to Low

  // Use Timer 2 (8bit timer) for actual PWM
  TCCR2 |= (1 << WGM21);    // CTC Mode (WGM21 -> 1, others 0)
  TCCR2 |= (1 << CS20);    // No pre-scaler (running at CPU speed) (CS20
-> 1)
  //Calculate Preload value
  OCR2 = CPU_SPEED / 25600;  // will cause an overflow (TIMER2_COMP) if
TCNT reaches OCR2
  TIMSK |= (1 << OCIE2);    // Enable the overflow interrupt
}


ISR(TIMER2_COMP_vect)
{
  // ISR for PWM

  // This happens every 100 Cycles (25 600 Times each second)
  // Every cycle has 256 steps (resolution of brightness, 256 different
levels of brightness are possible) - from 0 .. 255 is one frame
  // We run at 100fps

  currentValueInRun++;  // will overflow automatically at 255 to 0

  if (currentValueInRun >= currentBrightness[0])   // check if we are in
the range of switching on / off
  {
    // Off State
    PWM_PORT &= ~(1 << PWM_CH0);
  }
  else
  {
    // On State
    PWM_PORT |= (1 << PWM_CH0);
  }
}

ISR(TIMER0_OVF_vect)
{
  // ISR for Automatic changer

  currentBrightness[0] = 255;
  PORTD=0xff;


  /*currentColourRun++;
  if (currentColourRun >= colourChangeTime)
  {
    currentColourRun = 0;
    // change color either completely or some step
    currentBrightness[0]++;
  }
  else
  {
    currentColourRun++;
  }*/
}


void enableAutomaticChanger(void)
{
  // Use Timer 0 - timing is not important
  TCCR0 |= (1 << CS00) | (1 << CS02);   // Prescaler: 1024, no reload
value (will count from 0 ... 255)
  TIMSK |= (1 << TOIE0);          // Enable interrupt
}

int main(void)
{
  // Init the brightness settings:
  for (int i = 0; i < 3; i++) {
    currentBrightness[i] = 0x00;
  }

  enablePWM();

  enableAutomaticChanger();

  PORTD = 0x00;

  sei();            // Enable global interrupts and wait
  while(1);          // now wait for interrupts
}


PortD nutze ich zum Überprüfen ob der Atmega8 in die entsprechenden
Routinen springt. Nun wirds aber interessant.
Aktiviere ich die PWM NICHT, so springt er - wie er soll in die
TIMER0_OVERFLOW ISR (PORTD = 0xff).
Wenn nun aber parallel dazu die PWM aktiviert wird, so springt er
einfach nicht mehr in die TIMER0_OVERFLOW ISR (PORTD bleibt auf 0x00).

Was mache ich denn falsch?

Um den Effekt herbeizuführen, reicht es aus, die Zeile enablePWM();
einfach mal auszukommentieren.

Danke für jegliche Hilfe :)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du setzt OCR2 auf 39 Zyklen, das ist fast nichts.

Warscheinlich kommst Du garnicht aus dem TIMER2_COMP raus.



Peter

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uff, tatsächlich. Selten so einen dummen Fehler gehabt.

Dank dir vielmals :)

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.