Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: 32F407VG disco проблема c NVIC_init / TIM_ITConfig
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
kerasin
День добрый
Я ещё совсем новичок в микроконтроллерах, поэтому даже не очень знаю как правильно задать вопрос по своей проблеме.

Пробую запустить Keil 4.73 вполне дефолтный код обработчика прерывания от таймера

Код
    TIM_TimeBaseInitTypeDef timer_struct;
    NVIC_InitTypeDef NVIC_struct;
        uint32_t flag = 0;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

    timer_struct.TIM_Prescaler = 20000 - 1;
    timer_struct.TIM_CounterMode = TIM_CounterMode_Up;
    timer_struct.TIM_Period = 1000;
    timer_struct.TIM_ClockDivision = TIM_CKD_DIV1;
    timer_struct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM5, &timer_struct);
    
    TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);
    
    TIM_Cmd(TIM5, ENABLE);

    // NVIC init
    NVIC_struct.NVIC_IRQChannel = TIM5_IRQn;
    NVIC_struct.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_struct.NVIC_IRQChannelSubPriority = 1;
    NVIC_struct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_struct);

    while (1)
    {
            flag++;
        }


Всё компилируется без ошибок, запускается, но ничего не работает.
По брейкпойнтам стало ясно, что проблема либо с действиями NVIC_Init(&NVIC_struct); либо с TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE); Не важно, в каком порядке инициализировать, та строчка, которая будет второй вешает исполнение программы, ощущение, что оно уходит в бесконечный цикл и до while(1) даже не доходит. flag в watch'e на нуле и не растёт

ПРИ ЭТОМ:
Если поставить брейкпойнт в проблемном месте и трейсить пошагово, то всё работает как надо и flag в watch'e растёт.

Подскажите, с чем может быть проблема, куда копать?
adnega
Цитата(kerasin @ Nov 16 2016, 13:53) *
Подскажите, с чем может быть проблема, куда копать?

А обработчик прерывания вы сделали?
Может, у вас улетает в пустой обработчик?
kerasin
Делал, но до него не доходит, видимо, он не вызывается. флаг не растёт

Код
void TIM5_IRQ_Handler(void) {
    if (TIM_GetITStatus(TIM5, TIM_IT_Update) == SET)    {
        TIM_ClearITPendingBit(TIM5, TIM_IT_Update);
    //    GPIO_ToggleBits (GPIOD, GPIO_Pin_12);
        flag++;
    }
}
adnega
Цитата(kerasin @ Nov 16 2016, 14:45) *
TIM5_IRQ_Handler

Проверьте имя. Оно должно совпадать с именем в стартапе.
Мне кажется подчеркивание лишнее и должно быть TIM5_IRQHandler.
kerasin
Цитата(adnega @ Nov 16 2016, 16:00) *
Проверьте имя. Оно должно совпадать с именем в стартапе.
Мне кажется подчеркивание лишнее и должно быть TIM5_IRQHandler.


ОГРОМНОЕ СПАСИБО!
неделю ломал голову, что не так =)

Расскажите, вкратце, в чём причина была? Ну или где почитать про это можно

я так понимаю, прерывание надо скидывать иначе оно уходит в пустой дефолтный обработчик и там зацикливается?
adnega
Цитата(kerasin @ Nov 16 2016, 16:27) *
Расскажите, вкратце, в чём причина была?

Нужно смотреть startup-файл для вашего проекта.
Обычно он называется startup_stm32f40xx.s
Там есть таблица векторов прерываний, которые будут использоваться при возникновении прерываний.
Если в проекте функция не переопределена, то будет вызываться стандартная заглушка, типа
Код
...; line 396
DCMI_IRQHandler                                                            
CRYP_IRQHandler                                                    
HASH_RNG_IRQHandler
FPU_IRQHandler
  
                B       .

, где "B ." - перейти на себя (бесконечный цикл).
Обычно есть файл stm32f4xx_it.c, в котором переопределены стандартные исключения и нужно дописывать свои обработчики.
Поскольку с именами векторов прерываний строгих требований нет, истинной в последней инстанции являются имена из startup-файла.
kerasin
по
Цитата
FPU_IRQHandler

B .


оно и ходило в бесконечном цикле иногда при ручной трассировке
esaulenka
На самом деле, ходило оно по пустому TIM5_IRQHandler().
Просто в startupXXX.s есть особая ассемблерная магия - все обработчики прерываний объявлены с одним и тем же телом - "B ." (оно же - бесконечный цикл).

Так что да, при объявлении обработчиков надо быть очень внимательным, при опечатках линкер без каких-либо предупреждений подсунет "пустышку".
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.