Hello,
Please find an extract from a global sketch aiming at full control of multiple timers. The structure CFG contains all the parameters used to configure each timer, after initialization the subroutine FrameFast is called to update each change of CFG.
I've connected my oscilloscope Tek2445 to the PWM outputs but discovered that the ouptuts are not TCNT's delayed correctly for some reason but all OCR's are correct. In other words, the internal registers OCR's once uploaded with CFG's update produce correct signals (frequency and duty cycle) but for some reason, the TCNT's register do not time delay correctly. I do get a time delay of occurence between timer4 and timer3 but this delay is always incorrect.
There must be either a bug in my code or TCNT register timer special procedure I'm missing !
Thank you in advance for any help, Albert
#define CPU_CLOCK 16000000.0
typedef unsigned char percentage_t;
// current frequency of timer1, timer 3, timer4 and timer5
static unsigned int freqPWM=800; // multiply by 10 to obtain value in Hz
static unsigned int localfreqPWM;
struct timerConfig {
percentage_t pulse;
percentage_t extract;
percentage_t delay;
} __attribute__((__packed__));
struct allConfig {
timerConfig timer1;
timerConfig timer3;
timerConfig timer4;
timerConfig timer5;
} __attribute__((__packed__));
static struct allConfig cfg = {
{1, 1, 0}, // Timer 1,
{20, 20, 80}, // Timer 3,
{100, 100, 0}, // Timer 4,
{1, 1, 0}, // Timer 5,
};
// current frequency pulse extract delay of timer1
static unsigned int localpulsePWM1;
static unsigned int localextractPWM1;
static unsigned int localdelayPWM1;
// current frequency pulse extract delay of timer3
static unsigned int localpulsePWM3;
static unsigned int localextractPWM3;
static unsigned int localdelayPWM3;
// current frequency pulse extract delay of timer4
static unsigned int localpulsePWM4;
static unsigned int localextractPWM4;
static unsigned int localdelayPWM4;
// current frequency pulse extract delay of timer5
static unsigned int localpulsePWM5;
static unsigned int localextractPWM5;
static unsigned int localdelayPWM5;
// timer1 used for ZPE pump
int outputPin1B = 12;
int outputPin1C = 13;
// timer3 used for ZPE pump
int outputPin3B = 2;
int outputPin3C = 3;
// timer4 used for ZPE pump
int outputPin4B = 7;
int outputPin4C = 8;
// timer5 used for ZPE pump
int outputPin5B = 45;
int outputPin5C = 44;
void setup()
{
// select output pins & initialize timer1
// pinMode(outputPin1B, OUTPUT);
// pinMode(outputPin1C, OUTPUT);
// TCCR1A = B00101011; // Fast PWM change at OCR1A
// TCCR1B = B11001; // prescaling by 1 the system clock
// select output pins & initialize timer3
pinMode(outputPin3B, OUTPUT); // Fast PWM change at OCR3A
pinMode(outputPin3C, OUTPUT); // prescaling by 1 the system clock
TCCR3A = B00101011;
TCCR3B = B11001;
// select output pins & initialize timer4
pinMode(outputPin4B, OUTPUT); // Fast PWM change at OCR4A
pinMode(outputPin4C, OUTPUT); // prescaling by 1 the system clock
TCCR4A = B00101011;
TCCR4B = B11001;
// select output pins & initialize timer5
// pinMode(outputPin5B, OUTPUT);
// pinMode(outputPin5C, OUTPUT);
// TCCR5A = B00101011; // Fast PWM change at OCR5A
// TCCR5B = B11001; // prescaling by 1 the system clock
FrameFast();
}
void loop()
{
}
void FrameFast()
{
float fperiod;
fperiod=CPU_CLOCK/10.0/float(freqPWM);
localfreqPWM=(unsigned int) (fperiod-0.5);
fperiod=fperiod/1000.0; // millièmes
// localpulsePWM1=(unsigned int) (float(cfg.timer1.pulse)*fperiod-0.5);
// localextractPWM1=(unsigned int) (float(cfg.timer1.extract)*fperiod-0.5);
// localdelayPWM1=(unsigned int) (float(cfg.timer1.delay)*fperiod-0.5);
localpulsePWM3=(unsigned int) (float(cfg.timer3.pulse)*fperiod-0.5);
localextractPWM3=(unsigned int) (float(cfg.timer3.extract)*fperiod-0.5);
localdelayPWM3=(unsigned int) (float(cfg.timer3.delay)*fperiod-0.5);
localpulsePWM4=(unsigned int) (float(cfg.timer4.pulse)*fperiod-0.5);
localextractPWM4=(unsigned int) (float(cfg.timer4.extract)*fperiod-0.5);
localdelayPWM4=(unsigned int) (float(cfg.timer4.delay)*fperiod-0.5);
// localpulsePWM5=(unsigned int) (float(cfg.timer5.pulse)*fperiod-0.5);
// localextractPWM5=(unsigned int) (float(cfg.timer5.extract)*fperiod-0.5);
// localdelayPWM5=(unsigned int) (float(cfg.timer5.delay)*fperiod-0.5);
cli();
// OCR1A=localfreqPWM;
OCR3A=localfreqPWM;
OCR4A=localfreqPWM;
// OCR5A=localfreqPWM;
// OCR1B=localpulsePWM1;
// OCR1C=localpulsePWM1;
// OCR1C=localextractPWM1;
OCR3B=localpulsePWM3;
OCR3C=localpulsePWM3;
// OCR3C=localextractPWM3;
OCR4B=localpulsePWM4;
OCR4C=localpulsePWM4;
// OCR4C=localextractPWM4;
// OCR5B=localpulsePWM5;
// OCR5C=localpulsePWM5;
// OCR5C=localextractPWM5;
// TCNT1=localdelayPWM1;
TCNT3=localdelayPWM3;
TCNT4=localdelayPWM4;
// TCNT5=localdelayPWM5;
sei();
}