Страница 1 из 1
STM32F100C4T6 проблема с NVIC
Добавлено: Сб дек 07, 2013 02:16:21
РадиоЛоматель
Добрый день!
У меня такая проблема: при первой после перепрошивки попытке записать 0x10000000 в ISER[0] контроллер перезапускается. После этого его ничем не пронять, кроме повторной прошивки. Смотрел регистры - ничего лишнего не установлено. Все работало, как надо. Но после очередного перезапуска отладки (даже без перепрошивки) контроллер перестал подавать признаки жизни. Работает адекватно до момента включения NVIC. Может кто сталкивался с таким? Я даже не знаю, в какую сторону бежать.
Re: STM32F100C4T6 проблема с NVIC
Добавлено: Сб дек 07, 2013 08:58:42
dosikus
РадиоЛоматель писал(а):
при попытке записать 0x10000000 в ISER[0] контроллер перезапускается.
Это что то осознанное или просто метод тыка ?
Возможно, тыркаясь, Вы включаете несуществующие прерывание или что еще хуже исключения , со всеми вытекающими .
Изучите как это происходит в CMSIS :
Код: Выделить всё
/** \brief Enable External Interrupt
The function enables a device-specific interrupt in the NVIC interrupt controller.
\param [in] IRQn External interrupt number. Value cannot be negative.
*/
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
}
Где тип
IRQn_Type описанный в хэдере
stm32f10x.h :
Спойлер
Код: Выделить всё
typedef enum IRQn
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** STM32 specific Interrupt Numbers *********************************************************/
WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */
PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */
TAMPER_IRQn = 2, /*!< Tamper Interrupt */
RTC_IRQn = 3, /*!< RTC global Interrupt */
FLASH_IRQn = 4, /*!< FLASH global Interrupt */
RCC_IRQn = 5, /*!< RCC global Interrupt */
EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */
EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */
EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */
EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */
EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */
DMA1_Channel1_IRQn = 11, /*!< DMA1 Channel 1 global Interrupt */
DMA1_Channel2_IRQn = 12, /*!< DMA1 Channel 2 global Interrupt */
DMA1_Channel3_IRQn = 13, /*!< DMA1 Channel 3 global Interrupt */
DMA1_Channel4_IRQn = 14, /*!< DMA1 Channel 4 global Interrupt */
DMA1_Channel5_IRQn = 15, /*!< DMA1 Channel 5 global Interrupt */
DMA1_Channel6_IRQn = 16, /*!< DMA1 Channel 6 global Interrupt */
DMA1_Channel7_IRQn = 17, /*!< DMA1 Channel 7 global Interrupt */
#ifdef STM32F10X_LD
ADC1_2_IRQn
Re: STM32F100C4T6 проблема с NVIC
Добавлено: Сб дек 07, 2013 20:58:06
РадиоЛоматель
Нет, я включаю осознанно существующее прерывание от таймера2 с помощью как раз этой самой CMSIS.
Я, конечно, не считаю себя прям таким уж супер программистом, но все-таки писать в случайные регистры случайные значения я бы не стал.
Похоже, придётся ставить новый контроллер. Хотя, еще проверю на discovery и другой проект на этом.
А, ну и чтоб совсем развеять все сомнения, вот:
Спойлер
Код: Выделить всё
void Timers_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//TIM_OCInitTypeDef TIM_OCInitStructure;
timecount = 0;
RCC_PCLK1Config(RCC_HCLK_Div1);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 1000;
TIM_TimeBaseStructure.TIM_Prescaler = 24-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Output Compare Active Mode configuration: Channel1 */
/*TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);*/
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); <----------------------------- Вот тут умирает
TIM_Cmd(TIM2, ENABLE);
}
И плюс конкретное место, где это в CMSIS находится. (Хотя на самом деле это не cmsis, а STM32F10x_StdPeriph_Driver)
Спойлер
STM32F10x_StdPeriph_Driver\src\misc.c
Код: Выделить всё
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
{
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;
tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;
NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
/* Enable the Selected IRQ Channels --------------------------------------*/
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F); <----------------------------- Вот тут умирает
}
else
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
}
Re: STM32F100C4T6 проблема с NVIC
Добавлено: Сб дек 07, 2013 22:07:33
dosikus
В SPL черт ногу сломит .
Но в SPL примерах приоритет выставляется такой :
Код: Выделить всё
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
Попробуй ...
Re: STM32F100C4T6 проблема с NVIC
Добавлено: Сб дек 07, 2013 23:52:51
РадиоЛоматель
Проблема разрешилась сама собой. Не сказал бы, что это меня радует, но все же, лучше, чем ничего. Возможно, что это связанно с тем, что включение тактовых частот я распределил по местам инициализации соответствующей периферии, вместо того, чтобы включать их в начале программы. На это пошел из-за того, что в новом проекте прерывания заработали совершенно безболезненно.