Good evening everyone,
I have bene playing around with making my own library, specifically for the controlling Timer1 on the Arduino Mega 2560. I'm sort of new to OOP but I am trying my hand at it here.
I wrote some code to generate a PWM wave with a 100 ms period and a 25% duty cycle, and I have Siglent SDS 1052DL, 50MHz oscilloscope that I'm using that verifies the code is successful. I am using clear-timer-on-compare-match mode and timer interrupts to generate the PWM wave. My code is below:
#include "Timer1.h"
Timer1 timer;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(13, OUTPUT);
timer.begin();
}
void loop(){
// put your main code here, to run repeatedly:
}
I made a Timer1.cpp file and a Timer1.h to go along with this file. They are below.
Timer1.cpp
#include "Arduino.h"
#include "Timer1.h"
float frequency = 10.0;
float period_ms;
float clock_pulse = 16.0;
unsigned long opening_time = 25000;
unsigned int ocr1a;
unsigned int ocr1b;
Timer1::Timer1() { // Object used to control 16-bit timer1
}
void Timer1::begin() {
CRITICAL_SECTION_START; // Clear I bit
CLEAR_TCCR1A; // Reset TCCR1A
CLEAR_TCCR1B; // Reset TCCR1B
SET_CTC_MODE; // Set to CTC mode
DISABLE_TIMER1_INTERRUPTS; // Disable OCIE1A/B
TCCR1B |= (1 << CS12); // 256
period_ms = (1000.0f / frequency);
ocr1a = 1000UL * (period_ms / clock_pulse);
OCR1A = ocr1a;
TIMSK1 |= (1 << OCIE1A);
ocr1b = (unsigned int)float(opening_time) / clock_pulse;
OCR1B = ocr1b;
TIMSK1 |= (1 << OCIE1B);
TCNT1 = 0; // Reset counter
CRITICAL_SECTION_END; // Set I bit
}
ISR(TIMER1_COMPA_vect) {
digitalWrite(13, HIGH);
}
ISR(TIMER1_COMPB_vect) {
digitalWrite(13, LOW);
}
Timer1.h
#ifndef TIMER1_H
#define TIMER1_H
// ========== HANDY MACROS ========== //
#define CLEAR_TCCR1A TCCR1A = 0
#define CLEAR_TCCR1B TCCR1B = 0
#define SET_CTC_MODE TCCR1B |= (1 << WGM12)
#define DISABLE_TIMER1_INTERRUPTS TIMSK1 &= ~((1 << OCIE1B) | (1 << OCIE1A))
#define CLEAR_CLOCK_SELECT_BITS TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10))
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli()
#define CRITICAL_SECTION_END SREG = _sreg
class Timer1{
public:
// Constructor:
Timer1();
// Begin:
void begin();
};
#endif // TIMER1_H
This code works exactly as I would expect. I originally had placed the whole block of code found in the Timer1::begin() method in the Timer1::Timer1() constructor method. When I did this, I was getting a completely different signal (2.04 ms period with about an 80% duty cycle). Is there a simple explanation for what is occurring?