In order to better test my dcf77 library DCF77 Library | Blinkenlight under realistic conditions I want to implement a simple signal emulator. First step is to create a 77 500 Hz carrier. I tried with the code below. I already verified that the timing is correct (by adding digitalWrite + analysis with DSO). However I fail to get any signal on pin 3 (PD3, OC2B).
Obviously something with my timer2 configuration must be wrong. But what? Has anyone any hints for me?
// 16000000 / 77500 = 206 + 70/155 = 206 + 14/31
const uint8_t ticks_per_period = 206;
// fractional ticks
const uint8_t nominator = 14;
const uint8_t denominator = 31;
const uint8_t pwm_full_carrier = ticks_per_period / 2; // ~50 % duty cycle
const uint8_t pwm_modulated_carrier = ticks_per_period / 8; // ~12.5% duty cycle
ISR(TIMER2_COMPA_vect) {
static uint8_t accumulated_fractional_ticks;
accumulated_fractional_ticks += nominator;
if (accumulated_fractional_ticks < denominator) {
OCR2A = ticks_per_period - 1;
} else {
OCR2A = ticks_per_period;
accumulated_fractional_ticks -= denominator;
}
}
void setup_timer_0() {
// disable timer 0 interrupts
TIMSK0 = 0;
}
void setup_timer_1() {
// disable timer1 interrupts
TIMSK1 = 0;
// do not toggle or change timer IO pins
TCCR1A = 0;
// (16000000 / 256) - 1
OCR1A = 62500 - 1;
// Mode 4, CTC using OCR1A | set prescaler to 256
TCCR1B = (1<<WGM12) | (1<<CS12);
}
void setup_timer_2() {
// disable timer2 interrupts during setup
TIMSK2 = 0;
// enable OC2B pin for output (digital pin 3)
DDRD |= 1<<3;
// The fast Pulse Width Modulation or fast PWM mode (WGM22:0 = 3 or 7) provides a high fre-
// quency PWM waveform generation option. The fast PWM differs from the other PWM option by
// its single-slope operation. The counter counts from BOTTOM to TOP then restarts from BOT-
// TOM. TOP is defined as 0xFF when WGM2:0 = 3, and OCR2A when MGM2:0 = 7. In non-
// inverting Compare Output mode, the Output Compare (OC2x) is cleared on the compare match
// between TCNT2 and OCR2x, and set at BOTTOM. In inverting Compare Output mode, the out-
// put is set on compare match and cleared at BOTTOM.
TCCR2A = 1<< WGM20 || 1<<WGM21 || // Fast PWM
1<<COM2B1; // Clear OC2B on Compare Match
TCCR2B = 1<<CS20 || // no Prescaler
1<<WGM22; // Fast PWM
OCR2A = ticks_per_period - 1; // period length
OCR2B = pwm_full_carrier; // duty cycle
// enable match interrupts
TIMSK2 = 1<<OCIE2A;
}
void setup() {
setup_timer_0();
setup_timer_1();
setup_timer_2();
}
void modulate(const uint8_t duration) {
}
void loop() {
}