Skocz do zawartości

Maska bitowa OR a sterowanie serwami


Pomocna odpowiedź

Napisano

Witajcie,
mam spory problem z zadaniem które wyznaczył mi prowadzący lab: wysterować ramię robota (7 serw) przy użyciu procesora sygnałowego + układu FPGA (po prostu taki zestaw jest dostępny w tym laboratorium).

Z układem FPGA nie było większych problemów bo za dużo w nim zmieniać nie musieliśmy.

Serwa nieprzerobione, o czym pewnie wiecie lepiej ode mnie są sterowane wypełnieniem sygnału (dla tego konkretnego serwa 0,3 ms do 2,7 ms) z częstotliwością 50Hz. To, znając taktowanie procesora, udało mi się zrealizować.

Dla jednego konkretnego serwa sterowanie jest realizowane poprawnie, dla większej ich ilości już nie. Sygnał sterujący wysyłany jest w postaci 1 logicznej na konkretnym bicie przyporządkowany do danego serwa. Gdy przykładowo sterujemy serwem pierwszym na wyjście wystawiamy 1 gdy drugim 2 trzecim 4 i dla dalszych analogicznie.

Natomiast problem jest być może banalny ale ja nie umiem sobie z nim poradzić: gdy steruję serwem np trzecim (wyjscie na 4, binarne [..]100) to reszta serw jest niesterowalna. Z tego co przeglądnąłem w sieci to rozwiązaniem problemu byłaby maska OR.

Sama idea jest dla mnie mniej więcej zrozumiała jednak jej implementacja w C już nie.

W celu poglądowym zamieszczam część kodu w C jaką napisałem.

/***********************KOD WLASNY*************************/	

zm_licznik++ ;

if(zm_licznik>zm_serwo_1) JP1=1 ;
 else JP1=0;
if(zm_licznik>zm_serwo_2) JP1=2 ;
 else JP1=0;  
if(zm_licznik>zm_serwo_3) JP1=4 ;
 else JP1=0;  
if(zm_licznik>zm_serwo_4) JP1=8 ;
 else JP1=0;
if(zm_licznik>zm_serwo_5) JP1=16 ;
 else JP1=0;
if(zm_licznik>zm_serwo_6) JP1=32 ;
 else JP1=0;  
if(zm_licznik>zm_serwo_7) JP1=64 ;
 else JP1=0;   

if(zm_licznik>133) zm_licznik=0;

OUTPUT0=(int)JP1;

/***********************KOD WLASNY*************************/

I tu moje pytanie jak wyfiltrować (zamaskować) wartości JP1 tak aby móc zmieniać bity niezależnie. Tak aby ustawienie <> na którymś z bitów nie zerował pozostałych.

Zamieszczam zdjęcie.

Byłbym niezmiernie rad gdyby ktoś pomógł mi z tym maskowanie.

Ja niestety z C nie miałem za dużo wspólnego wiec poprosiłbym o łopatologiczne wytłumaczenie.

1. OR to | , drugi przydatny może byc dla ciebie AND &

W każdej książce do C to znajdziesz, więc nie wiem gdzie szukałeś

2.Możesz też sterować każdym serwem oddzielnie. Sygnał dla poszczególnych serw wysyłasz co 20ms, a maksymalna długość sygnału to generalnie ~2ms. Czyli teoretycznie możesz generować 10 sygnałów oddzielnie i to zapętlić, co da 20ms.

Optymalnie zostawić sobie trochę więcej miejsca i generować maksymalnie sygnał ok 2,5ms, bo każde serwo działa w trochę innym zakresie.

3.DSP+FPGA to jak strzelanie z atomówki do muchy 🙂

7*2,7 = 18,9ms, więc możesz kolejno do poszczególnych serw bez problemu wysyłać informację. Sprawdź może jakie masz opcje w tym procesorze sygnałowym, być może mógłbyś wygenerować sprzętowo na odpowiednich nóżkach sygnały PWM o okresie 20ms.

Operacje | i & to podstawa, więc masz pewne braki w edukacji jeśli chodzi o programowanie mikroprocesorów.

Operacje | i & to podstawa, więc masz pewne braki w edukacji jeśli chodzi o programowanie mikroprocesorów.

Dlatego napisałem w dziale dla początkujących.

Czy to zadziała poprawnie?

if(zm_licznik>zm_serwo_1) JP1=JP1 | 1 ;
 else JP1=0;
if(zm_licznik>zm_serwo_2) JP1=JP1 | 2 ;
 else JP1=0;  
if(zm_licznik>zm_serwo_3) JP1=JP1 | 4 ;
 else JP1=0;  
if(zm_licznik>zm_serwo_4) JP1=JP1 | 8 ;
 else JP1=0;
if(zm_licznik>zm_serwo_5) JP1=JP1 | 16 ;
 else JP1=0;
if(zm_licznik>zm_serwo_6) JP1=JP1 | 32 ;
 else JP1=0;  
if(zm_licznik>zm_serwo_7) JP1=JP1 | 64 ;
 else JP1=0;  

dla ustawiania poszczegolnych bitow, tak, tylko potem nie kasujesz poszczegolnych bitow w else tylko cala zmienna i tutaj sie wszystko rozjedzie 🙂

Podalem po cos funkcje AND...

Faktycznie, o tym nie pomyślałem. Dzięki.

if(zm_licznik>zm_serwo_1) JP1=JP1 | 1 ;
 else JP1=JP1 & 126;
if(zm_licznik>zm_serwo_2) JP1=JP1 | 2 ;
 else JP1=JP1 & 125;  
if(zm_licznik>zm_serwo_3) JP1=JP1 | 4 ;
 else JP1=JP1 & 123;  
if(zm_licznik>zm_serwo_4) JP1=JP1 | 8 ;
 else JP1=JP1 & 119;
if(zm_licznik>zm_serwo_5) JP1=JP1 | 16 ;
 else JP1=JP1 & 111;
if(zm_licznik>zm_serwo_6) JP1=JP1 | 32 ;
 else JP1=JP1 & 95;  
if(zm_licznik>zm_serwo_7) JP1=JP1 | 64 ;
 else JP1=JP1 & 63;  

Mam nadzieję że to już jest dobrze.

Tak, wyglada ok.

Tylko jeżeli zmienna JP1 jest zmienna lokalna, którą na koniec przesyłasz na port to łatwiej zrobić:

JP1=0;

i potem same if...

a wszystkie else są zupełnie zbędne i tylko zwalniają program 🙂

Polecam stosowanie skrótów 🙂

JP1 = JP1 | 16;

to to samo co

JP1 |= 16;

działa to z każdym operatorem (+-/*|&^)

X = X op Y

X op= Y

Co się kryje pod zmiennymi zm_serwo_x ?

Zdecydowanie tak jak proponuje Mirek:

int JP1 = 0;

if () JP1 |= 1;

if () JP1 |= 2;

...

Już zrealizowałem tą radę aby zerować je jednocześnie.

zm_serwo_x służy do zadawania położenia serwa. Przykładowo (bo nie pamiętam już dokładnych wartości liczbowych) ustawiając 5 masz położenie max w jedną ze stron 15 środek 25 max w drugą. Odpowiada to konkretnym wartością w milisekundach.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...