Programownie w C
- Tranzystor
- Użytkownik
- Posty: 889
- Rejestracja: 28 sie 2005, 19:19
- Lokalizacja: Świętochłowice
- Kontakt:
No właśnie 
& oznacza iloczyn logiczny (bramka AND),
| oznacza sumę logiczną (bramka OR),
^ jest bramką XOR,
~ jest negacją czyli bramka NOT.
Jeżeli chodzi o zapis:
to jest on równoznaczny z zapisem:
Myślę, że teraz wszystko jasne
Pozdrawiam
& oznacza iloczyn logiczny (bramka AND),
| oznacza sumę logiczną (bramka OR),
^ jest bramką XOR,
~ jest negacją czyli bramka NOT.
Jeżeli chodzi o zapis:
Kod: Zaznacz cały
DDRB |= _BV(DDB7);Kod: Zaznacz cały
DDRB = DDRB | _BV(DDB7);Pozdrawiam
A jak się nie chce stosować tych operatorów to można sobie pisać przykładowo:
wtedy każda cyfra po "b" oznacza jeden bit rejestru DDRB, czyli każdy pin portu B. Tyle że wtedy trzeba pamiętać o tym żeby po 0b było 8 cyfr. Tyle że taki zapis ma wadę że zmieniamy na raz cały rejestr a przy pomocy operatorów bitowych operujemy w danym momencie tylko na jednym bicie rejestru pozostałe zostawiając w spokoju.
Kod: Zaznacz cały
DDRB=0b01011100;- Tranzystor
- Użytkownik
- Posty: 889
- Rejestracja: 28 sie 2005, 19:19
- Lokalizacja: Świętochłowice
- Kontakt:
AND czyli symbol "&" jest przydatny do przykładania maski, zerowania bitów
np na PORTB mamy stany 10011111 i załóżmy że chcemy wyzerować najstarszy i najmłodszy bit a pozostałe pozostawić bez zmian:
tworzymy maskę ~((1<<7)|(1<<0)) która binarnie wygląda tak 10000001 a po negacji (tej prze nawiasem) wyglądać to będzie tak 01111110
teraz robimy iloczyn logiczny:
10011111
& 01111110
--------------
00011110
OR jest niezastąpione do ustawiania bitów np 10011111 chcąc ustawić przedostatni bit (patrząc od najstarszego) tworzymy maskę 1<<6 czyli 01000000
10011111
| 01000000
--------------
11011110
Zapis PORD |=1<<6 jest tożsamy z zapisem PORD =PORTD | 1<<6
Jest to przypisanie wartości operacji sumy logicznej do PORTD z maską 1<<6 na PORTD
Polecam jeszcze raz przerobienie przykładów operacji bitowych z pliczku, który polecałem wcześniej w dowolnym kompilatorze np Dev C++ czy C++ Builder.
Powinno to wszystko rozjaśnić
np na PORTB mamy stany 10011111 i załóżmy że chcemy wyzerować najstarszy i najmłodszy bit a pozostałe pozostawić bez zmian:
tworzymy maskę ~((1<<7)|(1<<0)) która binarnie wygląda tak 10000001 a po negacji (tej prze nawiasem) wyglądać to będzie tak 01111110
teraz robimy iloczyn logiczny:
10011111
& 01111110
--------------
00011110
OR jest niezastąpione do ustawiania bitów np 10011111 chcąc ustawić przedostatni bit (patrząc od najstarszego) tworzymy maskę 1<<6 czyli 01000000
10011111
| 01000000
--------------
11011110
Zapis PORD |=1<<6 jest tożsamy z zapisem PORD =PORTD | 1<<6
Jest to przypisanie wartości operacji sumy logicznej do PORTD z maską 1<<6 na PORTD
Polecam jeszcze raz przerobienie przykładów operacji bitowych z pliczku, który polecałem wcześniej w dowolnym kompilatorze np Dev C++ czy C++ Builder.
Powinno to wszystko rozjaśnić
Najprościej to chyba będzie pokazać na przykładzie.
Weźmy PORTB = 48 (00110000b w zapisie bitowym) przy czym wszystkie nóżki są wyjściami. Chcemy zapalić diodę podłączoną do pinu nr 2 PORTB. Tworzymy maskę (1<<2) = 4 (00000100b). Na koniec robimy operację sumy logicznej:
00110000b
00000100b
-----------
00110100b
W przypadku gdy chcemy wygasić bit nr 5 tworzymy odwróconą maskę ~(1<<5) = ~(00100000b) = 11011111b. ~ jest operatorem negacji logicznej. I jeszcze iloczyn logiczny:
00110000b
11011111b
-----------
00010000b
Prościej to już się chyba tego nie da wytłumaczyć.
//edit: za wolno posty piszę :p
Weźmy PORTB = 48 (00110000b w zapisie bitowym) przy czym wszystkie nóżki są wyjściami. Chcemy zapalić diodę podłączoną do pinu nr 2 PORTB. Tworzymy maskę (1<<2) = 4 (00000100b). Na koniec robimy operację sumy logicznej:
00110000b
00000100b
-----------
00110100b
W przypadku gdy chcemy wygasić bit nr 5 tworzymy odwróconą maskę ~(1<<5) = ~(00100000b) = 11011111b. ~ jest operatorem negacji logicznej. I jeszcze iloczyn logiczny:
00110000b
11011111b
-----------
00010000b
Prościej to już się chyba tego nie da wytłumaczyć.
//edit: za wolno posty piszę :p
Czyli jeśli dobrze zrozumiałem jeśli mam np
Jesli dobrze to chwała wam jeśli nie to się pochlastam
. Kolega Banan popełnił mały błąd chyba bo odwrócona maska ~(1<<5) to bitowo 11101111 
Kod: Zaznacz cały
PORTB=125 bitowo 01111101
i chce zmienic tylko 4 i 5 bit to tworze maske
PORTB&=~(1<<4) | (1<<5)
Rozumiem, że chciałeś wyzerować bity, lecz popełniłeś drobny błąd: brak nawiasów. Poprawnie powinno wyglądać tak:
'~' ma wyższy priorytet i zostało by wykonane wcześniej niż '|'.
Kod: Zaznacz cały
PORTB &= ~((1<<4) | (1<<5))Zobacz. Operacje na bitach są proste
W skrócie. Jeśli chcesz ustawić jakiś bit, to musisz do niego dodać 1, czyli operacja bitowa OR. Nie ważne, czy wartość początkowa będzie 0 czy 1, to zawsze wynik dodawania będzie 1.
np
. Ustawiamy najmłodszy bit
np.
Można dołożyć do tego jeszcze przesunięcie bitowe w lewo. Chcemy ustawić bit 5.
Co daje razem ustawianie bitu 6 portu C.
Co w skrócie można zapisać jako:
Jeśli chcesz bit wyzerować, to musisz pomnożyć go przez 0, bo mnożenie przez 0 zawsze daje wynik 0. Bitowa funkcja AND. Obejrzyj sobie w necie tabelki prawdy tych funkcji, jeśli ich nie znasz.
Przykład zerowania bitu 4 portu C:
Czyli dla przykładu wartość rejestru PORTC przed i po operacji.
W skrócie. Jeśli chcesz ustawić jakiś bit, to musisz do niego dodać 1, czyli operacja bitowa OR. Nie ważne, czy wartość początkowa będzie 0 czy 1, to zawsze wynik dodawania będzie 1.
Kod: Zaznacz cały
00100100 | 00000001 = 00100101Kod: Zaznacz cały
PORTC = PORTC | 0x01;Kod: Zaznacz cały
00000001 << 5 = 00100000Kod: Zaznacz cały
PORTC = PORTC | (1<<5);Kod: Zaznacz cały
PORTC |= (1<<5);Przykład zerowania bitu 4 portu C:
Kod: Zaznacz cały
PORTC &= (1<<4)Kod: Zaznacz cały
00111101 & 00010000 = 00101101 Nie chce zakładać nowego tematu wiec napisze w starym(temat pasuje).Chce użyć timera1 jako czasomierza.Stworzyłem zlepek z kilku programów z sieci i kursów chciałbym aby mi to ktos sprawdził i w razie potrzeby pomógł.Proszę o wyrozumiałość
Kod: Zaznacz cały
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define OSC 8
char jednostki_sekund = 0
char dziesiatki_sekund = 0
char jednostki_minut = 0
char dziesiatki_minut = 0
char jednostki_godzin = 0
char dziesiatki_godzin = 0
SIGNAL (SIG_OVERFLOW1)
{
TCNT1H = 0x0B;
TCNT1L = 0xDC;
czas();
}
void czas(void)
{
jednostki_sekund++;
if(jednostki_sekund == 10)
{
jednostki_sekund = 0;
dziesiatki_sekund++;
if(dziesiatki_sekund == 6)
{
dziesiatki_sekund = 0;
jednostki_minut++;
if(jednostki_minut == 10)
{
jednostki_minut = 0;
dziesiatki_minut++;
if(dziesiatki_minut == 6)
{
dziesiatki_minut = 0;
jednostki_godzin++;
if((dziesiatki_godzin == 2) && (jednostki_godzin == 4))
{
dziesiatki_godzin = jednostki_godzin = 0;
}
if(jednostki_godzin == 10)
{
jednostki_godzin = 0;
dziesiatki_godzin++;
}
}
}
}
}
}
int main(void)
{
DDRB = 0xFF;
DDRD = 0xFC;
PORTB = 0xFF;
PORTD = 0xF7;
TCCR0A = 0x04;
TCCR1B = 0x03;
TCNT0 = 128;
TIMSK = 130;
TCCR1B = _BV(CS10)|_BV(CS12|~_BV(CS11); // preskaler 1024
sei();//globalne zezwolenie na przerwania
while(1);
return 0;
}