X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=main.c;h=07ef6cc351ca0f1a3f57e15a5ca4f5c7d0c2ba86;hb=a968de353b007e247391470626d01152519de09c;hp=0fbb9196d5f4e74f1ef4f7f1b295858ea5113741;hpb=17cbca493bd2ecc9317b7b934e7a2807c5212c4c;p=kolektor.git diff --git a/main.c b/main.c index 0fbb919..07ef6cc 100644 --- a/main.c +++ b/main.c @@ -42,7 +42,10 @@ static void init_tc1() // 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; @@ -59,6 +62,25 @@ static uint16_t read_adc_sync() 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() @@ -71,26 +93,27 @@ 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(); @@ -101,30 +124,35 @@ int main(void) // 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(); } }