2 #include <util/delay.h>
4 #include <avr/interrupt.h>
9 // init PLL clock for timer/counter 1
10 // datasheet sekce 12.2.1
11 static void enable_pll_clock()
14 PLLCSR = _BV(PLLE) | _BV(LSM); // low-speed mode (32 MHz)
16 // Synchronize to the phase lock
18 while((PLLCSR & _BV(PLOCK)) == 0)
23 // Timer/Counter 1 initialization
25 static void init_tc1()
27 power_timer1_enable();
29 TCCR1 = _BV(CTC1) // clear on compare match
30 | _BV(CS10) // clock = PCK (no divisor)
31 | _BV(COM1A1) // clear output line on compare match
32 | _BV(PWM1A); // PWM mode
34 OCR1C = 255; // TOP value
39 // Tohle pripadne povoli PWM i na OC1B (PB4)
40 // GTCCR = _BV(COM1B1) | _BV(PWM1B);
42 // OCR1B = 0; // stride
45 // precte synchronne (busy-waitem) jednu hodnotu z A/D prevodniku
46 static uint16_t read_adc_sync()
50 ADCSRA |= _BV(ADSC); // start the conversion
52 // wait for the conversion to finish
53 while((ADCSRA & _BV(ADIF)) == 0)
57 ADCSRA |= _BV(ADIF); // clear the IRQ flag
62 // analog to digital converter
64 static void init_adc()
67 ACSR |= _BV(ACD); // enable ADC, disable AC
69 ADCSRA = _BV(ADEN) // enable
70 | _BV(ADPS1) | _BV(ADPS0) // CLK/8 = 125 kHz
73 DIDR0 = _BV(ADC1D) | _BV(ADC3D); // disable dig. input on ADC1, ADC3 (PB2, PB3)
74 ADMUX = _BV(REFS1) // 1.1V internal reference
75 | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0) // ADC4 (temperature)
78 // do the first conversion, drop the result
88 log_byte(0x42); // zkouska logovani
89 log_flush(); // nezapomenout vylit buffer
91 power_all_disable(); /* vypneme cele I/O, pak zapneme co bude potreba */
93 DDRB |= _BV(DDB4); // PB4 as output
99 // po skonceni inicializace muzeme i zapnout preruseni,
100 // pokud je budeme potrebovat
103 // priklad prace s A/D prevodnikemo
104 // init_adc() necha ADMUX nastaveny na ADC4 (teplomer), jinak
105 // tady lze ADMUX prestavit na neco jineho (pozor na napetovou
107 log_word(read_adc_sync()); // nacteme teplotu, zalogujeme
108 // interpretace vysledku: datasheet sekce 17.12
112 for (i = 0; i < 16; i++) {
113 // zapiname/vypiname portb4 v sudem/lichem kroku
115 PORTB |= _BV(PORTB4);
117 PORTB &= ~_BV(PORTB4);
120 // hodnopta PWM pro PB1 (OC1A)
121 // jdeme od 128 do 248, napriklad:
122 OCR1A = 0x80 + (i << 3);
124 // busy-wait, nebo se muzeme nechat casovat
125 // pomoci watchdogu (WDT, datasheet sekce 7.4.5)
126 // nebo pomoci Timer/Counter 0 (datasheet sekce 11)