Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка ПО на языке Си для микроконтроллера AT91SAM7S.pdf
Скачиваний:
120
Добавлен:
18.05.2014
Размер:
838.69 Кб
Скачать

6Логические операции

Си поддерживает два вида логических операций:

-обычные логические операции, выполняемые над булевым операндами;

-побитовые логические операции.

Обычные логические операции применяются к одному или двумя булевым операндам, результат имеет булев тип. Допускается применение логических операций с операндами целочисленных типов и даже с указателями, поскольку любые целочисленные переменные при необходимости автоматически неявно преобразуются к типу bool по следующему правилу: любое ненулевое значение переменной (или ненулевой указатель) преобразуется в true, а нулевое – в false. Обычные логические операции, наряду с операторами сравнения (см. раздел 8) используются для формирования булевых признаков, которые затем проверяются с помощью операторов условий (см. раздел 7) для управления ходом выполнения программы.

Побитовые логические операции работают с целочисленными типами. Результат также является целым числом и каждый его бит определяется результатом выполнения логической операции над соответствующими битами операндов (см. рис. 1). Являясь средством выполнения манипуляций с битами (установка, сброс, проверка значения), они широко применяются при работе с регистрами ввода-вывода, отражёнными в память.

Логические операторы, используемые в языке приведены в табл. 5; примеры применения логических операций приведены в листингах 13 и 14.

Таблица 5. Логические операции

 

 

Логические операции

Побитовые логические

Лог. операция

Количество

 

 

операции

 

операндов

 

 

 

 

 

Оператор

Пример

Оператор

Пример

 

 

 

 

 

выражения

 

выражения

 

 

 

 

 

 

И

2

&&

a && b

&

a & b

 

 

 

 

 

 

ИЛИ

2

||

c || d

|

c | d

 

 

 

 

 

 

НЕ

1

!

!e

~

~e

 

 

 

 

 

 

ИСКЛ. ИЛИ

2

(отсутствует)

 

^

f ^ g

 

 

 

 

 

 

25

0x5a

01011010

&

&

0x3c

00111100

=

=

0x18

00011000

Рисунок 1: Пояснение принципа работы побитовых логических операций

Листинг 13. Примеры применения логических операций

//Подключение заголовочного файла, в котором определён тип bool #include <stdbool.h>

//«И»

//velocityOk будет равно true, если velocity лежит в интервале от 20,5 до 62,7 // (не включая границы), и равно false в противном случае.

bool velocityOk = (velocity > 20.5) && (velocity < 62.7);

//«ИЛИ»

//ready будет равно true, если velocityOk равно true или temperature

//превышает 50.0

//bool ready = velocityOk || (temperature > 50.0);

//«НЕ»

//notReady будет равно true, если ready равно false и наоборот

//bool notReady = !ready;

Листинг 14. Пример использования побитовых логических операций

// Пример использования побитовых операций.

//Нумерация битов идёт с 0. int regValue = getRegValue();

//Установка бита #3 с использованием побитового «ИЛИ» regValue = regValue | 0x08; // 0x08 = 0b00001000

//Сброс битов #6 и #7 с использованием побитовых «И» и «НЕ»

regValue = regValue & ~0x40; // ~0x40 = ~0b 1100 0000 = 0b 0011 1111

//Проверка, установлен ли бит #9

//bool bit9Set = regValue & 0x0200; // 0x0200 = 0b 0000 0010 0000 0000

setRegValue(regValue);

26

Поскольку минимальной адресуемой единицей памяти является байт, строго говоря, независимое изменение (установка или сброс) произвольных битов внутри байта невозможно – возможно только изменение байта (или группы байтов) целиком. Поэтому, если требуется изменить конкретные биты ячейки памяти без затрагивания других битов, необходимо сначала получить значение данной ячейки, изменить нужные биты с помощью побитовых логических операций, а затем записать новое значение ячейки памяти.

Однако при работе с микроконтроллером AT91SAM7S, необходимо помнить, что не все регистры ввода-вывода поддерживают режим доступа на чтение и запись – некоторые рассчитаны только на запись или только на чтение5.

В регистр, рассчитанный только на запись, возможно только записать новое значение, т. е. новый набор битов целиком. Производить чтение из такого регистра нельзя, поэтому, если по ходу работы программы требуется модифицировать отдельные биты в таком регистре, то следует создать переменную-копию этого регистра в оперативной памяти, чтобы с ней производить битовые операции. После каждого изменения её значение должно записываться в регистр (присваиванием). Такая переменная должна сохранять своё значение между модификациями битов регистра.

5В документации к микроконтроллеру эта характеристика обозначается как «Access type» (режим доступа).

27

7Условия

Условные операторы (также называемые операторами управления потоком

выполнения) – это механизм, позволяющий определять ход выполнения программы в зависимости от заданных условий.

Существуют следующие условные операторы – if («если»), else («иначе»), а также else if («иначе, если»). Операторы «else» и «else if» могут быть использованы только совместно с оператором if.

Синтаксис условных операторов и примеры использования приведены в листинге 15.

Листинг 15. Синтаксис условных операторов и примеры применения

//Синтаксис конструкций с условными операторами

//if (условие1)

//

{блок_1}

_

// else if (условие_2)

\

//

{блок_2}

|

// …

 

\___ необязательная часть

// else if (условие_N)

/

//

{блок N}

|

// else

|

//

{блок кода}

_/

//

 

 

//Получить код нажатой кнопки (прототип функции).

//Возвращаемые значения:

//0 – никакая кнопка не нажата, 1 – кнопка «старт»,

//2 - «стоп», 3 - «пауза»

int getButtonPressed();

int main ()

{

int buttonCode = getButtonPressed();

//Здесь используется оператор проверки на равенство «==», подробнее

//см. раздел 8.

if (buttonCode == 1)

{

// Этот блок выполнится, если была нажата кнопка «старт»

}

//Если кнопка старт не была нажата (т. е. buttonCode не равно 1),

//проверяем, не была ли нажата ли кнопка «стоп»

28

else if (buttonCode == 2)

{

//Этот блок выполнится, если нажата кнопка «стоп»,

//но не нажата «старт»

}

else if (buttonCode == 0)

{ // Этот блок выполнится, если никакая кнопка не была нажата

}

else

{

//Этот блок выполнится, если не выполнится ни одно из предыдущих

//условий. Возможно была нажата какая-то другая кнопка?

}

}

Так же, как и с логическими операциями, выражения, стоящие в круглых скобках у условных операторов, должны иметь булев тип, либо должны преобразовываться в булев тип.

29