ISRs stören sich gegenseitig

OP #363882
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 :)

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.