Odpowiedz 
 
Ocena wątku:
  • 3 Głosów - 3.33 Średnio
  • 1
  • 2
  • 3
  • 4
  • 5
Programowanie w języku C w środowisku AVR Studio4
SP4EJT Offline
Marcin
****

Liczba postów: 340
Dołączył: 06-05-2011
Post: #121
RE: Programowanie w języku C w środowisku AVR Studio4
Przepraszam, mój bład.
Kompilator pewnie naprawił mój błąd zamieniając typ zmiennej na "unsigned long long int", podobnie jak z wcześniejszym moim błędem w deklaracji tablicy - musiał ja powiększyć o 1 element.
Zatem żeby naprawić mój błąd deklaracja zmiennej FTW powinna być taka:
Kod:
unsigned long long int FTW;
Potem wgram poprawione pliki, bo zaraz będę miał domowe zajęcie.

Czy wystarczy zmienną, FTW zadeklarować jako 64bitową czy zmienne od których jest zależne FTW też trzeba deklarować jako 64bitowe żeby było poprawnie ?
(Ten post był ostatnio modyfikowany: 26-02-2012 12:28 przez SP4EJT.)
26-02-2012 12:27
Odwiedź stronę użytkownika Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
JaHo Offline
Nowicjusz
*

Liczba postów: 35
Dołączył: 24-06-2011
Post: #122
RE: Programowanie w języku C w środowisku AVR Studio4
Moim prywatnym zdaniem ... jeśli to niczemu nie przeszkadza ... wszystkie zmienne bym zrobił "unsigned long long", i wszystkie stałe też (przyrostek "ULL") ...

unsigned long long int FTW, fs, frequency;
fs=400000000ULL; // "ULL" -> "unsigned long long"
// ...
// poniżej ... przyrostek "ULL" w stałej wymusi przeprowadzenie
// obliczeń w precyzji "unsigned long long", nawet jeśli "frequency"
// i/lub "fs" będą tylko "unsigned long"
FTW = 4294967296ULL * frequency / fs;

Poza tym, żeby być pewnym kolejności wykonywania działań ... dodałbym nawiasy ...
albo ...
FTW = (4294967296ULL * frequency) / fs;
albo ...
FTW = 4294967296ULL * (frequency / fs);
zależnie od tego jak bym chciał żeby się to liczyło.

A propos, kompilator nie ma żadnego prawa zmienić typu ani rozmiaru zmiennej ... może co najwyżej wyemitować ostrzeżenie (warning) jeśli uzna że coś może być nie tak (ale być może jest o.k. bo tego właśnie chciał użytkownik), a w przypadku bardziej krytycznych problemów zgłosić błąd (error) i przerwać działanie ... zawsze to użytkownik musi sam poprawić swój kod źródłowy.

Na koniec jeszcze jedna uwaga ... upewnij się że twój kompilator naprawdę traktuje typ "long long" jako 8B (a "long" jako 4B). Co więcej, jego zachowanie może zależeć od konkretnych flag (opcji kompilatora) podanych w trakcie kompilacji kodu źródłowego.
Standard mówi jedynie że (zwróć uwagę na znak "mniejsze-równe"):
sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

Naprościej byłoby po prostu napisać kawałek testujący:

printf("%d %d %d %d\n", sizeof(short), sizeof(int), sizeof(long), sizeof(long long));
printf("%d %d %d %d\n", sizeof(unsigned short), sizeof(unsigned int), sizeof(unsigned long), sizeof(unsigned long long));

Generalnie jednak, użyłbym typów "Uint64_t" albo "u64" - to gwarantuje "unsigned 8-Bytes" (i "Uint32_t" albo "u32" dla zmiennych "unsigned 4-Bytes" oraz "Uint8_t" albo "u08" dla zmiennych "unsigned 1-Byte").
https://ccrma.stanford.edu/courses/250a/...yntax.html
https://ccrma.stanford.edu/wiki/AVR_Programming
(Ten post był ostatnio modyfikowany: 26-02-2012 14:33 przez JaHo.)
26-02-2012 13:58
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
TG50 Offline
Józef
***

Liczba postów: 178
Dołączył: 20-11-2009
Post: #123
RE: Programowanie w języku C w środowisku AVR Studio4
(26-02-2012 12:27)SP4EJT napisał(a):  Czy wystarczy zmienną, FTW zadeklarować jako 64bitową ... ?

Według opisu układu AD9951 nastawa dla DDSa powinna być na 4 bajtach, tak zresztą jest napisany fragment do ustawiania syntezy. Zatem FTW powinno pozostać jako zmienna 32 bitowa bez znaku.
26-02-2012 14:51
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
JaHo Offline
Nowicjusz
*

Liczba postów: 35
Dołączył: 24-06-2011
Post: #124
RE: Programowanie w języku C w środowisku AVR Studio4
Pomyślałem sobie że ... jeśli masz zmienne "unsigned 4-Bytes" i rezultat ma być "unsigned 4-Bytes" ale obliczenia potrzebujesz wykonać w precyzji "unsigned 8-Bytes" ... to można po prostu użyć jawnej konwersji typów (explicit type conversion) bezpośrednio w samym równaniu ...

Kod:
Uint32_t FTW, fs, frequency;
fs = 400000000UL;
// ...
FTW = ((Uint32_t)( 4294967296ULL * ((Uint64_t)frequency) / ((Uint64_t)fs) ));

A żeby być jeszcze bardziej pewnym ... można zastąpić 4294967296ULL poprzez (((Uint64_t)1) << 32) albo (((Uint64_t)65536UL) * ((Uint64_t)65536UL))
(Ten post był ostatnio modyfikowany: 26-02-2012 16:33 przez JaHo.)
26-02-2012 16:32
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP3SWJ Offline
Jarek
****

Liczba postów: 653
Dołączył: 20-03-2010
Post: #125
RE: Programowanie w języku C w środowisku AVR Studio4
(26-02-2012 14:51)TG50 napisał(a):  
(26-02-2012 12:27)SP4EJT napisał(a):  Czy wystarczy zmienną, FTW zadeklarować jako 64bitową ... ?

Według opisu układu AD9951 nastawa dla DDSa powinna być na 4 bajtach, tak zresztą jest napisany fragment do ustawiania syntezy. Zatem FTW powinno pozostać jako zmienna 32 bitowa bez znaku.

FTW jako ciąg bitów wysyłanych do DDS - wynik obliczeń musi być 32 bitowy...

można sobie po drodze liczyć na "dłuższych" liczbach ale na koniec trzeba :

- albo liczbę "obciąć" do 32 bitów
- albo świadomie wysłać 32 młodsze bity

===

RESET jest konieczny dla tego modelu DDS - by wszystko pracowało stabilnie i powtarzalnie.... ... byłem ciekawy jaką metodę zastosujesz do sterowania tego DDS bez "resetowania" go...

jeśli sie nie używa zaawansowanego "debugera" to dobrze jest wszystkie pośrednie wyniki wyrzucać na port RS232 jako liczby i weryfikować to z naszymi obliczeniami w excelu ... potem te "printy" zaremować.
26-02-2012 20:45
Odwiedź stronę użytkownika Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP4EJT Offline
Marcin
****

Liczba postów: 340
Dołączył: 06-05-2011
Post: #126
RE: Programowanie w języku C w środowisku AVR Studio4
Dziękuję chłopaki że mnie prostujecie - dzięki Wam zdaję sobie sprawę jak mało umiem Tongue postaram się nie popełniać tych samych błędów więcej.
(26-02-2012 20:45)SP3SWJ napisał(a):  RESET jest konieczny dla tego modelu DDS - by wszystko pracowało stabilnie i powtarzalnie.... ... byłem ciekawy jaką metodę zastosujesz do sterowania tego DDS bez "resetowania" go...
no tak, pomyślałem sobie że po co reset skoro dopiero co włączone zostało zasilanie Smile na szczęście w porę doszedłem do tego poprzez sprawdzenie w prawdziwym układzie czy to zadziała i się poprawiłem.
SP3SWJ napisał(a):jeśli sie nie używa zaawansowanego "debugera" to dobrze jest wszystkie pośrednie wyniki wyrzucać na port RS232 jako liczby i weryfikować to z naszymi obliczeniami w excelu ... potem te "printy" zaremować.
kurde , Jarek ... dzięki ! Super pomysł ! To rzeczywiście będzie bardzo pomocne. [Wazelina mode: on] Jak to dobrze mądrego posłuchać [Wazelina mode: off] Wink
Pobawię się z podglądem zmiennych w ten sposób i potem Wam opowiem co i jak było, myślę że za kilka dni się wyrobię.

Co do tego że kompilator powinien czerwone kropy wywalać to się zgadzam - ale on nie wywala, kompiluje i program działa ! ... dziwne zachowanie z jego strony Confused
Sami możecie sprawdzić - plik całęgo projektu jest w którymś z ostatnich moich postów - nie usprawiedliwiam się tylk o nie pamiętam żeby jakieś Warningi były w raporcie kompilacji.
(Ten post był ostatnio modyfikowany: 26-02-2012 23:34 przez SP4EJT.)
26-02-2012 23:34
Odwiedź stronę użytkownika Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP5FCS Offline
Adam
*****

Liczba postów: 1,072
Dołączył: 02-02-2009
Post: #127
RE: Programowanie w języku C w środowisku AVR Studio4
(26-02-2012 23:34)SP4EJT napisał(a):  Co do tego że kompilator powinien czerwone kropy wywalać to się zgadzam - ale on nie wywala, kompiluje i program działa ! ... dziwne zachowanie z jego strony Confused

No to mamy triumf praktyki nad teorią: "program działa tylko nie wiemy dlaczego" Blush

Kod:
unsigned long int FTW, fs;   // deklaracja zmiennej FTW i zmiennej fs
fs=400000000;         // fs to częstotliwość taktowania DDSa
...
...
FTW=4294967296*frequency/fs;

Dlaczego powyższy kod działa poprawnie ?

* liczba 4294967296 to nic innego jak 2 do potęgi 32. Słusznie zauważono wcześniej, że nie mieści się ona na 4 bajtach. Na szczęście nie został jawnie określony format tej liczby jako (UL). Kompilator widząc w kodzie źródłowym liczbę większą od long int (32bity) nadał jej format long long int (64bity) co uratowało ten kod od wysypania !
* mimo, że zmienne frequency i fs są 32 bitowe to wynik wyrażenia po prawej stronie jest 64 bitowy ponieważ przyjmuje on format największego argumentu występującego w wyrażeniu (stała long long int, 64bity) .
* format zmiennej FTW jest zgodny z naszymi potrzebami, czyli 32bity. Podczas przypisania wyniku wyrażenia zmiennej FTW następuje niejawna konwersja formatu wyniku z 64 bitów do 32bitów. Nie tracimy żadnej informacji ponieważ wynik zawsze mieści się na 4 bajtach i jest to tylko zmiana formatu danych.

Bardziej czytelny byłby zapis zawierający jawne rzutowanie wyniku wyrażenia na format zmiennej po lewej stronie oraz jawne określenie formatu stałej:

FTW=(unsigned long int) (4294967296ULL*frequency/fs)

Inne uwagi:
- ze względu na zajętość pamięci oraz czas wykonania należy unikać długich formatów zmiennych;
- szybszą metodą niż mnożenie przez 4294967296 jest przesunięcie zmiennej o 32 bity w lewo !!!
- wysyłanie nastawy FTW do DDS-a lepiej przerobić na wysyłanie pojedynczych bajtów, maskowanie bitu na zmiennej 32 bitowej pochłania bardzo dużo czasu;
- jeszcze efektywniejsze jest wykorzystanie sprzętowego SPI procesora do komunikacji z DDS-em.

73 Adam
29-02-2012 1:07
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP4EJT Offline
Marcin
****

Liczba postów: 340
Dołączył: 06-05-2011
Post: #128
RE: Programowanie w języku C w środowisku AVR Studio4
Zastosuję się na pewno do większości twoich uwag Adamie, ale trochę później.
W ten weekend wyjeżdżam z domu i raczej nic w tym tygodniu nie napisze ciekawego, ale widzę, że i tak temat "umarł". Zainteresowanie chyba spadło do zera, bo piszą sami "krytycy" ( dzięki im za to oczywiście ), żadnej wypowiedzi od tych którzy się wcześniej tym tematem interesowali. Chyba krytyka samego języka C jak i mojego sposobu nauczania zniechęciła ludzi. Może dobrym pomysłem będzie jak przestanę pisać i zacznę dopiero wtedy, gdy będę miał dla kogo...
(Ten post był ostatnio modyfikowany: 02-03-2012 15:49 przez SP4EJT.)
02-03-2012 15:47
Odwiedź stronę użytkownika Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP5IWI Offline
Janek
*

Liczba postów: 32
Dołączył: 01-02-2009
Post: #129
RE: Programowanie w języku C w środowisku AVR Studio4
(02-03-2012 15:47)SP4EJT napisał(a):  Zastosuję się na pewno do większości twoich uwag Adamie, ale trochę później.
W ten weekend wyjeżdżam z domu i raczej nic w tym tygodniu nie napisze ciekawego, ale widzę, że i tak temat "umarł". Zainteresowanie chyba spadło do zera, bo piszą sami "krytycy" ( dzięki im za to oczywiście ), żadnej wypowiedzi od tych którzy się wcześniej tym tematem interesowali. Chyba krytyka samego języka C jak i mojego sposobu nauczania zniechęciła ludzi. Może dobrym pomysłem będzie jak przestanę pisać i zacznę dopiero wtedy, gdy będę miał dla kogo...


Programuję Twoim "gotowcem" jak i skompilowanym przezemnie kompilacja OK programowanie OK a na wyświetlaczu nic.Cwiczyłem kilkanaście razy i to samo.Nic to walczę dalej
Janek sp5iwi
02-03-2012 23:44
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP5FCS Offline
Adam
*****

Liczba postów: 1,072
Dołączył: 02-02-2009
Post: #130
RE: Programowanie w języku C w środowisku AVR Studio4
Początki nauki zawsze są proste i przyjemne, potem jest coraz trudniej i trudniej dlatego często brakuje zapału i determinacji do pełnego opanowania języka. Możliwości języka C są naprawdę bardzo duże, składnia bardzo wyszukana, trzeba zwracać uwagę na najdrobniejsze szczegóły. Oprócz poznawania elementów samego języka warto również od początku uczyć się zasad dobrego stylu programowania. Potem pozostaje już tylko zdobywanie doświadczenia przy kolejnych projektach ale na to trzeba wielu miesięcy a nawet i lat.
Nie ma lekko WinkWink.

Pliki źródłowe i nagłówkowe
Plik źródłowy zawiera kod programu tworzony przez programistę wg. składni języka. Taki plik stanowi źródło dla kompilatora, który zamienia go na kod maszynowy zrozumiały dla procesora. Dla poprawienia czytelności programu oraz ułatwienia jego edycji zaleca się dzielenie całego programu na mniejsze, tematyczne moduły zapisywane w oddzielnych plikach źródłowych (np. LCD, SPI, ADC, Setup, itd.). Dodatkowe pliki źródłowe do obsługi określonych funkcji, zasobów procesora mocą być wykorzystywane jako uniwersalne moduły w innych projektach. Aby kompilator widział kod umieszczony w zewnętrznych plikach musimy je podłączyć pod główny kod programu lub podać taką informację w konfiguracji projektu.

Kod:
#include "lcd_alfanum.c"  // obsługa wyświetlacza LCD
#include "AD9951.c"         // obsługa DDS-a przez SPI

Takie rozwiązanie poprawia czytelność kodu, wprowadza pewien porządek ale ma również istotne wady:
- kompilowany musi być cały kod programu łącznie z dodatkowymi plikami co pochłania sporo czasu przy rozbudowanych projektach;
- musimy posiadać wszystkie pliki źródłowe wchodzące w skład projektu;
- nie możemy ukryć części zmiennych oraz funkcji definiowanych w dodatkowych plikach źródłowych;

Aby pozbyć się powyższych wad na potrzeby języka C wymyślono pliki nagłówkowe. Przykładowy projekt biblioteki do obsługi wyświetlacza musi posiadać dwa pliki: plik źródłowy lcd.c oraz plik nagłówkowy lcd.h. Plik lcd.c zawiera definicje zmiennych globalnych dla LCD oraz zestaw funkcji do obsługi wyświetlacza LCD. Plik nagłówkowy lcd.h zawiera tylko definicję pinów oraz deklarację zmiennych i deklarację funkcji, które będą widoczne w programie głównym po jego wczytaniu. Taka konstrukcja pliku nagłówkowego pozwala na szybką modyfikację i zmianę konfiguracji pinów bez potrzeby edycji pliku źródłowego. Nie wszystkie zmienne i funkcje zdefiniowane w pliku lcd.c muszą być udostępnione w pliku nagłówkowym co skutkuje tym, że nie będą one widoczne w innych modułach projektu.

Taka koncepcja plików bibliotecznych pozwala na:
- rozdzielenie deklaracji i definicji zmiennych oraz funkcji;
- niezależne kompilowanie poszczególnych modułów projektu;
- oszczędność czasu kompilacji całego projektu, pliki biblioteczne są dołączane na etapie linkowania;
- pracę zespołową wielu programistów nad jednym projektem bez udostępniania źródeł, wystarczą pliki nagłówkowe oraz pliki po kompilacji;
- ukrywanie zmiennych oraz funkcji widocznych tylko w jednym module projektu.

73 Adam
03-03-2012 0:13
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
Odpowiedz 


Skocz do:


Użytkownicy przeglądający ten wątek: