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.

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:
Zapis unsigned long w pamięci 2402.

Postautor: Sławek5 » 15 sty 2006, o 11:16

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.

a_antoniak
-
-
Posty:651
Rejestracja:13 sty 2005, o 18:38
Lokalizacja:Krasnystaw
Kontaktowanie:

Re: Zapis unsigned long w pamięci 2402.

Postautor: a_antoniak » 15 sty 2006, o 14:26

Maksymalna wartość dla danej typu unsigned long jest za mała i chciałbym ją powiększyć do np 40 bitów.
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.

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

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 15 sty 2006, o 16:11

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_antoniak
-
-
Posty:651
Rejestracja:13 sty 2005, o 18:38
Lokalizacja:Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 15 sty 2006, o 19:28

ARM - maly straszek? :D

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

Kod: Zaznacz cały

unsigned long wynik = TH0<<8 + TL0
. to powinno zostac zinterpretowane prawidlowo, ale mozna zapisac bardziej "lopatologicznie" (z rzutowaniem).

szymel
-
-
Posty:212
Rejestracja:16 sty 2005, o 16:42
Lokalizacja:Włocławek

Postautor: szymel » 15 sty 2006, o 19:38

...
A może jakaś rada co z zapisaniem tej liczby Unsigned long w pamięci EEPROM na 8bitach, jak z tym sobie poradzić.
...
Użyj "union" :D
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.
Można j/w.

Piotrek

PS
Jakiego używasz kompilatora :?:

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 15 sty 2006, o 20:43

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.

a_antoniak
-
-
Posty:651
Rejestracja:13 sty 2005, o 18:38
Lokalizacja:Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 15 sty 2006, o 20:53

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:

Kod: Zaznacz cały

wynik=(unsigned int)(TH0 << 8 )+TL0;
jest bez sensu, bo jesli utrata mialaby wystapic to i tak wystapi :). Lepiej juz tak:

Kod: Zaznacz cały

wynik=((unsigned int)TH0) << 8 +TL0;
ale to straszna "krowa".

ze zmienna pomocnicza tez bardzo niezgrabnie! Zreszta zauwaz, ze jesli "utrata bitow" mialaby nastapic to w tym:

Kod: Zaznacz cały

pomoc=TH0<<8;
i tak nastapi.

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 16 sty 2006, o 14:29

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

szymel
-
-
Posty:212
Rejestracja:16 sty 2005, o 16:42
Lokalizacja:Włocławek

Postautor: szymel » 16 sty 2006, o 15:14

Przepraszam 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)
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_antoniak

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]); }
Tak zrobiłbym ja , a Ty zrobisz jak zechcesz :D

Piotrek

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 16 sty 2006, o 20:17

Dzięki ze nie skrytykowaliście mnie za te bużki bo one wyszły jakoś przypadkiem a niechcący, oczywiście miała być tam cyfra 8.
Na podglądzie było ok , ale po wysłaniu już nie sprawdziłem i sie popsuło.

Dzięki też za odpowiedź.

radzio
Moderator
Moderator
Posty:967
Rejestracja:13 maja 2003, o 10:33
Lokalizacja:Sosnowiec
Kontaktowanie:

Postautor: radzio » 16 sty 2006, o 21:14

Ujmuj kod w tagi [code][/code] to nie będą sie pojawiały żadne buźki :)

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 18 sty 2006, o 19:26

Co do unii to masz rację ae muszę to na spokojnie "przetrawić" .

Spotkałem jeszcze taki zapis

unsigned int dana;

(byte*)&dana[0]=TL0;
(byte*)&dana[1]=TH0;

Jak ja mam to zrozumieć;

a_antoniak
-
-
Posty:651
Rejestracja:13 sty 2005, o 18:38
Lokalizacja:Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 18 sty 2006, o 20:24

Spotkałem jeszcze taki zapis
gdzie?

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 19 sty 2006, o 06:34

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.

a_antoniak
-
-
Posty:651
Rejestracja:13 sty 2005, o 18:38
Lokalizacja:Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 19 sty 2006, o 10:49

Kod: Zaznacz cały

((byte*)&wspolczynnik_wtrysku)[0]=EDATA1; ((byte*)&wspolczynnik_wtrysku)[1]=EDATA2;
to nie jest to samo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

To caly program (ten w zalaczniku)? nie widze tak deklaracji i definicji zmiennych np. wspolczynnik_wtrysku. (chyba ze czegos nie zrozumialem)

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 19 sty 2006, o 13:24

Moja wina przyznaje się. Pomyłka - nie dopisałem nawiasów. Przepraszam.
Załącznik zmieniłem i powinno być OK

a_antoniak
-
-
Posty:651
Rejestracja:13 sty 2005, o 18:38
Lokalizacja:Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 19 sty 2006, o 13:58

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

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 20 sty 2006, o 07:19

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

a_antoniak
-
-
Posty:651
Rejestracja:13 sty 2005, o 18:38
Lokalizacja:Krasnystaw
Kontaktowanie:

Postautor: a_antoniak » 20 sty 2006, o 14:35

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.
Po pierwsze: tablice indeksuje się od 0 a nie od 1.
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.
A czy mogę napisać tak
union xx{
unsigned char tim0;
unsigned char tim1;
unsigned int t0;}licznik;
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.
Widziałem taki (da mie niezbyt zrozumaiły zapis)

union xx{
struct ww {
unsigned char aa;
unsigned char cc;
}tim;
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).
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
w tym przypadku zadnej roznicy nie ma


ujmuj kod w tagi [ code ] [ /code ] !!!!!

Sławek5
-
-
Posty:485
Rejestracja:15 sie 2003, o 16:40
Lokalizacja:Szczecin
Kontaktowanie:

Postautor: Sławek5 » 20 sty 2006, o 14:47

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ę

Kod: Zaznacz cały

union xx{ char a; char b; int c; } liczba;
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ć

Kod: Zaznacz cały

union xx{ char a[2]; int c; }liczba;
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ć.

Wróć do „Projektowanie PCB, programy EDA, CAD, narzędziowe”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 87 gości