Читаем Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С полностью

Разберем назначение отдельных элементов программы. В первой строке записана директива препроцессора компилятора #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 будет инвертирован, а содержимое программного счетчика обнулено.

Обратимся теперь к разъяснению содержимого заголовочного файла. Мы не будем приводить его текст целиком, а приведем лишь те строки, которые необходимы для рассматриваемой в основном примере программы:

1 #define _IO_BASE 0

2 #define _P(off) *(unsigned char volatile*) (_IO_BASE + off)

3 #define TSCR _Р(0х86)

4 #define TMSK2 _Р(0х8D)

5 #define TFLG2 _P(0x8F)

6 #define DDRA _Р(0х02)

7 #define PORTA _Р(0х00)

8 #define CLI asm("cli\n")

9 #define EXIT asm("swi\n")

Две первые строки приведенного фрагмента заголовочного файла используются для определения макроса _P с аргументом off. Обратите внимание на символ указателя в макросе. Все следующие выражения в строках с 3 по 7 определяют численные значения для символьных обозначений регистров специальных функций МК. Эти численные значения — адреса регистров в соответствии с картой памяти МК. Любое упоминание имен регистров в тексте программы связано с выполнением операций чтения или записи в эти регистры по их физическим адресам. Этим объясняется необходимость применения указателя в определении макроса _P(off). Две последние строки 8 и 9 являются примерами определения макросов.

Вернемся к примеру управления светодиодами. После обработки программой компилятора исходного текста программы Sample.c будет получен следующий текст программы на языке ассемблера.

1   .module interrupt.c

2   .area memory(abs)

3   .org 0xb1e

4  _Timer_Overflow_interrupt_vector::

5   .word _TOIISR

6   .area data

7  _second::

8   .blkb 1

9   .area idata

10 .byte 0

11 .area data

12  .area text _main::

14 ; void TOIISR(void);

15 ; #pragma interrupt_handler TOIISR ;

16 ; #pragma abs_address:0x0B1E

17 ; void (*Timer_Overflow_interrupt_vector[]) ={TOIISR};

18 ; #pragma end_abs_address ;

19 ; unsigned char second=0x00;

20 ;

21 ;void main(void)

22 ;{

23 ; TSCR=0x80;

24  ldab #128

25  stab 0х86

26 ; ТМSК2=0х80;

27  ldab #128

28  stab 0x8d

29 ; TFLG2=0x80;

30  ldab #128

31  stab 0x8f

32 ; DDRA=0xFF;

33  ldab #255

34  stab 0х2

35 ; CLI;

36  сli

37 L3: L4:

38  bra L3

39 X0:

40 ; while(1) {};

41 ; EXIT;

42  swi

43 ; }L2

44 .dbline 0

45 ; func end

46  rts

47 _TOIISR: :

48  void TOIISR(void)

49 ; {

50 ; TFLG2=0x80;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже