STM32F100C4T6 проблема с NVIC

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Мудрый кот
Аватара пользователя
Сообщения: 1733
Зарегистрирован: Чт авг 21, 2008 22:03:30
Откуда: Одесса(Украина)

Сообщение РадиоЛоматель »

Добрый день!
У меня такая проблема: при первой после перепрошивки попытке записать 0x10000000 в ISER[0] контроллер перезапускается. После этого его ничем не пронять, кроме повторной прошивки. Смотрел регистры - ничего лишнего не установлено. Все работало, как надо. Но после очередного перезапуска отладки (даже без перепрошивки) контроллер перестал подавать признаки жизни. Работает адекватно до момента включения NVIC. Может кто сталкивался с таким? Я даже не знаю, в какую сторону бежать.
(*tmp) &= ~( ( (param1 & (1<<PARAM1_BIT6)) || ((param2==PARAM2_TRUE)&&(--param3)) ) ? (param1 & (~param2)) : (Func1() | FUNC1_FLAGS) );
Люблю Си...
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение 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            
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1733
Зарегистрирован: Чт авг 21, 2008 22:03:30
Откуда: Одесса(Украина)

Сообщение РадиоЛоматель »

Нет, я включаю осознанно существующее прерывание от таймера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);
  }
}
(*tmp) &= ~( ( (param1 & (1<<PARAM1_BIT6)) || ((param2==PARAM2_TRUE)&&(--param3)) ) ? (param1 & (~param2)) : (Func1() | FUNC1_FLAGS) );
Люблю Си...
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

В SPL черт ногу сломит .
Но в SPL примерах приоритет выставляется такой :

Код: Выделить всё

 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
Попробуй ...
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Аватара пользователя
Сообщения: 1733
Зарегистрирован: Чт авг 21, 2008 22:03:30
Откуда: Одесса(Украина)

Сообщение РадиоЛоматель »

Проблема разрешилась сама собой. Не сказал бы, что это меня радует, но все же, лучше, чем ничего. Возможно, что это связанно с тем, что включение тактовых частот я распределил по местам инициализации соответствующей периферии, вместо того, чтобы включать их в начале программы. На это пошел из-за того, что в новом проекте прерывания заработали совершенно безболезненно.
(*tmp) &= ~( ( (param1 & (1<<PARAM1_BIT6)) || ((param2==PARAM2_TRUE)&&(--param3)) ) ? (param1 & (~param2)) : (Func1() | FUNC1_FLAGS) );
Люблю Си...
Контактная информация:
Реклама
Ответить

Вернуться в «ARM»