Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С - Стивен Барретт
Шрифт:
Интервал:
Закладка:
• Бит разрешения работы модуля таймера TEN (регистр управления модулем таймера TSCR);
• Бит разрешения прерывания по переполнению счетчика временной базы TOI и биты выбора коэффициента деления программируемого делителя частоты на входе счетчика временной базы PR2:PR1:PR0 (регистр масок таймера TMSK2);
• Бит выбора режима работы канала IOSn (регистр режимов каналов захвата/сравнения TIOS). Если бит IOSn установлен в 1, то канал работает в режиме выходного сравнения;
• Биты выбора режима работы формирователя уровня канала выходного сравнения OMn:OLn (регистры управления таймером TCTL1 и TCTL2);
• Бит события в канала CnF (регистр флагов таймера TFLG1);
• Бит разрешения прерывания по событию в канале выходного сравнения CnI (регистр масок таймера TMSK1);
• Регистр данных канала TCn, код которого автоматически сравнивается с кодом счетчика временной базы. Момент равенства кодов и является событием выходного сравнения.
В тексте примера timer3.c мы будем генерировать импульсный сигнал с произвольной частотой и коэффициентом заполнения. Проанализировав текст программа Вы объясните, какую форму и какие временные параметры будет иметь формируемый сигнал.
Прежде, чем знакомиться с текстом программы timer3.c, вспомним, как оформляются подпрограммы прерывания при программировании на Си. Сначала следует убедиться, что Ваш заголовочный файл содержит определения макросов, которые позволят Вам использовать одноименные с командами ассемблера функции для запрета и разрешения прерываний в системе (см. раздел 4.12):
#define CLI() asm("clin"); //разрешить маскируемые прерывания
#define SEI() asm("sein"); //запретить маскируемые прерывания
Также следует отметить, что специфика записи подпрограммы прерывания частично определяется типом используемого компилятора. В соответствии с предварительной договоренностью, в текстах примеров этой книги используется компилятор ICC12 компании ImageСraft.
/*----------------------------------------------------------------------*/
/* filename: timer3.c */
/* МAIN PROGRAМ: Эта программа генерирует импульсную последовательность */
/* в форме меандра с использованием таймера и подсистемы прерывания */
/* Сигнал формируется на выходе 2 таймера (IC2) */
/*----------------------------------------------------------------------*/
/*подключаемые файлы*/
#include <912b32.h>
/*используемые функции*/
void initialize(void); /*функция инициализации*/
void toggle_isr(void); /*подпрограмма прерывания toggle_isr*/
//объявление функции обслуживания прерывания
#pragma interrupt_handler toggle_isr
//инициализация вектора прерывания
#pragma abs_address: 0xF7EA
void (*Timer_Channel_2_interrupt_vector[]) () = {toggle_isr};
#pragma end_abs address
/*глобальные переменные*/
int с;
void main(void) {
с = 100;
initialize(); /*инициализация подсистемы таймера*/
TMSK1 = 0х04; /*разрешение прерывания по событию в канале 2*/
TFLG1 = 0xFF; /*сброс всех флагов событий от каналов*/
CLI(); /*разрешить прерывания*/
while(1) {
/*ожидание прерывания*/
;
}
}
/*-------------------------------------------------------------*/
/* Функция initialize задает начальные установки модуля таймера*/
/*-------------------------------------------------------------*/
void initialize(void) {
TMSK2 = 0x02; /*назначить коэффициент деления 4*/
TIOS = 0х04; /*установить канал 2 в режим выходного сравнения*/
TSCR = 0х80; /*разрешить работу таймера*/
TCTL2 = 0х10; /*назначить режим формирователя уровня */
/*инвертирование*/
}
/*----------------------------------------------*/
/* Функция toggle_isr – подпрограмма прерывания */
/*----------------------------------------------*/
void toggle_isr(void) {
TFLG1 = 0xFF;
/*сброс всех флагов событий от каналов*/
ТС2 = TC2 + c;
/*задать код сравнения в регистр данных канала*/
c = c + 100;
/*вычислить новое значение c*/
}
/*-----------------------------------------------*/
Проанализируйте функцию toggle_isr. Генерацию какого импульсного сигнала она обеспечивает?
В следующем примере timer4.c показаны потенциальные возможности подсистемы выходного сравнения, обслуживаемой по прерываниям. В примере генерируются сразу две импульсные последовательности с разными частотами и коэффициентами заполнения. Нетрудно видеть, что число одновременного генерируемых импульсных сигналов может быть увеличено.
/*------------------------------------------------------------------------*/
/*filename: timer4.c */
/*МAIN PROGRAМ: Эта программа генерирует две импульсных последовательности*/
/* с использованием таймера и двух каналов подсистемы прерывания */
/* Сигналы формируются на выходах 2 и 3 таймера. */
/*------------------------------------------------------------------------*/
/*подключаемые файлы*/
#include <912b32.h>
/*используемые функции*/
void initialize(void); /*функция инициализации*/
void toggle1_isr(void); /*подпрограмма прерывания toggle1_isr*/
void toggle2_isr(void); /*подпрограмма прерывания toggle2_isr*/
//объявление функции обслуживания прерывания
#pragma interrupt_handler toggle1_isr
#pragma interrupt_handler toggle2_isr
//инициализация векторов прерывания
#pragma abs_address: 0xF7E8
void (*Timer_Channel_3_interrupt_vector[]) () = {toggle2_isr};
void (*Timer_Channel_2_interrupt_vector[]) () = {toggle1_isr};
#pragma end_abs address
void main(void) {
initialize(); /*инициализация подсистемы таймера*/
TMSK1 = 0х0C; /*разрешение прерывания по событию в каналах 2 и 3*/
TFLG1 = 0xFF; /*сброс всех флагов событий от каналов*/
CLI(); /*разрешить прерывания*/
while(l) {
/*ожидание прерывания*/
;
}
}
/*-------------------------------------------------------------*/
/* Функция initialize задает начальные установки модуля таймера*/
/*-------------------------------------------------------------*/
void initialize(void) {
TMSK2 = 0x02; /*назначить коэффициент деления 4*/
TIOS = 0х0C; /*установить каналы 2 и 3 в режим выходного*/
/*сравнения*/
TSCR = 0х80; /*разрешить работу таймера*/
TCTL2 = 0х50; /*назначить режим формирователя уровня */
/*инвертирование для обоих каналов*/
}
/*------------------------------------------------------------------*/
/* Функция toggle1_isr подпрограмма прерывания по событию в канале 2*/
/*------------------------------------------------------------------*/
void toggle1_isr(void) {
TFLG1 = 0x04; /*сброс флага события канала 2*/
ТС2 += 9091; /*задать код сравнения в регистр данных канала*/
}
/*------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/* Функция toggle2_isr подпрограмма прерывания по событию в канале 3 */
/*-------------------------------------------------------------------*/
void toggle2_isr(void) {
TFLG1 = 0x08; /*сброс флага события канала 3*/
ТС2 += 4854; /*задать код сравнения в регистр данных канала*/
}
/*-------------------------------------------------------------------*/
Проанализируйте функции toggle1_isr и toggle2_isr. Генерацию каких импульсных последовательностей они обеспечивают?
4.14.5. Счетчик событий
Счетчик событий или аккумулятор импульсов (Pulse Accumulator) — это подсистема модуля таймера, которая разработана специально для подсчета импульсов. Основной элемент счетчика событий — 16 разрядный счетчик, который может работать в двух режимах:
• Счетчик внешних событий. В этом режиме счетчик PACNT подсчитывает число событий, которое детектируется его аппаратными средствам на входе PAI. Тип события (только нарастающий или только спадающий фронт сигнала) определяется посредством программных установок.
• Стробируемый таймер. В этом режиме счетчик PACNT тактируется внутренними импульсами с частотой fBUS/64, а сигналы на входе PAI разрешают или запрещают счет.
Режимы работы счетчикаСтруктурная схема подсистемы счетчика событий представлена на рис. 4.45. Изучив ее, вы увидите, что счетчик событий в качестве входа PAI, на который должны поступать внешние импульсы, использует линию PT7 порта PORT T. Таким образом, обслуживание подсистемы счетчика событий альтернативная функция линии 7 порта PORT T. Однако линия PT7 обладает еще одной альтернативной функцией. Она используется как вход или как выход канала 7 подсистемы захвата/сравнения модуля таймера. Какие программные установки в регистрах управления таймера необходимо выполнить, чтобы конфигурировать линию PT7 как вход PAI счетчика событий?