Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięZapis unsigned long w pamięci 2402.
Moderatorzy:Jacek Bogusz, robertw, k.pawliczak, Moderatorzy
Cześć.
Chciałem Was prosić o pomoc.
Mam zmienną typu unsigned long (4 bajtową) i muszę ją zapamiętać w pamięci EEPROM 2402. Dane do układu są przesyłane po 8 bitów. Co zrobić aby można było zapamiętać tą liczbę w pamięci a następnie odczytać z niej i ponownie zapisać jako ulong.
Napewno trzeba ją podzielić na fragmęty po 8 bitów tylko jak.
Druga rzecz o którą nie wiem zbyt jak zrobić to jak zwiększyć pojemnośc zmiennej jak wyżej. Maksymalna wartość dla danej typu unsigned long jest za mała i chciałbym ją powiększyć do np 40 bitów. Na tej zmienne potrzebne będą operacje dodawania odejmowania dzielenia i mnożenia czyli typowe działania.
Będę naprawdę wdzięczny za pomoc.
Sławek.
Chciałem Was prosić o pomoc.
Mam zmienną typu unsigned long (4 bajtową) i muszę ją zapamiętać w pamięci EEPROM 2402. Dane do układu są przesyłane po 8 bitów. Co zrobić aby można było zapamiętać tą liczbę w pamięci a następnie odczytać z niej i ponownie zapisać jako ulong.
Napewno trzeba ją podzielić na fragmęty po 8 bitów tylko jak.
Druga rzecz o którą nie wiem zbyt jak zrobić to jak zwiększyć pojemnośc zmiennej jak wyżej. Maksymalna wartość dla danej typu unsigned long jest za mała i chciałbym ją powiększyć do np 40 bitów. Na tej zmienne potrzebne będą operacje dodawania odejmowania dzielenia i mnożenia czyli typowe działania.
Będę naprawdę wdzięczny za pomoc.
Sławek.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Re: Zapis unsigned long w pamięci 2402.
A co, jesli mozna wiedziec, ma przechowywac taka zmienna? 40 bitow interpretowane jako liczba calkowita bez znaku (ze znakiem zreszta tez) to ogromna wartosc maksymalna! Cos ok. 10^12.Maksymalna wartość dla danej typu unsigned long jest za mała i chciałbym ją powiększyć do np 40 bitów.
Implementacja +,-,*,/ na takich liczbach jest mozliwa, ale bedzie niezbyt efektywna na uC 8-bitowym. Moze ARMik? masz 32 bity z marszu (o ile tyle Ci wystarczy) .
Co do ARMika to odpada na razie ani nie mam pod ręką ani nie jestem do nich przekonany.
A może jakaś rada co z zapisaniem tej liczby Unsigned long w pamięci EEPROM na 8bitach, jak z tym sobie poradzić.
Przy okazjo jeśli można to się zapytam o dwie takie rzeczy:
1) Często widzę zapis liczby 16L dlaczego dodaje się to L na końcu. Jeśli mam long i=16; to i tak zapisze tą 16 tak jak trzeba to po co jeszcze dodawać L.
2) Mam zmienną "unsigned long wynik" .W 8051 jest licznik 16 bitowy zapisujący TH0 (starszą) i TL0 (młodszą) część liczby, jak dodać do zmiennej wynik zawartość licznika.
A może jakaś rada co z zapisaniem tej liczby Unsigned long w pamięci EEPROM na 8bitach, jak z tym sobie poradzić.
Przy okazjo jeśli można to się zapytam o dwie takie rzeczy:
1) Często widzę zapis liczby 16L dlaczego dodaje się to L na końcu. Jeśli mam long i=16; to i tak zapisze tą 16 tak jak trzeba to po co jeszcze dodawać L.
2) Mam zmienną "unsigned long wynik" .W 8051 jest licznik 16 bitowy zapisujący TH0 (starszą) i TL0 (młodszą) część liczby, jak dodać do zmiennej wynik zawartość licznika.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
ARM - maly straszek?
Zapis w EEPROM: AND z odpowiednia maska bitowa i odpowiednie przesuniecie, np. dla bajta numer 2 (0 - najmniej znaczacy bajt)
Z dokladnoscia do tego, ze unsigned long nie musi we wszystkich implementacjach oznaczac zmiennej zapisywanej na 4 bajtach, a unsigned char - na jednym (choc zwykle tak jest).
1) chodzi o to aby powiedziec kompilatorowi wprost: te stala interpretuj jako long. nie musi sie on "domyslac" na podstawie kontekstu i nie musowo rzutowac. w prostych wyrazeniach mozna pominac, w bardziej skomplikowanych taki zapis (z L) pozwala uniknac klopotow. To tak jak np. zapis 3 nie pozwala sie domyslec, czy chodzi o float czy int (long). Zapis 3.0 jednoznacznie wskazuje na float, zapis 3L - na long.
2). to powinno zostac zinterpretowane prawidlowo, ale mozna zapisac bardziej "lopatologicznie" (z rzutowaniem).
Zapis w EEPROM: AND z odpowiednia maska bitowa i odpowiednie przesuniecie, np. dla bajta numer 2 (0 - najmniej znaczacy bajt)
Kod: Zaznacz cały
unsigned long number_long;
unsigned char byte2=(number_long & 0xFF0000)>>16;
1) chodzi o to aby powiedziec kompilatorowi wprost: te stala interpretuj jako long. nie musi sie on "domyslac" na podstawie kontekstu i nie musowo rzutowac. w prostych wyrazeniach mozna pominac, w bardziej skomplikowanych taki zapis (z L) pozwala uniknac klopotow. To tak jak np. zapis 3 nie pozwala sie domyslec, czy chodzi o float czy int (long). Zapis 3.0 jednoznacznie wskazuje na float, zapis 3L - na long.
2)
Kod: Zaznacz cały
unsigned long wynik = TH0<<8 + TL0
Użyj "union"...
A może jakaś rada co z zapisaniem tej liczby Unsigned long w pamięci EEPROM na 8bitach, jak z tym sobie poradzić.
...
Można j/w.2) Mam zmienną "unsigned long wynik" .W 8051 jest licznik 16 bitowy zapisujący TH0 (starszą) i TL0 (młodszą) część liczby, jak dodać do zmiennej wynik zawartość licznika.
Piotrek
PS
Jakiego używasz kompilatora
Czy to jest dobrze:
unsigneg int wynik;
wynik=(unsigned int)(TH0 << 8 )+TL0;
czy może za pomocą drugiej zmiennej pomocniczej:
unsigneg int wynik, pomoc;
pomoc=TH0<<8;
wynik=pomoc+TL0;
Chodzi mi o to czy zapis TH0<<8 nie spowoduje utraty bitów bo przesunięcie o 8 pozycji spowoduje utrate tych bitów bo TH0 jest 8-bitowe.
I czy powinno być + (dodawanie) czy | (OR) operacja sumowanie bitowe OR.
unsigneg int wynik;
wynik=(unsigned int)(TH0 << 8 )+TL0;
czy może za pomocą drugiej zmiennej pomocniczej:
unsigneg int wynik, pomoc;
pomoc=TH0<<8;
wynik=pomoc+TL0;
Chodzi mi o to czy zapis TH0<<8 nie spowoduje utraty bitów bo przesunięcie o 8 pozycji spowoduje utrate tych bitów bo TH0 jest 8-bitowe.
I czy powinno być + (dodawanie) czy | (OR) operacja sumowanie bitowe OR.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Sławek, anie mozesz po prostu sprawdzic?
Moim zdaniem nie spowoduje "utraty bitow", ale to w ogolnosci zalezy od kompilatora. Typowo kompilator stwierdzi ze skoro przypisujemy wynik operacji zmiennej unsigned int to sam (niejawnie) zalatwi sprawe.
To:
jest bez sensu, bo jesli utrata mialaby wystapic to i tak wystapi . Lepiej juz tak:
ale to straszna "krowa".
ze zmienna pomocnicza tez bardzo niezgrabnie! Zreszta zauwaz, ze jesli "utrata bitow" mialaby nastapic to w tym:
i tak nastapi.
Moim zdaniem nie spowoduje "utraty bitow", ale to w ogolnosci zalezy od kompilatora. Typowo kompilator stwierdzi ze skoro przypisujemy wynik operacji zmiennej unsigned int to sam (niejawnie) zalatwi sprawe.
To:
Kod: Zaznacz cały
wynik=(unsigned int)(TH0 << 8 )+TL0;
Kod: Zaznacz cały
wynik=((unsigned int)TH0) << 8 +TL0;
ze zmienna pomocnicza tez bardzo niezgrabnie! Zreszta zauwaz, ze jesli "utrata bitow" mialaby nastapic to w tym:
Kod: Zaznacz cały
pomoc=TH0<<8;
Różnica jest i to zasadnicza.Jeśli wykonujesz operację przypisania do zmiennej powyższego wyrażenia , to "+" czy "|" - jest bez znaczenia , ale gdyby to miała być operacja arytmetyczna na zmiennej i argumencie , to bezwzględnie "+".Poza tym (jak napomknąłem wcześniej) , dlaczego nie chcesz użyć unii Operację logiczne na zmiennych loong czy int , generują "krowiasty" kod , jak już wyżej wspomniał kol. a_antoniakPrzepraszam ze Was tak nękam tymi pytaniami ale czy jest jakaś różnica między:
((int)TH0<<8)|TL0;
((int)TH0<<8)+TL0;
chodzi o + czy | (OR bitowe)
Kod: Zaznacz cały
...
union xx{
unsigned char tim[2];
unsigned int t0;}licznik;
union yy{
unsigned char bl[4];
unsigned long total;}suma;
...
licznik.tim[0]=TL0;
licznik.tim[1]=TH0;
suma.total+=licznik.t0;
...
for(x=0;x<4;x++) {
zapisz_do_eepromu(suma.bl[x]); }
Piotrek
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Przejrzyj załącznik:
- Załączniki
-
- MAINPRG.ZIP
- (7.91KiB)Pobrany 157 razy
Ostatnio zmieniony 19 sty 2006, o 13:23 przez Sławek5, łącznie zmieniany 1 raz.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Kod: Zaznacz cały
((byte*)&wspolczynnik_wtrysku)[0]=EDATA1;
((byte*)&wspolczynnik_wtrysku)[1]=EDATA2;
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To caly program (ten w zalaczniku)? nie widze tak deklaracji i definicji zmiennych np. wspolczynnik_wtrysku. (chyba ze czegos nie zrozumialem)
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
ano chodzi o to, ze autor zadeklarowal i zdefiniowal sobie np. dlugosc_trasy jako unsigned long (domyslnie 4 bajty, choc nie musi tak byc!) a potem dobiera sie do poszczegolnych bajtow rzutujac wskaznik (~adres) do dlugosc_trasy na wskaznik do typu byte i potem biorac elementy nr. 0,1,2,3.
pomysl dosyc oryginalny . jednak (tak jak "mój" z przesunieciami) przy bardziej skomplikowanych wyrazeniach da skomplikowane zapisy. wtedy lepiej uzyc unii, ktorej uzywanie w prostych przypadkach jest IMHO niepotrzebne - zawsze to dodatkowa deklaracja typu (tu niektorzy zechca mnie zlinczowac ).
pomysl dosyc oryginalny . jednak (tak jak "mój" z przesunieciami) przy bardziej skomplikowanych wyrazeniach da skomplikowane zapisy. wtedy lepiej uzyc unii, ktorej uzywanie w prostych przypadkach jest IMHO niepotrzebne - zawsze to dodatkowa deklaracja typu (tu niektorzy zechca mnie zlinczowac ).
Macie jednak rację z tymi uniami, swietna sprawa.
Nie moge tylko się doszukać jak są posczeególne zmienne lokowane w pamięci.
Powiedzmy że jest unia:
union xx{
unsigned char tim[2];
unsigned int t0;}licznik;
Rozpatrując lokaliację poszczególnych bajtów w pamięci liczę od 1
to dla "int t0" LSB będzie w nr 1 a MSB w numerze 2
Podejrzewam że dla tim[0] tez będzie w numerze 1 a tim[1] w nr 2.
A czy mogę napisać tak
union xx{
unsigned char tim0;
unsigned char tim1;
unsigned int t0;}licznik;
Widziałem taki (da mie niezbyt zrozumaiły zapis)
union xx{
struct ww {
unsigned char aa;
unsigned char cc;
}tim;
unsigned int t0;}licznik;
Możecie mi troszkę to objaśnić a najlepiej jakoś obrazowo z umieszczeniem w pamięci
i czy kolejność zapisu w uni ma znaczenie?
I szukałem po necie ale opisu takiego szczegółowego nie znalazłem.
Pośięcie mi troszkę czasu na opis tego.
Powiedzćie mi przy okazji czy jest równica w działaniu takiej pętli
for(i=0;i<10;i++){} a taką for(i=0;i<10;++i){} chodzi mi o i++; i ++i; w pętli
Nie moge tylko się doszukać jak są posczeególne zmienne lokowane w pamięci.
Powiedzmy że jest unia:
union xx{
unsigned char tim[2];
unsigned int t0;}licznik;
Rozpatrując lokaliację poszczególnych bajtów w pamięci liczę od 1
to dla "int t0" LSB będzie w nr 1 a MSB w numerze 2
Podejrzewam że dla tim[0] tez będzie w numerze 1 a tim[1] w nr 2.
A czy mogę napisać tak
union xx{
unsigned char tim0;
unsigned char tim1;
unsigned int t0;}licznik;
Widziałem taki (da mie niezbyt zrozumaiły zapis)
union xx{
struct ww {
unsigned char aa;
unsigned char cc;
}tim;
unsigned int t0;}licznik;
Możecie mi troszkę to objaśnić a najlepiej jakoś obrazowo z umieszczeniem w pamięci
i czy kolejność zapisu w uni ma znaczenie?
I szukałem po necie ale opisu takiego szczegółowego nie znalazłem.
Pośięcie mi troszkę czasu na opis tego.
Powiedzćie mi przy okazji czy jest równica w działaniu takiej pętli
for(i=0;i<10;i++){} a taką for(i=0;i<10;++i){} chodzi mi o i++; i ++i; w pętli
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Po pierwsze: tablice indeksuje się od 0 a nie od 1.Macie jednak rację z tymi uniami, swietna sprawa.
Nie moge tylko się doszukać jak są posczeególne zmienne lokowane w pamięci.
Powiedzmy że jest unia:
union xx{
unsigned char tim[2];
unsigned int t0;}licznik;
Rozpatrując lokaliację poszczególnych bajtów w pamięci liczę od 1
to dla "int t0" LSB będzie w nr 1 a MSB w numerze 2
Podejrzewam że dla tim[0] tez będzie w numerze 1 a tim[1] w nr 2.
Rozmieszczenie zalezy od tego, czy dany rdzen wykorzystuje konwencje little-endian czy big-endian. Zgodnie z tym:
http://www.avrfreaks.net/index.php?modu ... showinfo=1
AVR-y wykorzystuja konwencje little-endian, co oznacza ze mniej znaczace bajty wielobajtowego typu danych (np. unsigned int) zapisywane sa pod mniejszymi adresami. Przyklad zapisu podal szymel.
nie. unia sluzy do przechowywania jednej danej sposrod danych w niej zadeklarowanych. tim0 i tim1 zostana zapisane w tym samym miejscu pamieci, a nie o to chodzi.A czy mogę napisać tak
union xx{
unsigned char tim0;
unsigned char tim1;
unsigned int t0;}licznik;
tu jest lepiej, bo elementem unii jest struktura. prawdopodobnie to zadziala, ale nie mam pewnosci jak dane rozmieszczane sa w pamieci w przypadku struktury (a w przypadku tablicy taka pewnosc mam).Widziałem taki (da mie niezbyt zrozumaiły zapis)
union xx{
struct ww {
unsigned char aa;
unsigned char cc;
}tim;
unsigned int t0;}licznik;
w tym przypadku zadnej roznicy nie maPowiedzćie mi przy okazji czy jest równica w działaniu takiej pętli
for(i=0;i<10;i++){} a taką for(i=0;i<10;++i){} chodzi mi o i++; i ++i; w pętli
ujmuj kod w tagi [ code ] [ /code ] !!!!!
Ku wyjaśnienia to liczenie napisałem: "Rozpatrując lokaliację poszczególnych bajtów w pamięci liczę od 1 "
Więc nie wiem dlaczego napisałeś: "Po pierwsze: tablice indeksuje się od 0 a nie od 1"
czyli jako 1 miałem na myśli komórkę pamięci a nie tablicę.
A co do odpowiedzi to jeżeli napiszę
to odwołanie sie liczba.a będzie tą samą komórką pamięci (ten sam adres lokalizyjący) co liczba.b, czy tak? Więc dlatego należy napisać
Czy dobrze zrozumiałem.
A nie wystarczyło grzecznie zwrócić mi uwagi tylko tak KRZYCZEĆ na mie, co???
Ale dzięki i nie mam za złe, cieszę się że mogę się czegoś dzięki Wam nauczyć.
Więc nie wiem dlaczego napisałeś: "Po pierwsze: tablice indeksuje się od 0 a nie od 1"
czyli jako 1 miałem na myśli komórkę pamięci a nie tablicę.
A co do odpowiedzi to jeżeli napiszę
Kod: Zaznacz cały
union xx{
char a;
char b;
int c;
} liczba;
Kod: Zaznacz cały
union xx{
char a[2];
int c;
}liczba;
A nie wystarczyło grzecznie zwrócić mi uwagi tylko tak KRZYCZEĆ na mie, co???
Ale dzięki i nie mam za złe, cieszę się że mogę się czegoś dzięki Wam nauczyć.
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 92 gości