В этом примере для объединения бит в одно число использована операция логического суммирования, а для указания номера бита – сдвиг единицы влево на необходимое число разрядов.
Если в операции присутствуют только константы, то компилятор вычислит число, соответствующее результату этой операции и в операторе присваивания будет работать именно с этим числом.
Запись нуля производится операцией логической И, как это показано в следующем примере:
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 страницу памяти
Если теперь придётся изменять программу в связи с изменением аппаратуры, то достаточно будет изменить её в одном месте. Кроме того, в имени константы может быть заложена функция, которая выполняется этой константой. Применение константы с таким именем повышает понятность программы.
После завершения работы программы на универсальном компьютере управление передаётся операционной системе. В микроконтроллере управление безраздельно принадлежит программисту, поэтому необходимо обеспечить, чтобы управление не попало в область памяти, где находятся данные, или ещё хуже где нет никакой памяти. Чтобы этого не произошло в конце программы необходимо разместить оператор бесконечного цикла. Для этого можно воспользоваться строкой:
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.