Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 29 mar 2024, o 12:33


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 
Autor Wiadomość
PostNapisane: 25 lis 2018, o 19:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Witam wszystkich forumowiczów.

Robię sobie samemu wzmacniacz audio DIY w skład którego postanowiłem wmontować procesor audio oparty na powszechnie stosowanym wa radiach samochodowych układzie TDA7418 który posiada przełącznik wejść, regulację tonów wysokich, średnich, basów, loudness i 4 wyjścia plus wyjście dla subwoofer-a.

Podglądając biblioteki arduino i inne w internecie napisałem swoja biblioteke do obsługi tego scalaka.
Samo wysyłanie i zmiana parametrów nie jest jakoś szczególnie skomplikowana ale pisząc sam program obsługi utknąłem na jednej rzeczy.

Stanąłem na regulacji balansu oraz fadera czyli regulacji każdego z czterech kanałów wyjściowych.
O ile nie jest problemem zmienić głośność w którymkolwiek kanale osobno,
to już sterowanie i uzależnienie wszystkich kanałów od ustawienia balansu i fadera już nie jest takie proste.

Chciałby zobaczyć jakie wy macie sugestie na temat takiej regulacji.
Nie chodzi mi o jakiś konkretny kod a jedynie o sposób realizacji czegoś takiego.

Być może ktoś z was już się z tym spotkał i ma jakieś doświadczenia.

Sama regulacja ma polegać na zmianie wartości odpowiednio czterech zmiennych przypisanych dla każdego z kanałów za pomocą dwóch zmiennych balans i fader o zakresie int przyjmujących wartości od -x przez 0 do x.

Czyli każdy kanał może być przyciszony o wartość jego zmiennej 0 do np. 50 gdzie 0 to maksymalna głośność a 50 to wyciszenie.
O ile nie ma najmniejszego problemu aby regulować na podstawie balansu czy faderu odpowiednie dwa kanały,
to już uzależnienie jednej regulacji od drugiej już nie jest dla mnie takie proste.
Czyli jeśli w faderze ustawimy pewne poziomy to w w balansie można tylko przyciszyć a nie można zgłośnić.

Czekam na wasze sugestie i pozdrawiam Paweł.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 gru 2018, o 22:24 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Witam ponownie

Udało mi się napisać przeliczanie dzięki pomocy mojego kolegi który na co dzień programuje.
Samo przeliczanie okazało się bardzo proste, zupełnie jak przypuszczałem.
Jak skończę pisać program nie omieszkam się podzielić tu na naszym forum.

Mam jeszcze jeden problem, ponieważ się uczę a do tej pory nie za bardzo używałem wskaźników.
Jedynie kopiowałem jakieś fragmenty kodów z Mirkowych programów i poradników i wszystko działało.
Choś nie zabardzo wiedziałem w jaki sposób.

Pisząc swój program praktycznie zawsze ma się inny pomysł na to jak go napisać i okazuje się, że to co pokazał Mirek w poradniku owszem działa ale ja bym chciał zrobić to w troszkę innaczej i tu tworzą się schody.
Na początku chyba każdy kto uczy się programować nie widzi potrzeby używania wskaźników.
Ja generalnie zrozumiałem zasadę ich działania jednak do pełnych możliwości ich używania w swoich programach jeszcze mi dużo brakuje.

Do czego zmierzam:
Mamy dwie zmienne a i b ale innych typów!
int zmienna_b

Drugą

uint8_t zmienna_a

i teraz chciałbym napisać swoją uniwersalną procedurę do wykonywania obliczeń na tych zmiennych.
Jednak sama procedura ma być bardzo uniwersalna i chciałbym aby robiła operacje w obie strony.
Czyli mogła odczytywać i przypisywać wartości jednocześnie do obu zmiennych.

Żaden problem prawda?!
Normalnie każda procedura może zwrócić tylko jeden argument a ja bym chciał aby zwracała 2 i tu właśnie przydadzą się wskaźniki.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Później w samym programie piszę;
moje_obliczenia( (uint8_t *)&zmienna_a, (int *)&zmienna_b, 0);

I taki kod działa prawidłowo kompiluje się bez problemu

Jednak ja raz bym chciał podstawiać zmienną a typu uint8_t jako Var_in a następnym razem jako Var_out

Czyli tak a wtedy kompilator od razu krzyczy.
Można chyba zadeklarować tą procedurę ze wskaźnikami void


Czyli tak:


Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


ale kiedy w programie próbuję użyć tak zadeklarowanej procedury to kompilator i tak się burzy.

Czy nie można jakby zadeklarować samej procedury z nieznanym typem wskaźnika czyli void a dopiero podczas jej użycia rzutować jego typu?????

Kurczę nie wiem czy ktokolwiek zrozumie moje pytanie.
No chyba, że całkowicie nie rozumiem jak działa void?

Pozdrawiam Paweł.

------------------------ [ Dodano po: 13 minutach ]

Czy przypadkiem prawidłowo mozna zadeklarować

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



hmm????



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 2 gru 2018, o 23:18 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27212
Lokalizacja: Szczecin
Pomógł: 1041

P3ndz3l3k napisał(a):
ale kiedy w programie próbuję użyć tak zadeklarowanej procedury to kompilator i tak się burzy.

ale jak tak piszesz, to dokończ zawsze i napisz co to znaczy, że się burzy - czyli pokaż komunikat bo trudno się domyśleć .... a przecież tak może wyglądać nagłówek funkcji - w czym problem?

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 gru 2018, o 18:33 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Dopiero z pracy wróciłem.

No więc doszedłem do tego, że prawidłowo powinno chyba być być tak:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Ale nie wiem teraz jak prawidłowo użyć tych wskaźników wewnątrz procedury:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Już mi się zwoje mózgowe całkowicie poplątały.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 gru 2018, o 20:18 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

P3ndz3l3k napisał(a):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Postaram się wytłumaczyć jak najprościej. Wskaźnik void to wskaźnik do zmiennej o nieokreślonym typie, więc również o nieokreślonym rozmiarze (w bajtach). Kiedy przypisujesz zmiennej wartość 10 - *input = 10; - skąd kompilator ma wiedzieć do jakiego typu zmiennej wpisuje/czyta dane, czyli ile bajtów ma wpisać/wczytać?
Dereferencję powinieneś zrobić w ten sposób:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Jeśli chcesz natomiast, aby rzutować wskaźniki raz na jeden typ, a innym razem na drugi typ, musisz dodać argument, dzięki któremu funkcja będzie wiedziała jakiego rzutowania ma dokonać:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


By było czytelniej można użyć unii:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 gru 2018, o 21:16 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Witam kolegę

andrews napisał(a):
Wskaźnik void to wskaźnik do zmiennej o nieokreślonym typie, więc również o nieokreślonym rozmiarze (w bajtach).


No widzisz bardzo mocno mi tym rozjasniłeś byłem święcie przekonany, że to void nie będzie wskaźnikiem na nieokreśloną zmienną ale, że własnie ten mój wskaźnik bedzie nieokreślonego typu i wtedy kiedy np. używając w pętli mojej procedury, będę mógł zrobić własnie rzutowanie dopasowane do mojej zmiennej czyli tak:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


i wtedy kompilator by wiedział jaki typ zmiennej ale to nie działa niestety.

Oczywiście tak jak mi napisałeś sposób z wewnętrznym rzutowaniem działa jednak w tym momencie procedura traci idee uniwersalności.

Drugiego sposobu z podmianą typów jeszcze nie sprawdzałem ale napewno działa jednak dzięki temu można obsłużyć tylko 2 typy i podczas użycia tej procedury trzeba by było zawsze wybierać ten kierunek. Jak by dorzucić switcha to mozna by wszystkie typy uzywać ale wtedy to ta procedura by nieźle się rozrosła.

Czyli generalnie mój pomysł z jakby automatycznym dopasowaniem typów jest nie wykonalny.

Szkoda trochę bo przecież ta zmienna jest gdzieś w programie zdeklarowana więc kompilator powinien sobie znaleźć jej typ.
Mogło by być tak dafaultowo, że jesli nie rzutujemy wskaźnika na inny typ zawsze jest tym samym co zmienna.
Przecież podczas użycia normalnej zmiennej jako parametru nie trzeba podawać typu.

Troche trudno mi opisać dokładnie co bym chciał zrobić.
Zawsze poczatkujący próbują zrobić coś czego nie da się zrobić bo nie widzą innego rozwiazania.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 gru 2018, o 21:42 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 01 lis 2015
Posty: 1448
Lokalizacja: okolice Warszawa
Pomógł: 149

zastanawiam się czy nie dałoby się coś pokombinować z sizeof.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 gru 2018, o 22:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Poczytam jak działa sizeof ale on podaje chyba tylko rozmiar czyli ilość bajtów a nie typ.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 gru 2018, o 09:13 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

P3ndz3l3k napisał(a):
Szkoda trochę bo przecież ta zmienna jest gdzieś w programie zdeklarowana więc kompilator powinien sobie znaleźć jej typ.

A co jeśli np. wywołanie funkcji jest w innym pliku *.c. Pliki *.c śa kompilowane osobno do plików obiektowych, dopiero linker je łączy w jeden plik wykonywalny...
Nie tak łatwo wytłumaczyć, dlaczego tak się nie uda, a ja w tej chwili nie mam czasu, żeby się rozpisywać (może później). W każdym razie funkcja musi znać typ danych wewnątrz definicji, nie w momencie wywołania.
Jeśli chcesz ewentualnie zwiększyć funkcjonalność funkcji możesz użyć switch zamiast if:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Wtedy będziesz mógł przekazać więcej kombinacji różnych typów, ale tak czy inaczej to rozwiązanie dość kłopotliwe. Można też przekazać osobno typ każdego z argumentów.

W przypadku stosunkowo prostych funkcji, można je zastąpić makrami (function-like macro):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Powinno zadziałać z (prawie) dowolnym typem (w tym przypadku kompilator będzie znał typ), ale takie rozwiązanie też ma swoje wady, jak np. to, że każde użycie takiego makra może znacząco zwiększać rozmiar kodu wynikowego. Makro działa trochę podobnie do funkcji inline, wstawiając za każdym razem kod w miejscu wywołania. Normalna funkcja to fragment kodu wielokrotnego użytku, dzięki czemu kod wynikowy jest zwykle mniejszy, szczególnie w przypadku częstego wywoływania takiej funkcji w różnych miejscach programu.

Daro69 napisał(a):
zastanawiam się czy nie dałoby się coś pokombinować z sizeof.

sizeof nic nie da w tym przypadku. Kompilator tutaj musi znać nie tylko rozmiar, ale dokładny typ zmiennych, bo (jeśli dobrze zrozumiałem) ma wykonywać na nich jakieś operacje arytmetyczne. Zmienne typu int32_t, uint32_t i float mają ten sam rozmiar, ale kompilator musi użyć innych algorytmów i instrukcji asm, żeby zrealizować operacje arytmetyczne na poszczególnych typach.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 gru 2018, o 17:53 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Witaj

Widzę, że jesteś już zaawansowanym programistą ja jak już pisałem uczę się i właśnie zaczynam używać wskaźników.
No i właśnie przyszedł mi taki pomysł z tymi różnymi typami bo Mirek zawsze w poradnikach mówi aby myśleć przyszłościowo i nie pisać
dziesięciu prawie jednakowych procedur a napisać jedną jak najbardziej uniwersalną.
Chyba chciałem za bardzo ją uniwersalną zrobić.
Z tąd ten pomysł, w moim programie gdzie potrzebuję użyć tej procedury będę wykorzystywał tylko dwa typy i aby nie kombinować, w wywołaniu tej procedury będę zamieniał poprostu miejscami te zmienne wstawiane jako argumenty.
A samą procedurę zadeklaruję poprostu na konkretne typy i będzie chulało.

Nie pisałem tego wcześniej ale te zmienne mam umieszczone wewnątrz struktury ale z punktu widzenia wskaźników nie ma to znaczenia chyba?

Bardzo ci dziękuję za wyjaśnienia.

Pozdrawiam Paweł.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 gru 2018, o 18:43 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

P3ndz3l3k napisał(a):
Nie pisałem tego wcześniej ale te zmienne mam umieszczone wewnątrz struktury ale z punktu widzenia wskaźników nie ma to znaczenia chyba?

Obydwa argumenty są elementami tej samej struktury? A może chociaż takiej samej struktury? Można przecież przekazywać do funkcji wskaźnik(i) na całą strukturę i dopiero wewnątrz operować na konkretnych elementach struktury w zależności np. od wartości argumentu direction. Jeśli przekażesz do funkcji wskaźnik na strukturę, to typy poszczególnych jej elementów będą znane wewnątrz definicji funkcji. Przekazywane do funkcji wskaźniki są 16-bitowe niezależnie od tego, na co wskazują, więc nie wpłynie to jakoś niekorzystnie na rozmiar kodu czy szybkość wykonania.

Niestety Twój opis jest zbyt ogólny, żeby doradzić coś konkretnego.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 gru 2018, o 19:23 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

No wiesz nie zabardzo chciałem zawracać głowy tym moim całym projektem ale jak go skończę to postaram sie opisać o co chodzi wstawić do DIY.
A także ciężko jednak pisząc przekazać dokładnie co się chce zrobić.
To jak pisanie 100 SMS-ów duzo szybciej można przekazać w 30s rozmowy.

A apropo przekazania wskaźnika do całej struktury to musiał bym dużo kombinować bo mam w tej strukturze kopię wszystkich rejestrów tego układu TDA7418 a jest ich 14 każdy to uint8_t i do tego 10 intów do przechowywania wartości i zmiany.

Jeszcze raz bardzo ci dziękuję fajnie, że masz wiedzę i chęć pomocy takim początkującym.

Pozdrawiam Paweł.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 4 gru 2018, o 20:16 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

P3ndz3l3k napisał(a):
A apropo przekazania wskaźnika do całej struktury to musiał bym dużo kombinować bo mam w tej strukturze kopię wszystkich rejestrów tego układu TDA7418 a jest ich 14 każdy to uint8_t i do tego 10 intów do przechowywania wartości i zmiany.

Wprawdzie nie znam szczegółów, ale wydaje mi się, że to raczej nie jest problem. Przecież i tak musisz pobrać adresy odpowiednich elementów struktury, więc czy zrobisz to przed wywołaniem funkcji, czy też dopiero wewnątrz funkcji nie powinno stanowić większej różnicy, a przekazanie całej struktury mogłoby rozwiązać problem kolejności argumentów i uczyniło funkcję bardziej uniwersalną.

No ale mogę się mylić, bo nie znam dokładnie Twojej ogólnej koncepcji programu. Nie będę już w takim razie narzucał się ze swoją pomocą i psuł Ci frajdy z odkrywania zawiłości języka C oraz satysfakcji z samodzielnego napisania kodu.

Życzę powodzenia w kodowaniu i pozdrawiam :-)
   Andrzej



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 12 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO