Je besser die Hardware, desto kompakter der Code.
1 |
#include <avr/io.h>
|
2 |
|
3 |
int main(void)
|
4 |
{
|
5 |
const uint32_t coefficient = 2577; // coefficient (@ 3.33 MHz main clock)
|
6 |
uint16_t frequency = 500; // frequency (Hz)
|
7 |
uint32_t tcfcmp = coefficient * frequency >> 8; // compare value for TCF0.CMP
|
8 |
|
9 |
TCF0.CTRLB = TCF_WGMODE_NCOFDC_gc; // NCO fixed duty-cycle
|
10 |
while(TCF0.STATUS){}; // wait if busy
|
11 |
TCF0.CMP = tcfcmp; // write compare value
|
12 |
TCF0.CTRLC = TCF_WO0EN_bm; // enable TCF WO0 (PA0)
|
13 |
TCF0.CTRLA = TCF_ENABLE_bm; // enable TCF
|
14 |
|
15 |
TCB0.CCMP = 0x8234; // timeout value (20ms)
|
16 |
TCB0.CTRLA = TCB_CLKSEL_DIV2_gc | TCB_ENABLE_bm; // 1.666 MHz, enable TCB0
|
17 |
|
18 |
while(1)
|
19 |
{
|
20 |
if(TCB0.INTFLAGS)
|
21 |
{
|
22 |
TCB0.INTFLAGS = TCB_CAPT_bm; // clear TCB0 interrupt flag
|
23 |
frequency += 1;
|
24 |
if(frequency > 1000)
|
25 |
{
|
26 |
frequency = 500;
|
27 |
}
|
28 |
tcfcmp = coefficient * frequency >> 8; // calculate
|
29 |
while(TCF0.STATUS & TCF_CMP0BUSY_bm){}; // wait if busy
|
30 |
TCF0.CMP = tcfcmp; // update
|
31 |
}
|
32 |
}
|
33 |
}
|
AVR16EB14 Data Sheet:
"This linear advantage over divide-by-n timers comes at the cost of the output jitter. However, the jitter that occurs periodically is always plus or minus one clock period, depending on the division remainder."