В представленном примере прикладная программа управляет светодиодами, подключенными к выходам порта PORTA микроконтроллера 68HC12B32. Периодически, по первому сигналу переполнения таймера светодиоды зажигаются, а последующему сигналу переполнения таймера эти светодиоды гасятся. Аппаратные средства, используемые для отладки этой задачи, представлены на рис. 3.11.
Рис. 3.11. Схема подключения светодиодов к микроконтроллеру 68HC912B32
/************************************************************/
/* Название: Sample.c */
/* Описание: Эта программа производит включение */
/* и выключение светодиодов с интервалом */
/* времени 1 с. Используется МК 68НС12ВЗ2 */
/* Файл заголовка header содержит адреса всех */
/* портов и регистров специальных функций */
/* Контроллер должен быть сконфигурирован */
/* для работы в однокристальном режиме */
/* Дата создания: May 15, 2004 */
/* Авторы: Daniel Pack and Steve Barrett */
/************************************************************/
1 #include <68НС12ВЗ2.h>
2 /*****************************************************/
3 void TOIISR(void);
4 /*****************************************************/
5 #pragma interrupt_handler TOIISR() /* Объявление подпрограммы
6 прерывания по переполнению таймера*/
7 #pragma abs_address:0x0B1E /*задать адрес подпрограммы прерывания ISR */
8 void (* Timer_Overflow_interrupt_vector[])()={TOIISR}
9 #pragma end_abs_address
10 unsigned char second = 0x00;
11 void main (void)
12 {
13 TSCR=0x80; /*включить таймер*/
14 TMSK2=0x80; /*разрешить прерывания по таймеру*/
15 TFLG2=0x80; /*очистить флаг TOIF*/
16 DDRA=0xFF; /* настроить порт Port A на вывод*/
17 CLI(); /*разрешить прерывания*/
19 EXIT()
20 }
21
22 void TOIISR(void) /*подпрограмма прерывания*/
23 {
24 TFLG2=0x80; /*очистить флаг TOIF*/
25 second += 1; /*увеличить на 1 программный счетчик с именем second*/
26 if (second == 122)
27 {
28 PORTA = !PORTA; /*инвертировать порт PORT A*/
29 second = 0x00; /*обнулить программный счетчик*/
30 }
31 }
Обратите внимание! Каждая программа должна обязательно иметь заголовок, в котором прописаны: название программы, краткое описание реализуемого алгоритма, авторы и дата создания программы. Файл заголовка 68HC12B32.h содержит определения регистров специальных функций МК B32 и макроопределения для препроцессора компилятора. Номера строк в приведенном тексте программы при вводе исходного текста в редакторе интегрированной среды ICC12 не должны присутствовать. Это наше дополнение для удобства восприятия материала.
Разберем назначение отдельных элементов программы. В первой строке записана директива препроцессора компилятора #include, которая предписывает присоединить к программе заголовочный файл с именем 68НС12ВЗ2.h. Содержимое этого файла мы рассмотрим ниже. Строка 3 содержит объявление функции TOIISR как подпрограммы прерывания по переполнению таймера. Строки с пятой по девятую содержат директивы, которые назначают ячейку памяти с адресом 0x0B1E для размещения в ней адреса начала подпрограммы прерывания TOIISR. В строке 10 осуществляется определение и инициализация глобальной переменной с именем second, которая будет использоваться в качестве программного счетчика. Строки с одиннадцатой по двадцатую содержат текст основной программы, в которой происходит инициализация подсистемы таймера. Таймер запускается на счет, разрешаются прерывания по его переполнению. Обратите внимание, в строке 17 вызывается макрос разрешения прерывания, который был определен в заголовочном файле. Строка 18 содержит конструкцию бесконечного цикла, который обеспечивает выполнение пустых команд микроконтроллером, пока не поступит запрос на прерывание от таймера. В строке 19 записан макрос программного прерывания EXIT(), который также определен в заголовочной файле. В строке 22 начинается подпрограмма прерывания по таймеру. В ней сбрасывается флаг переполнения таймера (строка 24), а затем инкрементируется программный счетчик second (строка 25). Заметим, что период счета 16 разрядного счетчика таймера микроконтроллера 68HC12 при частоте шины 8 МГц составляет 8,19 мс. Поэтому для отсчета 1 с требуется 122 периода переполнения этого таймера. В строке 26 записана конструкция условия if. Выражения строк 28 и 29 будут исполняться, только если счетчик second достиг значения 122. Тогда код на линиях PORTA будет инвертирован, а содержимое программного счетчика обнулено.