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

 
 
> Вложенные прерывания 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
Ответов
theBMV
сообщение Jan 22 2013, 06:31
Сообщение #2


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

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



Цитата(esaulenka @ Jan 16 2013, 14:28) *
Что-то я не понимаю...
По умолчанию в AIRCR поле "Interrupt priority grouping field" равно нулю. По моим соображениям, это означает, что приоритеты прерываний - это именно priority, а не subpriority. Т.е. количество вложенных прерываний может быть максимальным.

Я тоже так думал, пока у меня одно прерывание не зациклилось (с наинизшим приоритетом, между прочим) и не давало прерываниям с наивысшими приоритетами отработать.
Поэтому (PRIGROUP == 0) - это отключенная вложенность, и приоритетность прерываний ни коим образом не работает. Проверено.
А "приоритеты прерываний - это именно priority, а не subpriority" достигается, когда (PRIGROUP == 2). Table 660. Priority grouping в мануале на LPC1768.

Цитата(esaulenka @ Jan 16 2013, 18:17) *
Может, нам theBMV расскажет, что у него за компилятор? И даже стартапы все покажет? :-)

Кейл по умолчанию делает только инициализацию стеков, включает питание на периферию и настраивает PLL.
Тут, кажется, IAR, и там, может, есть настройки NVIC ?

Компилятор IAR. В стартапе указатлель на вершину стека, вектор сброса и вектора прерываний периферии с именами функций. Взят из примеров к IAR'у
CODE
/**************************************************
*
* Part one of the system initialization code, contains low-level
* initialization, plain thumb variant.
*
* Copyright 2009 IAR Systems. All rights reserved.
*
* $Revision: 33389 $
*
**************************************************/

;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbol _program_start or
; a user defined start symbol.
; To override the cstartup defined in the library, simply add your modified
; version to the workbench project.
;
; The vector table is normally located at address 0.
; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
; The name "__vector_table" has special meaning for C-SPY:
; it is where the SP start value is found, and the NVIC vector
; table register (VTOR) is initialized to this address if != 0.
;
; Cortex-M version
;

MODULE ?cstartup

;; Forward declaration of sections.
SECTION CSTACK:DATA:NOROOT(3)

SECTION .intvec:CODE:NOROOT(2)

EXTERN __iar_program_start
PUBLIC __vector_table
PUBLIC __vector_table_0x1c

DATA
__vector_table
DCD sfe(CSTACK) ; Top of Stack
DCD __iar_program_start ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
__vector_table_0x1c
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
DCD WDT_IRQHandler ; Watchdog Handler
DCD TMR0_IRQHandler ; TIMER0 Handler
DCD TMR1_IRQHandler ; TIMER1 Handler
DCD TMR2_IRQHandler ; TIMER2 Handler
DCD TMR3_IRQHandler ; TIMER3 Handler
DCD UART0_IRQHandler ; UART0 Handler
DCD UART1_IRQHandler ; UART1 Handler
DCD UART2_IRQHandler ; UART2 Handler
DCD UART3_IRQHandler ; UART3 Handler
DCD PWM1_IRQHandler ; PWM1 Handler
DCD I2C0_IRQHandler ; I2C0 Handler
DCD I2C1_IRQHandler ; I2C1 Handler
DCD I2C2_IRQHandler ; I2C2 Handler
DCD SPI_IRQHandler ; SPI Handler
DCD SSP0_IRQHandler ; SSP0 Handler
DCD SSP1_IRQHandler ; SSP1 Handler
DCD PLL0_IRQHandler ; PLL0 Handler
DCD RTC_IRQHandler ; RTC Handler
DCD EINT0_IRQHandler ; EXT Interupt 0 Handler
DCD EINT1_IRQHandler ; EXT Interupt 1 Handler
DCD EINT2_IRQHandler ; EXT Interupt 2 Handler
DCD EINT3_IRQHandler ; EXT Interupt 3 Handler
DCD ADC_IRQHandler ; ADC Handler
DCD BOD_IRQHandler ; BOD Handler
DCD USB_IRQHandler ; USB Handler
DCD CAN_IRQHandler ; CAN Handler
DCD GPDMA_IRQHandler ; General Purpose DMA Handler
DCD I2S_IRQHandler ; I2S Handler
DCD Ethernet_IRQHandler ; Ethernet Handler
DCD RIT_IRQHandler ; Repetitive Interrupt Timer Handler
DCD MotorControlPWM_IRQHandler; Motor Control PWM Handler
DCD QE_IRQHandler ; Quadrature Encoder Handler
DCD PLL1_IRQHandler ; PLL1 Handler

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;

PUBWEAK NMI_Handler
PUBWEAK HardFault_Handler
PUBWEAK MemManage_Handler
PUBWEAK BusFault_Handler
PUBWEAK UsageFault_Handler
PUBWEAK SVC_Handler
PUBWEAK DebugMon_Handler
PUBWEAK PendSV_Handler
PUBWEAK SysTick_Handler
PUBWEAK WDT_IRQHandler
PUBWEAK TMR0_IRQHandler
PUBWEAK TMR1_IRQHandler
PUBWEAK TMR2_IRQHandler
PUBWEAK TMR3_IRQHandler
PUBWEAK UART0_IRQHandler
PUBWEAK UART1_IRQHandler
PUBWEAK UART2_IRQHandler
PUBWEAK UART3_IRQHandler
PUBWEAK PWM1_IRQHandler
PUBWEAK I2C0_IRQHandler
PUBWEAK I2C1_IRQHandler
PUBWEAK I2C2_IRQHandler
PUBWEAK SPI_IRQHandler
PUBWEAK SSP0_IRQHandler
PUBWEAK SSP1_IRQHandler
PUBWEAK PLL0_IRQHandler
PUBWEAK RTC_IRQHandler
PUBWEAK EINT0_IRQHandler
PUBWEAK EINT1_IRQHandler
PUBWEAK EINT2_IRQHandler
PUBWEAK EINT3_IRQHandler
PUBWEAK ADC_IRQHandler
PUBWEAK BOD_IRQHandler
PUBWEAK USB_IRQHandler
PUBWEAK CAN_IRQHandler
PUBWEAK GPDMA_IRQHandler
PUBWEAK I2S_IRQHandler
PUBWEAK Ethernet_IRQHandler
PUBWEAK RIT_IRQHandler
PUBWEAK MotorControlPWM_IRQHandler
PUBWEAK QE_IRQHandler
PUBWEAK PLL1_IRQHandler

SECTION .text:CODE:REORDER(1)
THUMB
NMI_Handler
HardFault_Handler
MemManage_Handler
BusFault_Handler
UsageFault_Handler
SVC_Handler
DebugMon_Handler
PendSV_Handler
SysTick_Handler
WDT_IRQHandler
TMR0_IRQHandler
TMR1_IRQHandler
TMR2_IRQHandler
TMR3_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
UART2_IRQHandler
UART3_IRQHandler
PWM1_IRQHandler
I2C0_IRQHandler
I2C1_IRQHandler
I2C2_IRQHandler
SPI_IRQHandler
SSP0_IRQHandler
SSP1_IRQHandler
PLL0_IRQHandler
RTC_IRQHandler
EINT0_IRQHandler
EINT1_IRQHandler
EINT2_IRQHandler
EINT3_IRQHandler
ADC_IRQHandler
BOD_IRQHandler
USB_IRQHandler
CAN_IRQHandler
GPDMA_IRQHandler
I2S_IRQHandler
Ethernet_IRQHandler
RIT_IRQHandler
MotorControlPWM_IRQHandler
QE_IRQHandler
PLL1_IRQHandler
Default_Handler
B Default_Handler
END


Сообщение отредактировал IgorKossak - Jan 22 2013, 08:27
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post



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

 


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


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