Pomocnik

Mam błąd przy kompilacji, brak „sbi” i cbi”

Wstaw gdzieś na początku kodu definicje:
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

Operacje na bitach

Ta część Pomocnika jest oparta na listach Erica Weddingtona na AVRfreaks.

W języku C można ustawiać wartości bitów i odczytywać ich stan używając
operatorów bitowych, operatorów przypisania i masek bitowych.
PORTC |= 0x01;    // Ustaw bit 0 portu C.
PORTC &= ~0x01;     // Zeruj bit 0 portu C.
PORTC ^= 0x01;     // Przełącz bit 0 portu C.
PORTC & 0x01;     // Testuj bit 0 portu C.
PORTC |= 0x80;     // Ustaw bit 7 portu C.

Obecnie w „avr-libc” jest używane makro _BV() (BV od Bit Value).
Jest ono zdefiniowane jako:
#define _BV(x) (1 << x)
co pozwala na następujący zapis:
PORTC |= _BV(0);    // Ustaw bit 1 portu C .
PORTC &= ~_BV(1);     // Zeruj bit 0 portu C.
PORTC ^= _BV(7);     // Przełącz bit 7 portu C.
który można spotkać w definicjach w plikach nagłówkowych procesorów np.:
// For atmega128
#include <avr/io.h>
UCSR0B |= _BV(TXEN0);     // Ustaw bit 3 w UCSR0B.
Używając operatorów bitowych można dokonać operacji na wielu bitach jednocześnie:
PORTC |= (_BV(0) | _BV(2) | _BV(7));     // Ustaw bity 0,2,7
PORTC &= ~(_BV(1) | _BV(2) | _BV(6));     // Zeruj bity 1,2,6
PORTC ^= (_BV(5) | _BV(3));     // Przełącz bity 3,5
Dla wiekszej czytelności, można zdefiniować następujące makra:
#define bit_set(v,m) ((v) |= (m))
#define bit_clear(v,m) ((v) &= ~(m))
#define bit_toggle(v,m) ((v) ^= (m))
#define bit_test(v, m) ((v) & (m))
i potem je użyć w pokazany niżej sposób:
bit_set(PORTC, _BV(0));
bit_clear(PORTC, _BV(3) | _BV(5));
albo
// Check if transmit is complete
if(bit_test(UCSR0A, _BV(TXC0)))
{
// Send data.
}
Można uczynić ostatni przykład jeszcze bardziej czytelnym tworząc dodatkową warstwę makra:
#define usart0_transmit_complete() bit_test(UCSR0A, _BV(TXC0)
Dzięki temu można teraz zapisać:
// Check if transmit is complete
if(usart0_transmit_complete())
{
// Send data.
}

Reklamy
%d blogerów lubi to: