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

 
 
 
Reply to this topicStart new topic
> 32F407VG disco проблема c NVIC_init / TIM_ITConfig
kerasin
сообщение Nov 16 2016, 10:53
Сообщение #1





Группа: Новичок
Сообщений: 4
Регистрация: 16-11-16
Пользователь №: 94 208



День добрый
Я ещё совсем новичок в микроконтроллерах, поэтому даже не очень знаю как правильно задать вопрос по своей проблеме.

Пробую запустить 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 растёт.

Подскажите, с чем может быть проблема, куда копать?
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 16 2016, 11:20
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



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

А обработчик прерывания вы сделали?
Может, у вас улетает в пустой обработчик?
Go to the top of the page
 
+Quote Post
kerasin
сообщение Nov 16 2016, 11:45
Сообщение #3





Группа: Новичок
Сообщений: 4
Регистрация: 16-11-16
Пользователь №: 94 208



Делал, но до него не доходит, видимо, он не вызывается. флаг не растёт

Код
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++;
    }
}
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 16 2016, 13:00
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(kerasin @ Nov 16 2016, 14:45) *
TIM5_IRQ_Handler

Проверьте имя. Оно должно совпадать с именем в стартапе.
Мне кажется подчеркивание лишнее и должно быть TIM5_IRQHandler.
Go to the top of the page
 
+Quote Post
kerasin
сообщение Nov 16 2016, 13:27
Сообщение #5





Группа: Новичок
Сообщений: 4
Регистрация: 16-11-16
Пользователь №: 94 208



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


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

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

я так понимаю, прерывание надо скидывать иначе оно уходит в пустой дефолтный обработчик и там зацикливается?
Go to the top of the page
 
+Quote Post
adnega
сообщение Nov 16 2016, 15:00
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(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-файла.
Go to the top of the page
 
+Quote Post
kerasin
сообщение Nov 16 2016, 15:32
Сообщение #7





Группа: Новичок
Сообщений: 4
Регистрация: 16-11-16
Пользователь №: 94 208



по
Цитата
FPU_IRQHandler

B .


оно и ходило в бесконечном цикле иногда при ручной трассировке
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Nov 16 2016, 16:38
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



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

Так что да, при объявлении обработчиков надо быть очень внимательным, при опечатках линкер без каких-либо предупреждений подсунет "пустышку".


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post

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

 


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


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