Я пытаюсь создать несколько PWM-волн, используя таймер TC в Arduino Due. Моя проблема в том, что я не могу генерировать точные частоты, используя такие таймеры.Как создать точный таймер в Arduino Due
Вот простой код для того, что я пытаюсь сделать:
static void setupTimer(uint32_t freq_desired)
{
uint32_t ul_div;
uint32_t ul_tcclks;
uint32_t ul_sysclk = sysclk_get_cpu_hz();
uint32_t counts;
// Configure PMC
pmc_enable_periph_clk(ID_TC);
// Configure TC for the given frequency and trigger on RC compare.
tc_find_mck_divisor(
(uint32_t)freq_desired, // The desired frequency as a uint32.
ul_sysclk, // Master clock freq in Hz.
&ul_div, // Pointer to register where divisor will be stored.
&ul_tcclks, // Pointer to reg where clock selection number is stored.
ul_sysclk); // Board clock freq in Hz.
tc_init(TC0, CHANNEL, ul_tcclks | TC_CMR_CPCTRG);
// Find the best estimate of counts, then write it to TC register C.
counts = (ul_sysclk/ul_div)/freq_desired;
tc_write_rc(TC0, 0, counts);
// Enable interrupts for this TC, and start the TC.
tc_enable_interrupt(TC0, CHANNEL0, TC_IER_CPCS); // Enable interrupt.
tc_start(TC0,CHANNEL0); // Start the TC.
NVIC_DisableIRQ(TC_IRQn);
NVIC_ClearPendingIRQ(TC_IRQn);
NVIC_SetPriority(TC_IRQn,configMAX_PRIORITIES);
NVIC_EnableIRQ(TC_IRQn);
}
Тогда на ручки таймера все, что я делаю, спровоцировав выходной контакт с:
ioport_toggle_pin_level(OUT_PIN);
Проблема заключается в том что когда я пытаюсь, например, генерировать волну 1000 Гц (давая, конечно, 2000 Гц для таймера), он отлично работает. Но когда я пытаюсь, например, 3427 Гц, тогда он генерирует только 3420 Гц или что-то в этом роде.
Есть ли у вас какие-либо идеи, как это исправить? Я попытался добавить round() для вычисления значения «counts» , это помогло немного, но все же не очень точно.
Заранее спасибо.
Не думаю, что вы можете сделать это точным, потому что 16 000 000 (системная тактовая частота) неразделимо на 3427. – MikeCAT
Подумайте, как @MikeCAT. Вероятно, проблема заключается в множественности с 16 МГц ... – jabujavi
Да, это то, о чем я тоже думал (я использую Due, поэтому часы составляют 84 МГц). Так есть ли другой способ получить эту точность с использованием других механизмов, чем таймеры TC? –