[avr-gcc] problem z arytmetyka ...

Oct 14, 2004 13 Replies

Witam, napisalem prosty programik to liczenia czasu twania okresu przebiegu prostokatnego na wejscie IC1. Wyglada jak ponizej:



volatile u16 Counter; volatile u16 Capture; volatile u08 Ready; volatile u08 Start; volatile u32 Wynik;



int main ( void ) {



ICR1 = 0; TCNT1 = 0; TIMSK |= (1<<TICIE1) | (1<<TOIE1); TCCR1B |= (1<<ICNC1);



#if defined (__AVR_ATmega128__) // Config IC1 port ATMEGA128 DDRD &= ~(1<<DDD4); PORTD &= ~(1<<PD4); #endif



Ready = 0; Start = 1; sei();



//----- Program glowny -------------------------------------------------------- while (1) {



if (Ready == 1) { Wynik = (u32)Counter * 0x0000FFFF + (u32)Capture; Ready = 0; }



}

return 0; }


SIGNAL(SIG_OVERFLOW1){ TCNT1 = 0; Counter++; Ready = 0; }



SIGNAL(SIG_INPUT_CAPTURE1){ if (Start == 1) { TCNT1 = 0; ICR1 = 0; TCCR1B |= (1<<CS10); //Start Timer1



Counter = 0; Ready = 0; Start = 0; } else { Capture = ICR1; TCCR1B &= ~(1<<CS10); //Stop Timer1



Ready = 1; Start = 1; }



}

Wycialem procedury wyswietlania wyniku na LCD zeby nie zasmiecac zbytnio. Jednak zauwazylem ze Counter nie jest mnozona przez 0x0000FFFF i przyjmuje warosc ujemna jak rowniez Capture tez jest raz ujemna a raz dodatnia. Ludzie co jest grane???? Gdzie tkwi blad. Na AVRStudio 4.0 wszystko sie symuluje poprawnie (wrrr).



Akurat AVR-studio nie znam, ale moze mnozyc przez 0x0ffffL ?

No i po cholere taka operacja? Bo siakos nie rozumiem. Napisz po ludzku: wynik=(counter<<16)-1+capture

A dlaczego mno¿ysz przez 65535 a nie 65536? My¶lê zê bardziej poprawnie to powinno wygl±daæ tak: Wynik = (u32)(Counter) *(u32) (0x10000) + (u32)Capture;

A co znaczy, ze wynik raz jest ujemny raz dodatni? Przecie¿ wynik masz typu unsigned.

A tak wogóle to kiedy wyliczasz ten Wynik to powiniene¶ zablokowaæ przerwania.

Co to jest ICR1 ? rejestr 8 bitowy czy 16 ?

To tak pobieznie...

Pozdrawiam Mister

Wyswietlam Wynik na LCD i raz pokazuje sie ujemny a raz dodatni i nie jest to blad w wyswietlaniu :(

na wyliczenie mam caly okres przebiegu przed przeklamaniem oblicznie zabezpiecza mnie if (Ready == 1) ....

16bit

Witaj A sk±d wiesz, ¿e warto¶ci s± ujemne? Z procedury LCD, która wy¶wietla warto¶ci zarówno dodatnie jak i ujemne? Je¿eli w wyniku pojawia siê jedynka na najstarszej pozycji, to liczba mo¿e byæ traktowana jako ujemna. Ogólnie przyjrzyj siê zapisowi heksadecymalnemu i sprawd¼, czy wyniki s± poprawne. Pozdr EM

Jak nie? widocznie procedura obs³ugi LCD spodziewa sie signed. Nic nie piszesz czy poprawienie rzutowania da³o efekt.

Zaraz, czy w Mega 128 mo¿na bezpo¶rednio zapisaæ rejestr 16 bitowy ? przecie¿ to procek 8 bitowy.

Mister

W hexie tez sa anomalia ...

Jeszcze raz zapytam W AVRstudio wszystko jest OK, tzn. wyniki zgodne z oczekiwanymi? Je¶li tak: Gdzie wyskakuj± warto¶ci ujemne? Na LCD? Jakie anomalia w hexie?

Na LCD.

np Capture wyswietla 4fc1, Counter c1, a Wynik 4f00. Sprawdzalem wszystkie warianty zaproponowane przez kolegow w poprzednich watkach.

Podstawmy i obliczmy: Wynik powinien byæ C14F00

-> wniosek - liczba obciêta do typu u16 (a nie np. brak mono¿enia przez FFFF)

Procedura LCD nie obs³uguje liczb u32 poprawnie?

do wyswietlania uzywam stdio.h i printf ();

A dopisujesz l?

np. printf("%lx", Wynik);

Mister

bylo, ale pogrzebalem w makefile i all dziala !! big tx.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required