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."