реклама на сайте
подробности

 
 
> Вложенные прерывания Cortex M3 (LPC1768), не выполняются
theBMV
сообщение Dec 28 2012, 07:34
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 14-10-08
Из: г. Королев
Пользователь №: 40 940



Здравствуйте, уважаемые!
Пишу реализацию ПИД-регулятора. МК LPC1768
Период перерасчета должен быть соблюден крайне точно, поэтому использую прерывания по таймеру и устанавливаю этому прерыванию наивысший приоритет.
CODE
void init_tmr1()
{
T1TCR_bit.CR = 1; // Сбрасываем
T1TCR_bit.CR = 0;
/*
Fp = 25 МГц Частота периферии.
T = 20 мс Желаемый период таймера.
N = Fp/T Формула рачета кол-ва тактов за период.
N = 250000 Кол-во тактов за желаемый период таймера.
*/
T1MR0 = 250000; // Загружаем регистр сравнения
T1MCR_bit.MR0I = 1; // Разрешаем прерывание по совпадению MR0
T1MCR_bit.MR0R = 1; // Разрешаем сброс таймера по совпадению MR0
T1TCR_bit.CE = 1; // Разрешаем счет

IP0_bit.PRI_2 = 0; // Приоритет прерывания: наивысший (0)
SETENA0_bit.SETENA2 = 1; // Разрешаем прерывания в NVIC
}


Далее в обработчике прерываний от этого таймера есть получение данных с абсолютного датчика положения.
Опрос датчика производится из прерывания таймера 1 раз за прерывания,
поэтому на осциллографе я наблюдаю пакеты опроса датчика строго с частотой таймера.
Ок.
Теперь инициализирую UART для приема управляющего воздействия (DMX512)
CODE
PCONP_bit.PCUART3 = 1;

FIO3DIR_bit.P3_26 = 1;
FIO3CLR = 1 << 26;

PINSEL0_bit.P0_0 = 2;
PINSEL0_bit.P0_1 = 2;

// Скорость
/*
F = Fp/(16*(DLM*256+DLL)*(1+DIV/MUL))
F = 250 kBod
Fp = 100 MHz
DLM = 0
DLL = 25
DIV = 0
MUL = 1
*/
U3LCR_bit.DLAB = 1;
U3DLL = 25;
U3DLM = 0;
U3LCR_bit.DLAB = 0;

// FIFO
U3FCR_bit.FCRFE = 1; // Включаем FIFO
U3FCR_bit.RFR = 1; // Сбрасываем RxFIFO
U3FCR_bit.TFR = 1; // Сбрасываем TxFIFO
U3FCR_bit.RTLS = 2; // Порог срабатывания 8 символов

// Формат
U3LCR_bit.WLS = 3; // 8 бит
U3LCR_bit.SBS = 1; // 2 стоп-бита

// Преывания
U3IER_bit.RDAIE = 1; // Разрешаем прерывание по входящим данным
U3IER_bit.RXLSIE = 1; // Разрешаем прерывание по статусу линии

IP2_bit.PRI_8 = 2; // Приоритет прерывания: средний (2)
SETENA0_bit.SETENA8 = 1; // Разрешаем в NVIC
}

И в обработчике прерываний уже непосредственно получение данных из FIFO.
Итак: приоритет таймера - 0, приоритет UART - 2. Но когда по UART приходят данные период таймера нарушается и становится вообще не понятно каким.
То есть вложенные прерывания не выполняются? Как это исправить?

А если в процессе приема данных по UART отключить источник сигнала, то программа из прерывания UART вообще не выходит и прерывания таймера не выполняются вообще!
Вот обработчик UART
CODE
void UART3_IRQHandler()
{
char uiir, ulsr, urbr;

do
{
uiir = U3IIR;
ulsr = U3LSR;

if((uiir & INTID) == RLS)
{
if(ulsr & (OE | PE))
bDMX = 0;
if(ulsr & BI)
{
nDMX = 0;
bDMX = 1;
}
U3RBR;
}
if((uiir & INTID) == RDA)
{
urbr = U3RBR;
if(nDMX && bDMX && (nDMX < 513))
DMX[(nDMX++)-1] = urbr;
else
if(!(nDMX++) && urbr)
bDMX = 0;
}
}
while(!(uiir & INTPEND));

CLRPEND0_bit.CLRPEND8 = 1;
}


Сообщение отредактировал IgorKossak - Dec 28 2012, 08:15
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!, форматирование
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SSerge
сообщение Dec 28 2012, 09:05
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



А что с регистром AIRCR и полем PRIGROUP в нём?
Там у кортексов настраиваются группы приоритетов.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
theBMV
сообщение Dec 28 2012, 09:36
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 14-10-08
Из: г. Королев
Пользователь №: 40 940



Цитата(SSerge @ Dec 28 2012, 13:05) *
А что с регистром AIRCR и полем PRIGROUP в нём?
Там у кортексов настраиваются группы приоритетов.

Не пойму, о каких регистрах идет речь?
В мануале описаны следующие регистры, относящиеся к NVIC:
ISER0 - ISER3 RW Set-Enabe Разрешение прерывания
ICER0 - ICER3 RW Clear-Enable Запрет прерывания
ISPR0 - ISPR3 RW Set-Pending Установка ожидания (обработки)
ICPR0 - ICPR3 RWClear-Pending Снятие ожидания (обработки)
IABR0 - IABR3 RO Active Bit Состояние текущих прерываний (только чтение)
IPR0 - IPR27 RW Priority Установка приоритетов
STIR WO Software Trigger Программные прерывания

У меня в конце каждой функции инициализации периферии стоит установка приоритета и разрешение прерывания. А в конце каждого обработчика снятие ожидания.
Повторюсь: у таймера приоритет - 0, у UART'а - 2. Только почему-то из обработчика UART при возникновении прерывания по таймеру с высшим приоритетом перехода к его обработчику не происходит никогда.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Dec 28 2012, 10:12
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(theBMV @ Dec 28 2012, 10:36) *
У меня в конце каждой функции инициализации периферии стоит установка приоритета и разрешение прерывания. А в конце каждого обработчика снятие ожидания.
Повторюсь: у таймера приоритет - 0, у UART'а - 2. Только почему-то из обработчика UART при возникновении прерывания по таймеру с высшим приоритетом перехода к его обработчику не происходит никогда.

По умолчанию контроллер прерываний не настроен на вложенные прерывания. Для большинства случаев (до 16-ти уровней приоритетов и 16 подгрупп) подойдет вызов NVIC_SetPriorityGrouping(0x03) при инициализации приложения. Функция объявлена и реализована в core_cm3.h (но включать этот заголовок явно не надо, т.к. он включается через аппаратно-зависимый заголовок процессора).
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Jan 16 2013, 10:28
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(KnightIgor @ Dec 28 2012, 14:12) *
По умолчанию контроллер прерываний не настроен на вложенные прерывания.


Что-то я не понимаю...
По умолчанию в AIRCR поле "Interrupt priority grouping field" равно нулю. По моим соображениям, это означает, что приоритеты прерываний - это именно priority, а не subpriority. Т.е. количество вложенных прерываний может быть максимальным.

Ссылку на infocenter.arm.com дать не могу - никак не найду, где её там взять :-)

На железе, правда, все свои соображения проверить поленился: у меня критичное к времени старта прерывание ровно одно, оно же - самое длительное. Остальные прерывания быстрые, и особо не влияют. Пока, во всяком случае...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 02:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01405 секунд с 7
ELECTRONIX ©2004-2016