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



Teraz jest 18 kwi 2024, o 19:01


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 17 ] 
Autor Wiadomość
PostNapisane: 8 mar 2021, o 21:55 
Offline
Użytkownik

Dołączył(a): 01 sty 2013
Posty: 169
Pomógł: 0

Hej. Mam taki dylemat. Mam zmienną o nazwie "uint8_t wyjscia" Dla rozjaśnienia dodam, że będzie ona wysyłana na rejestr 74HC595 funkcją spi_xmit_byte ();

problem stanowi to, że pierwsza część bajtu (najstarsze cztery bity ) sterują przypuśćmy ledami, a druga część bajtu (najmłodsze cztery bity) sterują przekaźnikami.

Sterowanie mógłbym zrobić poprzez maskowanie czyli
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
ale wpisując takie coś to ustawię bity W taki 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.
wyzeruję. Jednocześnie jeśli chciałbym zapisać całą połówkę
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
poprzestawiam drugą połówkę bitu, której nie chcę ruszać.

Ustawianie i kasowanie każdego bitu niezależnie mógłbym zrealizować tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Coś mi jednak mówi że nie jest to dobry, poprawny czy też elegancki sposób.

Czy istnieje jakieś inne bardziej eleganckie rozwiązanie takiego sterowania?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 mar 2021, o 22:33 
Offline
Użytkownik

Dołączył(a): 11 sty 2015
Posty: 166
Pomógł: 24

Twój sposób jest całkiem poprawny i powinien działać.
Co do elegancji to oczywiście można to zrobić inaczej, kwestia co się komu podoba i czemu ma to służyć.
Pytanie tylko jak to chcesz wywoływać w programie?
Bo jeżeli masz ustawione wcześniej wszystkie zmienne led i prk to możesz to załatwić np. jedną linią:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

jeżeli chcesz zmienić tylko jeden bit to musisz to maskować np. tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Oczywiście zamiast posługiwać się stałymi dosłownymi możesz je wcześniej zdefiniować i posługiwać się makrami.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


------------------------ [ Dodano po: 6 minutach ]

Może trochę się pośpieszyłem z tym, że twój sposób jest dobry.
Przesuwasz całe wyjścia, powinno być:
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: 8 mar 2021, o 23:51 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2019
Posty: 147
Pomógł: 37

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łę

_________________
Think for yourself and question authority.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 06:42 
Offline
Użytkownik

Dołączył(a): 01 mar 2021
Posty: 28
Pomógł: 2

Forex. Dlaczego w strukturze zmienne typu int?

------------------------ [ Dodano po: kilkunastu sekundach ]

Fofex miało być ☺️



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 07:39 
Offline
Użytkownik

Dołączył(a): 01 sty 2013
Posty: 169
Pomógł: 0

A jeśli te połówki mam już wcześniej zdefiniowane w postaci stałej - słowa 4 bitowego np:

w zależności co się dzieje w programie wystawiam połówkę bajtu
1111
0111
1011
1101
0101
0001

Jak taką połówkę wstawić jako taką wartość binarną nie zmieniając jednocześnie drugiej połówki ?
Moimi sposobami powyżej to poustawiam tylko bity, a nie wyzeruję, lub wyzeruję a nie ustawię albo też zmienię cały bajt przypisaniem "= "

Jeśli bym chciał zamaskować drugą połówkę bajtu musiałbym ją chwilowo zapisać do jakiejś innej zmiennej a potem poprzez |= dopisać tę drugą część . Ale tutaj też albo bity poustawiam, albo wyzeruję albo zapiszę cały bajt - czego też nie chcę i znów jestem w punkcie wyjścia
Można by też użyć przesunięcia bitowego np wyjscia = (0b1101<<4) ale to też poprzesuwa mi pozostałe bity bajtu.

Czy jest jakiś sposób aby zmienić połówkę bajtu bez ingerencji w drugą jej część? jestem pewny że język C umożliwia takie operacje.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 07:53 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Maskowanie i sumowanie bitów



Ostatnio edytowano 9 mar 2021, o 08:14 przez micky, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 08:04 
Offline
Użytkownik

Dołączył(a): 01 sty 2013
Posty: 169
Pomógł: 0

czyli operator XOR. Jeśli bit zostanie zamaskowany wartością 0 nie zostanie zmieniony. A takie użycie będzie poprawne?

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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 08:14 
Offline
Użytkownik

Dołączył(a): 01 mar 2021
Posty: 28
Pomógł: 2

pol_bajtu = 0b0000xxxx;
wyjście |= pol_bajtu ; (wyjście = wyjście | pol_bajtu)
Tak ustawisz młodsze pół bajtu bez ingerencji w starsze.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 08:15 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Maskowanie to AND a nie żaden XOR. Sumowanie to OR.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 08:30 
Offline
Użytkownik

Dołączył(a): 01 mar 2021
Posty: 28
Pomógł: 2

Kasowanie poszczególnych bitów bez ingerencji w pozostałe:
wyjście &= ~(1<<nr_bitu);



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 08:33 
Offline
Użytkownik

Dołączył(a): 01 sty 2013
Posty: 169
Pomógł: 0

adamma25 napisał(a):
wyjście |= pol_bajtu ; (wyjście = wyjście | pol_bajtu)
Tak ustawisz młodsze pół bajtu bez ingerencji w starsze.

Tak jak powiedziałeś ustawię ale tylko ustawię, bo używamy operatora | Ja chciałem również wyzerować te bity według wcześniej przegotowanego schematu.

Np kiedy zmienna "wyjścia" będzie miała wartość 1010 i dopiszę w ten sposób" wyjście |= 0b0101" to otrzymam 1111, czy tak jak chciałem 0101?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 08:57 
Offline
Użytkownik

Dołączył(a): 01 mar 2021
Posty: 28
Pomógł: 2

Przy sumowaniu OR, tam gdzie była jedynka wcześniej, to zostanie jedynka. Jeśli chcesz skasować te jedynki to musisz użyć najpierw AND czyli:
wyjście &= ~(0b00001111), a następnie użyć sumy OR tak jak wcześniej pisałem lub odrazu można :
Wyjście =( (wyjście &(~(0b00001111))) | pol_bajtu )). Chyba tak. Wybacz jeśli coś pomyliłem z nawiasami. Wydaje mi się że w ten sposób, ale mogę się mylić



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 09:02 
Offline
Użytkownik

Dołączył(a): 01 sty 2013
Posty: 169
Pomógł: 0

Trochę moje pytanie się rozjechało, więc jeśli pozwolicie wyjaśnię jeszcze raz o co mi chodzi:

Mam bajt o nazwie "wyjscia" i steruje on dwoma zestawami przekaźników (po 4) . W różnych momentach programu na tych czterech przekaźnikach mają się pojawiać różne kombinacje załączonych i wyłączonych przekaźników I tak

pierwsza cześć bajtu ( pierwsze cztery przekaźniki) mają mieć stany 1010 a druga część bajtu ma mieć stan 0011.
W pewnym momencie zmienia się stan tylko czterech pierwszych przekaźników na zupełnie inny niektóre jego bity są wygaszane, niektóre zapalane a niektóre bez zmian. nie mogę tego zrobić za pomocą opertaora = ponieważ zapiszę cały bajt a nie chcę ruszać jego drugiej części. Nie mogę zrobić za pomocą |= ponieważ tylko zapalę bajty a nie wygaszę. Kiedy zrobię &= tylko wygaszę a nie pozapalam.

Wcześniejsze moje pomysły nie działają. Jaką prostą operacją można zapisać (zamaskować) jedną połowę bajtu nie ruszając jednocześnie drugiej a potem drugą połowę, nie zmieniając nic w pierwszej przy pomocy najlepiej innej zmiennej dosłownej tzn 0b0101xxxx lub 0bxxxx0011 ?

Nie chcę pojedynczo zapalać i gasić bitów tak jak podpowiedziano wcześniej, ponieważ mam już ustalone różne stany tych przekaźników (półbajtów) i nie wiem z jakiego stanu będą zmieniane Na jaki wiem ale warunki typu if skomplikowałyby program mocno.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 09:12 
Offline
Użytkownik

Dołączył(a): 01 mar 2021
Posty: 28
Pomógł: 2

Kolego wszystko możesz zrobić, przed wysłaniem do rejestru. Przecież dopóki nie wyślesz to nic się nie zmieni. Użyj AND lub OR tak jak pisałem czy inaczej. Możesz przed wysłaniem odrazu wpisać bajt który ci odpowiada.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 09:21 
Offline
Użytkownik

Dołączył(a): 01 sty 2013
Posty: 169
Pomógł: 0

Zgadza się, ale jeszcze raz. Chcę do zmiennej wyjścia przypisać cztery pierwsze bity jako 0b1010xxxx nie ruszając bitów młodszych Nie chcę robić tego w ten sposób
wyjscia |= (0b1010xxxx) a potem
wyjścia &= ~(0b0101xxxx)
ponieważ mam już przygotowaną wcześniej przez inną funkcję połówkę bajtu która wygląda tak
0b1010xxxx

nie mogę tego zrobić w ten sposób
wyjścia = (0b1010xxxx) ponieważ zmienić muszę wtedy też drugą młodszą część bajtu.


I tak jak w tytule posta nie wiem czy lepiej maskować pół bajtu ( w jaki sposób) czy przesuwać.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 09:31 
Offline
Użytkownik

Dołączył(a): 01 mar 2021
Posty: 28
Pomógł: 2

Wyjścia = (0b00001111 & wyjścia) | 0b1010xxxx; jeśli dobrze zrozumiałem to tak można


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 mar 2021, o 10:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2019
Posty: 147
Pomógł: 37

adamma25 napisał(a):
Dlaczego w strukturze zmienne typu int?

Powinno być raczej unsigned. Możesz wstawić unsigned char albo uint8_t, jeśli wolisz.

_________________
Think for yourself and question authority.



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: 17 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 4 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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO