2016-11-30 3 views
0

Моя цель состоит в том, чтобы иметь 38kHz прерывания и переключения светодиод, но независимо от того, что я поставил в делителем и периодПочему мой STM32F7 прерывается каждые 43 секунды?

static TIM_HandleTypeDef s_TimerInstance = { 
     .Instance = TIM2, 
    }; 
void Hal::initTim() 
{ 
    __TIM2_CLK_ENABLE(); 
    s_TimerInstance.Init.Prescaler = 96;       // This does nothing 
    s_TimerInstance.Init.CounterMode = TIM_COUNTERMODE_UP; 
    s_TimerInstance.Init.Period = 26;       // This does nothing 
    s_TimerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 
    HAL_TIM_Base_Init(&s_TimerInstance); 
    HAL_TIM_Base_Start_IT(&s_TimerInstance); 


    HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); 
    HAL_NVIC_EnableIRQ(TIM2_IRQn); 
} 
extern "C" void TIM2_IRQHandler() 
{ 
    HAL_TIM_IRQHandler(&s_TimerInstance); 
} 
extern "C" void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 
{ 
    HAL_GPIO_TogglePin(GPIOI, GPIO_PIN_1);  // Happens every 43 seconds for some reason 
} 
extern "C" void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim){} 
extern "C" void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim){} 

Когда прошить его к цели, светодиод не переключает каждые 43 секунд, независимо от того, что предделитель и период установлен.

Мне что-то не хватает, но я не могу понять это. Кто-нибудь с опытом прерывания, который может помочь?

+0

Поскольку это не весь код, нужно спросить, если HAL :: initTim на самом деле называется, и если есть другой код повторно -программировать свой таймер где-нибудь. – nos

+0

Что такое системные часы и часы источника таймера? (частота) –

+0

Это поможет увидеть немного больше вашего кода, в частности, инициирование часов, прерываний и таймера. – staringlizard

ответ

2

Хорошо. Таймеры очень просты. Вы просто сделали это, используя куб.

__TIM2_CLK_ENABLE(); 
TIM2->PSC = 96;       // prescaler (note that 0 is /1) 
TIM2->ARR = 0xFFFF-26;     // reload on overflow 
TIM2->DIER = TIM_DIER_UIE;    // overflow isr 
TIM2->CR1 |= TIM_CR1_CEN;     // enable timer 
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); 
HAL_NVIC_EnableIRQ(TIM2_IRQn); 

В ISR:

if(TIM2->SR & TIM_SR_UIF){ 
    TIM2->SR &= ~TIM_SR_UIF; 
} 

Как и в сторону. Мне нравится успокаивать условия перезагрузки init.

__HAL_RCC_TIM2_FORCE_RESET(); 
__NOP(); 
__HAL_RCC_TIM2_RELEASE_RESET(); 
0

Разный проект с STM32F469I-DISCOVERY, но я последовал за ответом Jeroen3. Я не уверен, где бы вы имели код __HAL_RCC ... и __NOP();, но он работал без него. Я рассчитал предделитель и период, чтобы быть некоторыми факторами. Например, чтобы получить мигающий светодиод 1 Гц, у меня был бы предварительный период '* period' = timer_clock, который, как я узнал, был core_clock/2.

Так core_clock из 180MHz и желаемое прерывание при 1Гц даст

(предделитель + 1) * (период + 1) = 180MHz/2/1Гц = 90M

, который может делиться на 9000 и 10000. Я не уверен в предделителе, но период на 16-разрядном таймере может быть не более 2¹⁶-1. Это означает, что коэффициенты не могут быть 90000 и 1000, потому что 90000 больше, чем 2¹⁶-1. Также он не может быть 900 и 100000.

extern "C" 
{ 
    #include "stm32f4xx_hal.h" 
    #include "stm32f4xx_hal_tim.h" 
    #include "stm32469i_discovery.h" //Needed for LED 

    /* User can use this section to tailor TIMx instance used and associated 
    resources */ 
    /* Definition for TIMx clock resources */ 
    #define TIMx       TIM3 
    #define TIMx_CLK_ENABLE()    __HAL_RCC_TIM3_CLK_ENABLE() 


    /* Definition for TIMx's NVIC */ 
    #define TIMx_IRQn      TIM3_IRQn 
    #define TIMx_IRQHandler    TIM3_IRQHandler 

    void TIM3_IRQHandler() 
    { 
     if(TIMx->SR & TIM_SR_UIF){ 
      TIMx->SR &= ~TIM_SR_UIF; 
      BSP_LED_Toggle(LED2); 
     } 
    } 

    void initTimer() 
    { 
     TIMx_CLK_ENABLE(); 
     //SystemCoreClock = 180MHz 
     //PSC = 180/2/10000-1 = 9000-1 
     TIMx->PSC = (uint32_t)((SystemCoreClock/2)/10000) - 1;// prescaler (note that 0 is /1) 
     TIMx->ARR = 10000-1;     // reload on overflow 
     TIMx->DIER = TIM_DIER_UIE;    // overflow isr 
     TIMx->CR1 |= TIM_CR1_CEN;     // enable timer 
     HAL_NVIC_SetPriority(TIMx_IRQn, 0, 0); 
     HAL_NVIC_EnableIRQ(TIMx_IRQn); 
    } 
} 

#include "gui/model/Timer.hpp" 

void Timer::init() 
{ 
    initTimer(); 
} 

Другое вдохновение: https://github.com/PaxInstruments/STM32CubeF4/blob/master/Projects/STM32469I-Discovery/Examples/TIM/TIM_TimeBase/Src/main.c