TMS320 для начинающих: Прерывания в контроллерах tms320 C2000

В микроконтроллере tms320f28027, который установлен на c2000-launchpad 14 линий прерывания ядра. Эти линии могут быть отключены глобальным ключом INTM, соответствующим ключом из набора регистра IER и замаскированы при помощи регистра IFR.

С этим в Техасе ничего нового не изобрели. Эта структура сложилась уже давно и представить что-то другой довольно сложно.
Но четырнадцати прерываний слишком мало. Поэтому в контроллерах tms320 есть блок расширения источников прерываний PIE.

Благодаря ему доступно 12 групп по 8 прерываний в каждой, т.е. 96 источников прерываний. 12 линий прерываний ядра расширены при помощи PIE, а INT13 и INT14 обходят PIE и подключены на прямую к ядру.
По сути PIE – навороченный мультиплексор. Мы настраиваем блок PIE и указываем контроллеру какой источник из периферии контроллера использовать для данной линии прерывания ядра.

Что же нужно сделать для инициализации прерывания?
1. Разрешить прерывания при помощи ключа INTM
2. Разрешить прерывание при помощи регистра IER
3. Включить и настроить блок PIE
4. Настроить блок XINT

Последний пункт применяется для настройки прерываний от ножек контроллера.

Давайте рассмотрим процесс настройки прерываний от ножки с2000-launchpad присоединённой к пользовательской кнопке.
После включения контроллера необходимо отключить сторожевой таймер (мы его использовать не будем), сбросить регистры флагов прерываний и отключить все прерывания.

         // инициализируе систему: PLL, WatchDog
         InitSysCtrl();
         // очищаем прерывания и инициализируем таблицу векторов PIE, очищаем прерывания ЦПУ
         DINT;
         // Инициализируем регистры PIE в их состояние по умолчанию
         // Состояние по умолчанию - все PIE прерывания выключены и флаги очищены
         InitPieCtrl();
         // Выключаем CPU прерывания и чистим все флаги
         IER = 0x0000;
         IFR = 0x0000;

После этого инициализировать таблицу векторов прерываний:

         // Инициализируем таблицу векторов PIE указателями на обработчики прерываний
         InitPieVectTable();

В данном примере я опишу прерывание от ножки GPIO12 через XINT1.
Настроим блок PIE для обработки прерывания XINT1 (внешнее прерывание 1).
Смотрим в таблице мультиплексированных векторов прерываний с.104 в описании GPIO от TI группу и подгруппу для данного прерывания.

Т.е. нам нужна 1 группа и 4 подгруппа PIE.
Настраиваем PIE:

         // настраиваем блок PIE для XINT1
         PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Включаем блок PIE
         PieCtrlRegs.PIEIER1.bit.INTx4= 1;  // Включаем в группе 1 PIE - INTx4

Как видно из документации для включения прерывания в определенной группе необходимо просто выставить соответствующий бит в регистре PIEIER.

Теперь укажем функцию обработчик прерывания:

         // указываем функцию - обработчик прерывания
         EALLOW;
         PieVectTable.XINT1 = &xint1_isr;
         EDIS;

Далее разрешаем линию прерываний 1 и замыкаем ключ INTM.

         IER |= M_INT1;                 // Разрешаем прерывание ядра по линии 1
         EINT;                  // Разрешаем прерывания глобально

Устанавливаем нулевой бит (INT1) в единицу для разрешения прерывания по линии 1.

Настроим светодиод на GPIO1 как выход, а кнопку на GPIO12 как вход:

         // GPIO1 настраиваем как выход
         EALLOW;
         GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // GPIO1
         GpioCtrlRegs.GPAPUD.all = 0;            // подтяжка включена на всем порту, иначе из-за наводок горят соседние диоды.
         GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;  // выход
         EDIS;


         // GPIO12 настраиваем как вход
         EALLOW;
         GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;      // GPIO12
         GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1;       // подтяжка выключена
         GpioCtrlRegs.GPADIR.bit.GPIO12 = 0;       // вход
         GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2;     // 6 семплов
         GpioCtrlRegs.GPACTRL.bit.QUALPRD2 = 0xFF; // максимальный период семплов GPIO12
         EDIS;

Настраиваем источником XINT1 кнопку на GPIO12:

         // GPIO12 настраиваем как источник XINT1
         EALLOW;
         GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 12; // Выбираем GPIO12 для Xint1
         EDIS;

         XIntruptRegs.XINT1CR.bit.POLARITY = 2; // срабатывает по заднему фронту
         XIntruptRegs.XINT1CR.bit.ENABLE = 1;   // Включаем XINT1

Поле POLARITY отвечает за событие генерирования прерывания. Прерывание может быть сгенерировано по переднему, заднему фронту или по обоим.

После данных настроек все готово для обработки прерываний с кнопки.
Будем менять состояние светодиода при каждом прерывании с кнопки:

interrupt void xint1_isr(void)
{
         GpioDataRegs.GPATOGGLE.bit.GPIO1 = 1;
         // указываем что обработали прерывание
         PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

Записываем 1 в регистр PIEACK. Этим мы очистим бит и разрешим в PIE обработку следующего прерывания.

Скачать проект.

Документация:
TMS320 System Control and Interrupts

 

Похожий код:

Фото аватара
Алексей Петров

Программист, разработчик с 5 летним опытом работы. Учусь на разработчика игр на Unity и разработчика VR&AR реальности (виртуальной реальности). Основные языки программирования: C#, C++.

Оцените автора
Бла, бла код
Добавить комментарий