// OCR1B = 0; // stride
}
-// precte synchronne (busy-waitem) jednu hodnotu z A/D prevodniku
+// Precte synchronne (busy-waitem) jednu hodnotu z A/D prevodniku.
+// Alternativa je nastavit bit ADSC a ADIE, delat neco jineho,
+// a pockat az prijde ADC interrupt (viz firmware "step-up" na strance
+// tinyboard).
static uint16_t read_adc_sync()
{
uint16_t rv;
return rv;
}
+// vyber kanalu A/D prevodniku (datasheet tabulka 17-4 v sekci 17.13.1)
+typedef enum { ADC1, ADC3, ADC4 } adc_channel;
+static void select_adc_channel(adc_channel c)
+{
+ switch (c) {
+ case ADC1:
+ ADMUX = _BV(REFS1) | _BV(MUX0); // ADC1 (PB2), 1.1V ref
+ break;
+ case ADC3:
+ ADMUX = _BV(REFS1) | _BV(MUX1) | _BV(MUX0); // ADC3 (PB3), 1.1V ref
+ break;
+ case ADC4:
+ ADMUX = _BV(REFS1) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0) // ADC4 (temperature), 1.1V ref
+ break
+ ;
+ }
+}
+
+
// analog to digital converter
// datasheet sekce 17
static void init_adc()
;
DIDR0 = _BV(ADC1D) | _BV(ADC3D); // disable dig. input on ADC1, ADC3 (PB2, PB3)
- ADMUX = _BV(REFS1) // 1.1V internal reference
- | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0) // ADC4 (temperature)
- ;
+ select_adc_channel(ADC4);
// do the first conversion, drop the result
read_adc_sync();
}
+// priklad vselijakych moznosti, co tenhle HW umi
int main(void)
{
unsigned char i;
- init_log();
+ init_log(); // viz logging.c - detekce poctu resetu, atd.
log_byte(0x42); // zkouska logovani
log_flush(); // nezapomenout vylit buffer
power_all_disable(); /* vypneme cele I/O, pak zapneme co bude potreba */
- DDRB |= _BV(DDB4); // PB4 as output
+ DDRB |= _BV(DDB4); // PB4 as output (lze misto tohoto pouzit jako PWM)
+
+ PORTB |= _BV(PB0); // PB0 interni pull-up (aby tady byla 1, pokud je plovak rozepnuty)
enable_pll_clock();
init_tc1();
// cli();
// priklad prace s A/D prevodnikemo
- // init_adc() necha ADMUX nastaveny na ADC4 (teplomer), jinak
- // tady lze ADMUX prestavit na neco jineho (pozor na napetovou
- // referenci REFS)
- log_word(read_adc_sync()); // nacteme teplotu, zalogujeme
+ select_adc_channel(ADC4); // interni teplomer na cipu
+ log_word(read_adc_sync()); // nacteme teplotu cipu, zalogujeme
// interpretace vysledku: datasheet sekce 17.12
log_flush();
+ // ve smycce budeme merit jak se meni hodnota na ADC3 (PB3)
+ select_adc_channel(ADC3);
+
while(1) {
- for (i = 0; i < 16; i++) {
- // zapiname/vypiname portb4 v sudem/lichem kroku
- if (i & 1) {
- PORTB |= _BV(PORTB4);
- } else {
- PORTB &= ~_BV(PORTB4);
- }
-
- // hodnopta PWM pro PB1 (OC1A)
- // jdeme od 128 do 248, napriklad:
- OCR1A = 0x80 + (i << 3);
-
- // busy-wait, nebo se muzeme nechat casovat
- // pomoci watchdogu (WDT, datasheet sekce 7.4.5)
- // nebo pomoci Timer/Counter 0 (datasheet sekce 11)
- _delay_ms(1500);
+ // PB4 (motor 2) zapínáme podle sepnutí plováku PB0
+ if (PINB & _BV(PINB0)) { // rozepnuto (1)
+ PORTB &= ~_BV(PORTB4);
+ } else { // sepnuto (0)
+ PORTB |= _BV(PORTB4);
}
+
+ // hodnota PWM pro PB1 (OC1A)
+ // jdeme od 128 do 248, napriklad:
+ OCR1A = 0x80 + (i << 3);
+
+ // busy-wait, nebo se muzeme nechat casovat
+ // pomoci watchdogu (WDT, datasheet sekce 7.4.5)
+ // nebo pomoci Timer/Counter 0 (datasheet sekce 11)
+ _delay_ms(1500);
+
+ i++;
+ i &= 0xF;
+
+ log_word(read_adc_sync()); // nacteme hodnotu, zalogujeme
+ log_flush();
}
}