Программирование микропроцессорных систем в интегрированной среде программирования keil-c: Методические указания к лабораторным работам, страница 14

В этом примере для объединения бит в одно число использована операция логического суммирования, а для указания номера бита – сдвиг единицы влево на необходимое число разрядов.

Если в операции присутствуют только константы, то компилятор вычислит число, соответствующее результату этой операции и в операторе присваивания будет работать именно с этим числом.

Запись нуля производится операцией логической И, как это показано в следующем примере:

Port2 &= ~(1|(1<<5)|(1<<3));  //Записать логический ноль в нулевой, третий и пятый биты порта

Операция инвертирования ~ в данном примере применяется, так как сброс бита в ноль производится операцией логического умножения с нулём.

А теперь посмотрим, как должны объявляться переменные, соответствующие параллельным портам процессора. Для объявления переменных с адресами регистров специальных функций, применяется расширения языка программирования С. Для объявления переменных в этом адресном пространстве используется зарезервированное слово sfr или sfr16. Например:

sfr   P0        = 0x80;  //порт p0 расположен по адресу 080h

sfr   P2        = 0xA0;  //порт p2 расположен по адресу 0a0h

Точно так же можно объявлять битовые переменные, соответствующие отдельным битам этих портов при помощи зарезервированного слова sbit:

sbit  TF1       = 0x8F;  //Флаг переполнения таймера T1

sbit  TR1       = 0x8E; //Флаг включения таймера T1

Но это полезно для описания процессоров, неизвестных языку программирования keil-C. Для описания большинства процессоров достаточно подключить готовый файл описания микроконтроллера при помощи директивы include:

#include "ADuC812.h"

Использование готовых файлов описания микроконтроллеров позволяет избежать ошибок в описании регистров специальных функций. Кроме того, это позволяет для описания микроконтроллера обойтись одной строкой.

В учебном стенде SDK-1.1 светодиоды подключены к параллельному порту, расположенному в восьмой странице внешней памяти по адресу 0x0007. Для доступа к этой ячейке памяти можно воспользоваться объявлением, которое  используется в обычном языке C для доступа к конкретным ячейкам памяти:

#define SvDiod   *(volatile unsigned char xdata *)7

Здесь объявляется однобайтовая ячейка памяти (unsigned char), доступ к которой возможен через указатель данных DPTR (после объявления типа переменной использован символ ‘*’). То, что эта ячейка памяти находится во внешней памяти данных показывает уточняющее слово “xdata”, отсутствующее в стандартном языке программирования C. Для того, чтобы объявленная переменная не могла быть уничтожена оптимизатором языка программирования, к объявлению типа переменной добавляется зарезервированное слово volatile.

Для переключения страниц в микроконтроллере используется регистр расширения DPP. Переключить страницы можно оператором присваивания:

DPP=8;         //Переключиться на страницу 0x80000

Эту константу можно было бы занести цифрой, но при развитии программы эта константа может быть использована в нескольких местах. При очередном изменении принципиальной схемы аппаратуры может измениться расположение порта в адресном пространстве микроконтроллера и поэтому лучше объявить константу при помощи директивы #define в одном месте:

#define ParPort 0x8              //Определить константу переключения на 8 страницу памяти

Если теперь придётся изменять программу в связи с изменением аппаратуры, то достаточно будет изменить её в одном месте. Кроме того, в имени константы может быть заложена функция, которая выполняется этой константой. Применение константы с таким именем повышает понятность программы.

После завершения работы программы на универсальном компьютере управление передаётся операционной системе. В микроконтроллере управление безраздельно принадлежит программисту, поэтому необходимо обеспечить, чтобы управление не попало в область памяти, где находятся данные, или ещё хуже где нет никакой памяти. Чтобы этого не произошло в конце программы необходимо разместить оператор бесконечного цикла. Для этого можно воспользоваться строкой: