Skocz do zawartości

Manipulowanie bitami w rejestrach portów - pierwsze próby


MarJanPol

Pomocna odpowiedź

Witam, jak zmodyfikować ten kod, żeby ustawiał wyjście i jedynkę na pinie D13 a nie D2?

void setup()
{DDRD = B00000100;
PORTD = B00000100;}
void loop()
{}

Próbowałem przez analogię:

  
void setup()
 {
 DDRB = B00100000; 
 }
 void loop()
{
PORTB = B00100000; 
delay(1000);
PORTB = B00100000; 
delay(1000);  
}
{}

ale nie działa.

Link do komentarza
Share on other sites

Może nie działa, bo Atmega328 nie ma pinu D13.

Zobacz np tutaj: https://www.theengineeringprojects.com/2017/08/introduction-to-atmega328.html - punkt 11

Inna sprawa, że ta "analogia" i tak nie zadziała, nawet jak wybierzesz istniejący pin.

Zasugerowałem się: https://www.arduino.cc/en/Reference/PortManipulation

Port Registers

Port registers allow for lower-level and faster manipulation of the i/o pins of the microcontroller on an Arduino board. The chips used on the Arduino board (the ATmega8 and ATmega168) have three ports:

B (digital pin 8 to 13)

C (analog input pins)

D (digital pins 0 to 7)

Each port is controlled by three registers, which are also defined variables in the arduino language. The DDR register, determines whether the pin is an INPUT or OUTPUT. The PORT register controls whether the pin is HIGH or LOW, and the PIN register reads the state of INPUT pins set to input with pinMode(). The maps of the ATmega8 and ATmega168 chips show the ports. The newer Atmega328p chip follows the pinout of the Atmega168 exactly.

Link do komentarza
Share on other sites

Ok, jeśli z D13 chodziło o pin Arduino 13 to faktycznie odpowiada mu PB5 i kod wygląda poprawnie.

[ Dodano: 25-02-2018, 18:05 ]

Edit: inna sprawa, że masz dwa razy do samo:

PORTB = B00100000;
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Właściwie to wypadałoby zmieniać tylko jeden bit, a nie zerować przy okazji wszystkie...

No fakt, a jak w takim poleceniu "bitowym" wskazać na konkretny bit bez dotykania pozostałych?

I jeśli można od razu drugie pytanie - gdybym chciał podpiąć zegar do któregoś timera, to muszę ustawić bit CS10 np w TCCR1B. Idąc za słuszną radą kolegi sprawdziłem w dokumentacji Atmegi 328P, że to jest pierwszy bit w rejestrze. Czyli znów chciałem na zasadzie analogii zrobić tak : TCCR1B = B00000001; No ale wtedy bym znów wyzerował pozostałe bity więc przydałoby się znów wiedzieć jak wskazać tylko ten konkretny bit...

Link do komentarza
Share on other sites

Tak, chociaż jest w tym pewna pułapka związana z przerwaniami - na szczęście na AVR kompilator powinien wygenerować odpowiedni kod i wszystko zadziała zawsze prawidłowo.

  • Lubię! 1
Link do komentarza
Share on other sites

Przypominam też, że do odwrócenie bitu na porcie nie trzeba robić operacji AND/OR. W AVR wystarczy wpisać jedynkę do rejestru PINx na bicie, który chcemy odwrócić:

PINB = 0b00100000;

Powyższe odwraca linię PB5. Oczywiście można mrugać na raz wieloma bitami:

PINB = 0b1011;

A do rejestrów timera nie pisz zer i jedynek bo jutro zapomnisz co to miało być, tylko używaj nazw tych bitów. Ktoś już odwalił robotę w podefiniowanie tego wszystkiego więc żeby odpalić zegar timera możesz zrobić tak:

TCCR2B = _BV(CS20);

albo tak, jeśli potrzebujesz więcej bitów na raz (i wolniejszy zegar):

TCCR2B = _BV(CS20) | _BV(CS21);

_BV() zamienia liczbę na zapalony bit na tej pozycji i jest liczone przez kompilator więc nie "zużywa" procesora.

Link do komentarza
Share on other sites

Nie jestem na 100% pewien, ale w przypadku AVR kompilator chyba zamienia operację OR/AND wykonywaną na jednym bicie na pojedynczą instrukcję asemblera - SBI/CBI czy jakoś tak. W każdym razie jest to operacja atomowa i nie ma problemów np. z przerwaniami. Inna sprawa, że niewielka zmiana w kodzie i ustawienie 2 bitów daje zupełnie inny kod i przestaje być atomową operacją. Inne mikrokontrolery mają często dodatkowe rejestry do ustawiania oraz kasowania bitów, albo jeszcze bardziej skomplikowane mechanizmy dostępu do pojedynczych bitów.

Link do komentarza
Share on other sites

Przypominam też, że do odwrócenie bitu na porcie nie trzeba robić operacji AND/OR. W AVR wystarczy wpisać jedynkę do rejestru PINx na bicie, który chcemy odwrócić:

PINB = 0b00100000;

Powyższe odwraca linię PB5. Oczywiście można mrugać na raz wieloma bitami:

PINB = 0b1011;

A do rejestrów timera nie pisz zer i jedynek bo jutro zapomnisz co to miało być, tylko używaj nazw tych bitów. Ktoś już odwalił robotę w podefiniowanie tego wszystkiego więc żeby odpalić zegar timera możesz zrobić tak:

TCCR2B = _BV(CS20);

albo tak, jeśli potrzebujesz więcej bitów na raz (i wolniejszy zegar):

TCCR2B = _BV(CS20) | _BV(CS21);

_BV() zamienia liczbę na zapalony bit na tej pozycji i jest liczone przez kompilator więc nie "zużywa" procesora.

Dzięki marek1707!

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.