Witam,
Chcę dokonać pomiaru odległości ultradźwiękami. Najpierw program wysterowuje nadajnik ultradźwiękowy falą prostokątną 40kHz (timer0). W tym czasie rusza też timer1 mierzący czas do odebrania sygnału przez odbiornik. Po pewnej chwili (gdy timer1 osiągnie wartość wpisaną do rejestru OCR1AL) wyłączam generację prostokąta (zatrzymuje timer0). I teraz program tylko czeka na odbiór fali przez odbiornik. Problem jest taki że wykonując to cyklicznie co drugi wynik pomiaru różni się o około 20 (czyli np. otrzymuję kolejno 340, 361, 340, 361, 340..)
Nie mogę znaleźć powodu takiego działania dlatego prosiłbym o pomoc:) Może zajmie to komuś z Was pare minut, a ja siedzę już 3 dni nad tym:/. Dodam że uwzględnianie co drugiej wartości pomiaru nie wchodzi w grę niestety:)
Poniżej zamieszczona jest pętla główna programu w C oraz część pliku *.lss. Nie znam sie za dobrze na asemblerze AVR bo zetknąłem się tylko dawno temu z asemblerem '51. Może należy zamienić te pare linijek na kod w asm? Albo jakiś inny zapis tego w C?
Sprawdzałem też wersję w wyłączeniem obsługi przerwań (zakomentowane komendy cli() i niżej sei() ) i nic. Próbowałem też wersję z użyciem rejestru przechwytywania ICR1 i wynik taki sam.
pętla główna w C:
fragment wygenerowanego pliku *.lss
Chcę dokonać pomiaru odległości ultradźwiękami. Najpierw program wysterowuje nadajnik ultradźwiękowy falą prostokątną 40kHz (timer0). W tym czasie rusza też timer1 mierzący czas do odebrania sygnału przez odbiornik. Po pewnej chwili (gdy timer1 osiągnie wartość wpisaną do rejestru OCR1AL) wyłączam generację prostokąta (zatrzymuje timer0). I teraz program tylko czeka na odbiór fali przez odbiornik. Problem jest taki że wykonując to cyklicznie co drugi wynik pomiaru różni się o około 20 (czyli np. otrzymuję kolejno 340, 361, 340, 361, 340..)
Nie mogę znaleźć powodu takiego działania dlatego prosiłbym o pomoc:) Może zajmie to komuś z Was pare minut, a ja siedzę już 3 dni nad tym:/. Dodam że uwzględnianie co drugiej wartości pomiaru nie wchodzi w grę niestety:)
Poniżej zamieszczona jest pętla główna programu w C oraz część pliku *.lss. Nie znam sie za dobrze na asemblerze AVR bo zetknąłem się tylko dawno temu z asemblerem '51. Może należy zamienić te pare linijek na kod w asm? Albo jakiś inny zapis tego w C?
Sprawdzałem też wersję w wyłączeniem obsługi przerwań (zakomentowane komendy cli() i niżej sei() ) i nic. Próbowałem też wersję z użyciem rejestru przechwytywania ICR1 i wynik taki sam.
pętla główna w C:
Kod: C / C++
fragment wygenerowanego pliku *.lss
//cli();
// SFIOR - reset preskalera
SFIOR = (1 << PSR10);
7d6: f0 be out 0x30, r15 ; 48
TCCR1B = 2; // start T1 częstotliowsc taktowania = CLK/8
7d8: ee bc out 0x2e, r14 ; 46
TCCR0 = (1 << WGM01)|(1 << COM00)|(1 << CS00); //start T0, tryb CTC
7da: d3 be out 0x33, r13 ; 51
//oczekiwanie na chwile gdy minie OCR1AL czasu na T1, wtedy zakończ generacje 40kHz
while(!(TIFR & 0x10)){};
7dc: 08 b6 in r0, 0x38 ; 56
7de: 04 fe sbrs r0, 4
7e0: fd cf rjmp .-6 ; 0x7dc <main+0xb0>
TCCR0 = 0; //zatrzymanie generacji paczki impulsów 40kHz
7e2: 13 be out 0x33, r1 ; 51
PORTB |= _BV(3); //stan wysoki na wyjsciu PB3 (OC0)
7e4: c3 9a sbi 0x18, 3 ; 24
while (!(GIFR & 0x40));
7e6: 0a b6 in r0, 0x3a ; 58
7e8: 06 fe sbrs r0, 6
7ea: fd cf rjmp .-6 ; 0x7e6 <main+0xba>
TCCR1B = 0; // stop T2
7ec: 1e bc out 0x2e, r1 ; 46
//sei();
if(!timeout) //jeśli czas odebrania nie upłynął to wypisz nową wartosc
7ee: 80 91 66 00 lds r24, 0x0066
7f2: 88 23 and r24, r24
7f4: 99 f0 breq .+38 ; 0x81c <main+0xf0>
}