Hi,
I spent all day long trying to fix my problem, that the ISRs seem not to be called.
I figured out, that the counter runs (print() in the mainloop), and the Interrupt flags are set at the "right" compare / overflow point. But It doesn't go into my ISRs. Does anyone has an idea what I do wrong?
The basic thing I want to do is to some kind of software pwm. One requirement is that both pins are never high at the same time. So my Idea was to set 0<CMP0 < CMP1 < CMP2 < OVF interrupt and switch my first pin on at CMP0 Interrupt and switch it out at CMP1 Interrupt. For my second pin I want to do the same with CMP2 and OVF interrupt.
If so. has a much better Idea, you're welcome
the main loop is actually not so meaningful, as it stands here. Since "clean up" for posting and change something still got mixed up.
But it doesn't change my actual problem. The main loop is actually completely without function here. It should run only with the ISR and it doesn't jump into it.
I just changed it a little according to your post. the volatile makes the compiler not to optimize it away and I don't wanted to have a delay() function in the main. So it's just a little bit like doing nothing.
What happens if you remove the Serial prints from the ISR's?
nothing
I changed the sketch a little, so I only wanted to have the OVF interrupt. I put the Trace in the mainloop and that is what comes on the serial monitor:
#define PIN1 12 //definiert den PIN1 für die Anwendung
#define PIN2 11 //definiert den PIN2 für die Anwendung
#include <ArduinoTrace.h>
volatile uint8_t debug;
void setup() {
// Init Pins
pinMode(PIN1, OUTPUT);
digitalWrite(PIN1, LOW);
pinMode(PIN2, OUTPUT);
digitalWrite(PIN2, LOW);
cli(); //disable global interrupts
TCA0.SINGLE.CTRLA = 0; // stop/reset Timer
TCA0.SINGLE.CTRLB = 0;
TCA0.SINGLE.CTRLC = 0;
TCA0.SINGLE.CTRLD = 0;
TCA0.SINGLE.EVCTRL = 0;
TCA0.SINGLE.CNT = 0;
TCA0.SINGLE.INTCTRL = 0;
//TCA0.SINGLE.CMP0 = 1000; //10% von 640 -1
//TCA0.SINGLE.CMP1 = 30000; // 50% von 640 -1
//TCA0.SINGLE.CMP2 = 40000; // 60 % von 640-1
TCA0.SINGLE.PERBUF= 60000; // Value Overflow TCA (640-1 @ 16 MHz --> 25 kHz) // overflow bei 639 bzw 0
/*
TCA0.SINGLE.CMP0 = (64-1); //10% von 640 -1
TCA0.SINGLE.CMP1 = (320-1); // 50% von 640 -1
TCA0.SINGLE.CMP2 = (384-1); // 60 % von 640-1
TCA0.SINGLE.PER= (640-1); // Value Overflow TCA (640-1 @ 16 MHz --> 25 kHz) // overflow bei 639 bzw 0
*/
TCA0.SINGLE.CTRLA |= (0x07<<1); // Clk Prescaler =1
TCA0.SINGLE.CTRLB &= ~((uint8_t)(0x7F)); //normal mode, Waveformoutputs und LUTs disabled
TCA0.SINGLE.CTRLD = 0; //not split mode;
// enable Interrupts for CMP0..2 and OVF
TCA0.SINGLE.INTCTRL = (1<<TCA_SINGLE_OVF_bm);//|(1<<TCA_SINGLE_CMP2EN_bm)|(1<<TCA_SINGLE_CMP1EN_bm)|(1<<TCA_SINGLE_CMP0EN_bm);
TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm; //enable Timer TCA in single mode
sei(); //enable global interrupts
Serial.begin(9600);
Serial.print("Config done");
TCA0.SINGLE.INTFLAGS = 113; //clear flags once (doesn't help)
}
ISR(TCA0_OVF_vect)
{
digitalWrite(PIN2, LOW);
debug++;
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
}
void loop()
{
volatile static uint16_t i=0;
i++;
DUMP(TCA0.SINGLE.CNT);
DUMP(TCA0.SINGLE.INTFLAGS);
DUMP(debug);
TRACE();
}
I don't understand, why the flags of all interrupts are set (maybe this trace libary does not look it up correctly) and the debug var shows, that the ISR is never entered.
If this is one of the cases where you clear flags but writing a 1, you probably dont want to use the |= form since it may clear other interrupts as well. Just use =.