[FAQ] Изменение и чтение отдельных битов

Ответы на наиболее часто встречающиеся вопросы.

[FAQ] Изменение и чтение отдельных битов

Сообщение toshas » 18 сен 2008, 20:24

имеем порт J, в codevision работать с ним как PORTJ.n нельзя,
поэтому для установки бита N в единицу не трогая другие биты делаем так:
PORTJ = PORTJ | (1<<N); или короче PORTJ |= (1<<N);

установка бита N в ноль тогда будет:
PORTJ = PORTJ & ~(1 << N);

Тема перенесена. Для факов есть спецраздел.
<Digit>


< avr123 > Как считывать и использовать значения отдельных битов смотрите в примерах на страничке "Си для МК" http://avr123.nm.ru/05a.htm
Аватара пользователя
toshas
 
Сообщения: 90
Зарегистрирован: 31 янв 2006, 14:37
Откуда: Москва

Re: [FAQ] установка определенного бита в порте/регистре

Сообщение Vooon » 22 сен 2008, 03:34

Классические макросы:

Код: Выделить всё
#ifndef _BV    // If !WinAVR
#define _BV(n)    (1 << (n))
#endif

#define set_bit(p, n)    p |= _BV(n)
#define clear_bit(p, n)    p &= ~_BV(n)
#define invert_bit(p, n)    p ^= _BV(n)
Linux user | Firefox user
Аватара пользователя
Vooon
Site Admin
 
Сообщения: 3339
Зарегистрирован: 09 фев 2006, 15:36
Откуда: Москва
Skype: vooon341
прог. языки: Python, C, Bash, JavaScript, C++, PHP
ФИО: Владимир Ермаков

Re: [FAQ] установка определенного бита в порте/регистре

Сообщение avr123.nm.ru » 22 сен 2008, 08:05

Цитата из задачи-упражнения 1 в курсе
http://avr123.nm.ru/z1.htm

Внимание ! Очень важно! Битовые операции !

Манипуляции отдельными битами регистров и переменных.

Надеюсь вы уже поняли - МК обычно должен "дергать ножками" - создавать на них то "1" то "0", то считывать, что там на них есть. И обычно не всеми сразу, а то одной то другой !

Значит Вы должны уметь эффективно управлять не целым портом, регистром, а отдельными битами!

Вот моя подборка вариантов такого управления для разных компиляторов!

ПРОВЕРЕНО в компиляторах IAR, CVAVR, ImageCraft ICC

1) вариант для любого компилятора:

// объявление:

Код: Выделить всё
#define SET_B(x) |= (1<<x)
#define CLR_B(x) &=~(1<<x)
#define INV_B(x) ^=(1<<x)


// x - номер бита в регистре

// использование:

Код: Выделить всё
PORTB SET_B(5);  // "установить"  бит5
PORTB CLR_B(2);  // "очистить"  бит2
PORTB INV_B(6);  // инвертировать бит6

"установить" значит сделать "1"
"очистить" значит сделать "0"
"инвертировать" - сделать "0" если был "1" и наоборот.

2) в CodeVision:

Код: Выделить всё
PORTB.7=0;   // сделать бит7  "0"
PORTB.5=1;   // сделать бит5  "1"
PORTB.1^=1;   // инвертировать бит1


Работает только с регистрами адрес которых меньше 31 !

3) в ImageCraft: (есть в Хелпе: "Bit Twiddling")

Код: Выделить всё
#include <macros.h>

PORTB &= ~BIT(7); // сделать бит7  "0"
PORTB |= BIT(5); // сделать бит5  "1"
PORTB ^= BIT(1); // инвертировать бит1


4) в IAR:

Код: Выделить всё
PORTB_Bit7 = 0;
PORTB_Bit5 = 1;
PORTB_Bit1 ^= 1;
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: [FAQ] Изменение и чтение отдельных битов

Сообщение megaMike » 09 сен 2010, 00:44

А почему никто не сказал о
cbi/sbi ?
megaMike
 
Сообщения: 20
Зарегистрирован: 28 авг 2010, 02:20
Откуда: Москва
прог. языки: С, С++, Lua, ActionScript

Re: [FAQ] Изменение и чтение отдельных битов

Сообщение boez » 09 сен 2010, 11:07

Потому что разговор идет о C :) Ну а вообще если компилятор нормальный, он PORTX |= (1<<bitnum) сам превратит в sbi.

некропостеры наступают ;)
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++


Вернуться в FAQ

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0