|
|
  |
прерывания STM32F4, должно работать, но не хочет... |
|
|
|
Aug 23 2014, 21:43
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
да, я видел, что 6.7 ваш код обработчика работает Код void EXTI0_IRQHandler(void) { uint32_t pr = EXTI->PR & EXTI_PR_PR0; EXTI->PR = pr; //сбросили бит прерывания cpl (LED_Blue); } а мой почти такой же нет. самое интересное, а почему, когда мигалку вставляю, он не мигает? попробуйте с мигалкой мигалка работает, если задержка for (i=0;i<2000000;i++){} а если как у меня на системном таймере- то не хочет. как-то они конфликтуют по прерываниям
|
|
|
|
|
Aug 23 2014, 22:06
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Что-то намудрили с использованием системных тиков. Не происходят прерывания от системного таймера. Я вот такое использовал: Код #include "stm32f4xx.h" #include "stm32f4xx_gpio.h"
#include "gpio_ascold.h" #include "hardware.h" #include "delay.h"
void EXTI0_IRQHandler(void) { uint32_t pr = EXTI->PR & EXTI_PR_PR0; EXTI->PR = pr; //сбросили бит прерывания cpl (LED_Green); }
#define KEY GPIOA, GPIO_Pin_0, H
void stall(int an) { volatile int n = an; while (an --) ; }
void main() { InitPeriph();
// настройка ноги на прерывание PA0 GPIOA->MODER &= ~GPIO_MODER_MODER0; //input //GPIOA->OTYPER &= ~GPIO_OTYPER_OT_0; //Output push-pull //GPIOA->OSPEEDR |=GPIO_OSPEEDER_OSPEEDR0; //40 MHz //GPIOA->PUPDR &=~GPIO_PUPDR_PUPDR0; //No pull-up, pull-down
//// // настройка внешнего прерывания на PA0 RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; SYSCFG->EXTICR [0] |= SYSCFG_EXTICR1_EXTI0_PA; // Connect EXTI line 4 to PB EXTI->IMR |= EXTI_IMR_MR0; // какую линию выбираем из 23-х (у нас 4-я) = EXTI4 EXTI->FTSR |= EXTI_FTSR_TR0; // настройка реакции на спад //EXTI->RTSR |= EXTI_RTSR_TR0; // настройка реакции на нарастание NVIC_EnableIRQ(EXTI0_IRQn); // NVIC_DisableIRQ(EXTI0_IRQn); //NVIC_SetPriority(EXTI0_IRQn, 1); //приоритет // for (;;) { cpl (LED_Red); stall(10000000); } } После пары незначительных правок delay.c заработало... Откатил назад - работает. Возможно Rebuild поможет. Деление на 8 в Вашем случае лишнее. Вы же предделитель таймера не программируете на 8? __IO - это личная собственность библиотеки. В своих программах лучше использовать volatile
|
|
|
|
|
Aug 23 2014, 22:09
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
а если мне точно надо время мерять? на другом проце, да и на этом с этим таймером все норм. работает, пока др. прерывания не происходят да, убрал деление на 8, заработало! давайте спать пойдем уже) И спасибо большое за помощь!
|
|
|
|
|
Aug 24 2014, 14:01
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Вот что странно: обработчик Код void EXTI0_IRQHandler(void) { cpl (LED_Blue); EXTI->PR |= EXTI_PR_PR0;//сбросили бит прерывания } не работает лампа а так Код void EXTI0_IRQHandler(void) { EXTI->PR |= EXTI_PR_PR0;//сбросили бит прерывания cpl (LED_Blue); } работает. Очень странно. Я на STM32L152 именно так и писал, и все работало. А почему тут не хочет? Почему сначала бит надо сбрасывать?
|
|
|
|
|
Aug 24 2014, 15:11
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Цитата Вот что странно: обработчик Код EXTI->PR |= EXTI_PR_PR0; Вы понимаете, что приеденный Вами код сбросит ВСЕ имеющиеся запросы на прерывание, а не только 0-й?
|
|
|
|
|
Aug 24 2014, 15:57
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Цитата(Genadi Zawidowski @ Aug 24 2014, 19:11)  Код EXTI->PR |= EXTI_PR_PR0; Вы понимаете, что приеденный Вами код сбросит ВСЕ имеющиеся запросы на прерывание, а не только 0-й? почему все? я маскирую только тот бит, что EXTI_PR_PR0 т.е. я делаю EXTI->PR = EXTI->PR | EXTI_PR_PR0; т.е. я в регистре PR не меняя его, делаю ИЛИ по биту одному, т.е. если PR= 0100 EXTI_PR_PR0= 0001 результат будет 0101 или что не так? читаю отличия) получается, что дважды прерывание вызывается? Т.к. если просто зажигать LED, то он зажигается.
|
|
|
|
|
Aug 24 2014, 19:55
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Цитата я хочу сбросить прерывание EXTI_PR_PR0, т.е. должен записать в PR 0x00000001 Да, именно так (написано в даташите). Сбросится только этот бит. Примечания и условные обозначения в reference manual RM0090 смотрите. DocID018909 Rev 7, страница 383 - про его состояние при чтении: Цитата 0: No trigger request occurred 1: selected trigger request occurred This bit is set when the selected edge event arrives on the external interrupt line. This bit is cleared by programming it to ‘1’.
Сообщение отредактировал Genadi Zawidowski - Aug 24 2014, 20:06
|
|
|
|
|
Aug 24 2014, 20:43
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Цитата так мы накладываем маску 0x00000001 и стираем т.о. только нулевой бит EXTI->PR |= EXTI_PR_PR0; стирает всё. EXTI->PR = EXTI_PR_PR0; Стирает только нулевой бит. Я такой немного "извращённый" способ использую (с маскированием интересующих и записью обратно) как шаблон для случая нескольких разных обработчиков на одной функции прерывания. Цитата нигде же не сказано, чтобы беречь другие биты. Если не хотите обрабатывать в других функциях - можно не беречь. Предположим у Вас ещё 4_9 биты установлены - для другого случая. Если вы их здесь сбросите, обработчик 4_9 уже не вызовется.
Сообщение отредактировал Genadi Zawidowski - Aug 24 2014, 20:47
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|