WinAVR i zmienne



Masz problem? Zapytaj na forum elektroda.pl

Poprzedni Następny
Wiadomość
Spis treści
From: "Goju" <emdz_at_nospam_poczta.onet.pl>
Subject: WinAVR i zmienne
Date: Sun, 29 May 2005 16:34:28 +0200


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



Poprzedni Następny
Wiadomość
Spis treści
From: Jan Dubiec <jdx_at_nospam_SPAMTRAP.slackware.pl>
Subject: Re: WinAVR i zmienne
Date: 29 May 2005 17:00:02 +0200


On Sun, 29 May 2005 16:34:28 +0200, "Goju" <emdz_at_nospam_poczta.onet.pl> wrote:
Witam.
mam taki oto programik: (oczywiście uart jest wczaśniej odpowiednio
skonfigurowany)

uint32_t temp;
UDR=temp; // odczyt z uartu
Skoro odczyt, to IMO powinno być temp = UDR.

[.....]
Może sa jakieś inne rozwiązania by wpisywać 8-bitowe dane do 32-bitowej
zmiennej na odpowiednią pozycję.
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.
--
Jan Dubiec We're all living in Amerika
jdx#slackware.pl Coca Cola
+48 506 790442 Sometimes war
Amerika by Rammstein

Poprzedni Następny
Wiadomość
Spis treści
From: "Goju" <emdz_at_nospam_poczta.onet.pl>
Subject: Re: WinAVR i zmienne
Date: Sun, 29 May 2005 17:11:55 +0200




UDR=temp; // odczyt z uartu
Skoro odczyt, to IMO powinno być temp = UDR.

w programie było dobrze.

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.

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




Poprzedni Następny
Wiadomość
Spis treści
From: "ZyLex" <wkwj_at_nospam_gazeta.pl>
Subject: Re: WinAVR i zmienne
Date: Sun, 29 May 2005 17:03:47 +0200


uint32_t temp;
UDR=temp; // odczyt z uartu
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.
temp=temp<<24; //przesuniecie o 24 bity w lewo
temp=temp>>24; //przesuniecie o 24 bity w prawo
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



Poprzedni Następny
Wiadomość
Spis treści
From: "Goju" <emdz_at_nospam_poczta.onet.pl>
Subject: Re: WinAVR i zmienne
Date: Sun, 29 May 2005 17:21:55 +0200




uint32_t temp;
UDR=temp; // odczyt z uartu
Przecież tutaj NIE czytasz z UARTa tylko do niego ZAPISUJESZ czyli
wysyłasz
"w świat"
mój błąd -przy operacji ctrl+c ctrl+v .

zawartość zmiennej temp, a o ile znam kompilator, to wysyłasz najmłodszych
8
bitów
tej zmiennej.
temp=temp<<24; //przesuniecie o 24 bity w lewo
temp=temp>>24; //przesuniecie o 24 bity w prawo
Co chcesz osiągnąć tymi 2 liniami kodu ? Czy nie lepiej zamaskować to tak:
temp&=0x000000ff;

chciałem sprawdzić poprawność przesuniecia. gdyż wartości do zmiennej
32-bitowej
nie są poprawnie wpisywane.


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);

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.
.



Poprzedni Następny
Wiadomość
Spis treści
From: =?utf-8?B?UmFmYcWC?= <isab_at_nospam_poczta.neostrada.pl>
Subject: Re: WinAVR i zmienne
Date: Sun, 29 May 2005 21:04:57 +0200


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.

A po kompilacji nie wywala Ci uwag? Bo mi tak.

Musisz zmienną "temp" rzutować jako "long" :
czas=czas+((long)temp<<24)

Poprzedni Następny
Wiadomość
Spis treści
From: =?utf-8?B?UmFmYcWC?= <isab_at_nospam_poczta.neostrada.pl>
Subject: Re: WinAVR i zmienne
Date: Sun, 29 May 2005 21:51:10 +0200


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.

A po kompilacji nie wywala Ci uwag? Bo mi tak.

Musisz zmienną "temp" rzutować jako "long" :
czas=czas+((long)temp<<24)

I zmienną "temp" zadeklarować jako "unsigned"

Poprzedni Następny
Wiadomość
Spis treści
From: "jfk" <jaromir_fk_at_nospam_gazeta.pl>
Subject: Re: WinAVR i zmienne
Date: Mon, 30 May 2005 09:23:10 +0200



bitów
tej zmiennej.
temp=temp<<24; //przesuniecie o 24 bity w lewo
temp=temp>>24; //przesuniecie o 24 bity w prawo
Co chcesz osiągnąć tymi 2 liniami kodu ? Czy nie lepiej zamaskować to
tak:
temp&=0x000000ff;

chciałem sprawdzić poprawność przesuniecia. gdyż wartości do zmiennej
32-bitowej
nie są poprawnie wpisywane.


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);

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.
.

Sprobuj sumy bitowej zamiast arytmetycznej:
czas=czas | (temp<<24);