// Test for CTC mode for Timer1 pin 9 and Timer2 pin 11
//
// Calculate myOCR:
// Select frequency, for example 625Hz.
// Select a prescaler, for example 256
// The OCR = 16MHz / (frequency * prescaler) - 1 = 49
//
// Test 1
// myIndex = 3, myOCR = 49 => 625 Hz in PulseView Good
// Test 2
// myIndex = 0, myOCR = 159 => 50.000 kHz in PulseView Good
// With my Uno (with resonator) in real life: Bad, 49.7kHz
// Test 3
// A Uno clone with a accurate 16MHz crystal.
// The LHT00SU1 turns out to sample at a wrong rate at 48MHz.
// It is accurate at 24MHz sample rate.
//
// Conclusion: My resonator is bad, my LHT00SU1 is not accurate at 48MHz,
// the CTC mode in Wokwi is the same as in real life.
// The other mode is probably correct by Wokwi as well.
// The combined prescaler values for Timer1 and Timer2.
const unsigned prescalerlist[5] = { 1, 8, 64, 256, 1024 };
// Select the index for the prescaler array and the OCR value
int myIndex = 0; // 0...4
uint8_t myOCR = 159; // 0...255
void setup()
{
Serial.begin(115200);
pinMode( 9, OUTPUT); // Timer1
pinMode( 11, OUTPUT); // Timer2
float result = float(F_CPU) / (float(prescalerlist[myIndex]) * (float(myOCR) + 1.0) * 2.0);
Serial.print( "result: ");
Serial.print( result, 4);
Serial.println( " Hz");
// convert the choosen prescaler index to
// the bits of the register for the TCCR1B register.
int prescaler = myIndex + 1;
// Set Timer1, pin 9
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = myOCR;
TCCR1A = _BV(COM1A0); // OC1A is toggle output
TCCR1B = _BV(WGM12) | (uint8_t) prescaler; // ctc mode
// Convert the prescaler even more, for the bits
// of the TCCR2B register
prescaler += (prescaler / 3) + (prescaler / 4);
// Set Timer2, pin 11
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;
OCR2A = myOCR;
TCCR2A = _BV(WGM21) | _BV(COM2A0); // ctc mode, OC2A is toggle output
TCCR2B = (uint8_t) prescaler; // start
}
void loop() {}