![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Генерация импульсной последовательности с использованием прерывания
Цель рассматриваемого примера (timer3.c) — познакомить читателя с техникой генерации импульсных сигналов с использованием подсистемы выходного сравнения, перезагрузка регистра данных которой реализуется в подпрограмме прерывания по очередному событию в канале выходного сравнения. Ниже перечислены биты и регистры управления, которые используются в данном примере: • Бит разрешения работы модуля таймера 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(" cli\n"); //разрешить маскируемые прерывания #define SEI() asm(" sei\n"); //запретить маскируемые прерывания Также следует отметить, что специфика записи подпрограммы прерывания частично определяется типом используемого компилятора. В соответствии с предварительной договоренностью, в текстах примеров этой книги используется компилятор 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. Генерацию каких импульсных последовательностей они обеспечивают?
|