Witam. mam taki oto programik: (oczywi¶cie uart jest wcza¶niej odpowiednio skonfigurowany)
uint32_t temp; UDR=temp; // odczyt z uartu temp=temp<<24; //przesuniecie o 24 bity w lewo temp=temp>>24; //przesuniecie o 24 bity w prawo UDR=temp; // wys³anie bajtu
Niby proste, ale wysy³am 255, a odczytuje 253. Nie wiem czym to jest spowodowane. Prosze o pomoc. Mo¿e sa jakie¶ inne rozwi±zania by wpisywaæ 8-bitowe dane do 32-bitowej zmiennej na odpowiedni± pozycjê. pozdrawiam
Didn't find your answer? Ask the community — no account required.
J
Jan Dubiec
Skoro odczyt, to IMO powinno być temp = UDR.
[.....]
Są - poczytaj o uniach. Ale należy sobie zdawać sprawę, że kod korzystający z unii w ogólności nie jest przenośny. Tzn. jeśli nagle zapragniesz przenieść ten kod na inną architekturę, to skompiluje się ładnie, ale będzie działać niekoniecznie zgodnie z oczekiwaniami.
Regards, /J.D.
Z
ZyLex
Przecie¿ tutaj NIE czytasz z UARTa tylko do niego ZAPISUJESZ czyli wysy³asz "w ¶wiat" zawarto¶æ zmiennej temp, a o ile znam kompilator, to wysy³asz najm³odszych 8 bitów tej zmiennej.
Co chcesz osi±gn±æ tymi 2 liniami kodu ? Czy nie lepiej zamaskowaæ to tak: temp&=0x000000ff; Poza tym dla bezpieczeñstwa i pewno¶ci stosuj rzutowanie: (unsigned char)temp; Ale i tak nie za bardzo rozumiem, co ma ten programik tak na prawdê zrobiæ... :-) Je¿eli chcesz odebraæ 4 bajty i zrobiæ z nich uint32 to mo¿esz to zrobiæ np. tak: temp=UDR; // poczekaj na odbiór nastêpnego bajtu temp+=(UDR<<8); // poczekaj na odbiór nastêpnego bajtu temp+=(UDR<<16); // poczekaj na odbiór nastêpnego bajtu temp+=(UDR<<24); To, w jaki sposób sprawdzasz, czy odebra³e¶ ju¿ nastepny bajt, zale¿y od stosowanego uC. Poza tym nie wiem, czy nie by³oby konieczne wprowadzenie jeszcze jednej zmiennej posredniej typu uchar i przepisywanie do niej zawarto¶ci UDR i u¿ywanie dopiero tej zmiennej do obliczeñ. Dlaczego ? Bo, przynajmniej w ATmega16, UDR jest 2. elementowym buform ko³owym a ka¿dy odczyt z niego "przewija" ten bufor. A nigdy nie masz pewno¶ci, jak kompilator przet³umaczy niby proste polecenie "temp+=(UDR<<n) i czy nie bêdzie tam 2x odwo³ania do UDR... Wysy³ka uint32 jest prostsza: UDR=(unsigned char)temp; // poczekaj na mo¿liwo¶æ wys³ania nastêpnego bajtu przez UART UDR=(unsigned char)(temp>>8); // poczekaj na mo¿liwo¶æ wys³ania nastêpnego bajtu przez UART UDR=(unsigned char)(temp>>16); // poczekaj na mo¿liwo¶æ wys³ania nastêpnego bajtu przez UART UDR=(unsigned char)(temp>>32); Pozdrawiam, zylex
G
Goju
w programie by³o dobrze.
mo¿e niedok³adnie napisa³em, ale korzystam ze zmiennych 32-bitowych. dane wpisuje do niej odpowiednio przesuwaj±c zmienne 8-bitowe. problem jest tego rodzaju, ¿e przesuniêcie o 8 i 16 bitów dzia³±ja dobrze, je¶li natomiast przesuwam o 24 bity to obcinany jest najmniejznacz±cy bit. uint32_t temp,czas; czas=temp; //pierwszy 8-bajt czas=czas+(temp<<8); //drugi bajt czas=czas+(temp<<16); //trzeci czas=czas+(temp<<24); //czwarty
G
Goju
mój b³±d -przy operacji ctrl+c ctrl+v .
chcia³em sprawdziæ poprawno¶æ przesuniecia. gdy¿ warto¶ci do zmiennej
32-bitowej nie s± poprawnie wpisywane.
ja robie to tak: czas=temp; //pierwszy 8-bajt .. czas=czas+(temp<<8); //drugi bajt .. czas=czas+(temp<<16); //trzeci .. czas=czas+(temp<<24); tylko ¿e trzy pierwsze bajty zapisuj± siê poprawnie, a z ostatnim jest problem. my¶la³em ¿e to mo¿e co¶ z pamiêci± , wiêc zmieni³em adresy komórk które tworz± zmienn± czas i temp ale to nic nie da³o. .
R
Rafał
A po kompilacji nie wywala Ci uwag? Bo mi tak.
Musisz zmienną "temp" rzutować jako "long" : czas=czas+((long)temp<<24)
R
Rafał
I zmienną "temp" zadeklarować jako "unsigned"
J
jfk
Sprobuj sumy bitowej zamiast arytmetycznej: czas=czas | (temp<<24);
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.