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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> прерывания STM32F4, должно работать, но не хочет...
Метценгерштейн
сообщение Aug 23 2014, 21:43
Сообщение #31


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

Группа: Свой
Сообщений: 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++){}

а если как у меня на системном таймере- то не хочет.
как-то они конфликтуют по прерываниям
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 23 2014, 22:06
Сообщение #32


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

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Aug 23 2014, 22:09
Сообщение #33


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



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

да, убрал деление на 8, заработало!
давайте спать пойдем уже)
И спасибо большое за помощь! wink.gif
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 23 2014, 22:10
Сообщение #34


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

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



Спокойной ночи.
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Aug 24 2014, 14:01
Сообщение #35


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

Группа: Свой
Сообщений: 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 именно так и писал, и все работало. А почему тут не хочет? Почему сначала бит надо сбрасывать?
Go to the top of the page
 
+Quote Post
adnega
сообщение Aug 24 2014, 15:07
Сообщение #36


Гуру
******

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



Цитата(Метценгерштейн @ Aug 24 2014, 18:01) *
Очень странно. Я на STM32L152 именно так и писал, и все работало. А почему тут не хочет? Почему сначала бит надо сбрасывать?

Тыщу раз обсуждали: прерывание вызывается два раза, т.к. сброс в самом конце обработчика.
Бит можете сбрасывать где угодно, но перед миганием нужно ПРОВЕРИТЬ установлен ли бит.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 24 2014, 15:11
Сообщение #37


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

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



Цитата
Вот что странно:
обработчик

Код
EXTI->PR |= EXTI_PR_PR0;

Вы понимаете, что приеденный Вами код сбросит ВСЕ имеющиеся запросы на прерывание, а не только 0-й?

Go to the top of the page
 
+Quote Post
adnega
сообщение Aug 24 2014, 15:23
Сообщение #38


Гуру
******

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



По второму кругу обсуждаем.
Найдите десять отличий http://electronix.ru/forum/index.php?showtopic=120361,
http://electronix.ru/forum/index.php?showt...t&p=1238176, http://electronix.ru/forum/index.php?showtopic=115489
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Aug 24 2014, 15:57
Сообщение #39


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

Группа: Свой
Сообщений: 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, то он зажигается.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 24 2014, 19:30
Сообщение #40


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

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



Цитата
почему все?

Потому, что ЗАПИСЬ единицы в соответствующий бит сбрасывает запрос.
Ну дали Вам работающий код, ну зачем игнорируете? И входил по одному разу... Если дребезг на кнопке - будет входить десятки раз за нажатие. Сброс запросов на этом не скажется.

Сообщение отредактировал Genadi Zawidowski - Aug 24 2014, 19:56
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Aug 24 2014, 19:47
Сообщение #41


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



я просто понять хочу и разобраться. Я не игнорирую )
давайте еще раз-
вот регистр
PR
есть там какое-то число записанное до нас.
я хочу сбросить прерывание
EXTI_PR_PR0, т.е. должен записать в PR 0x00000001
а число, что там уже было до нас? Его разве не надо сохранять?
Видел просто пишут
EXTI->PR = EXTI_PR_PR0;
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 24 2014, 19:55
Сообщение #42


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

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Aug 24 2014, 20:35
Сообщение #43


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



другими словами, можно просто писать
EXTI->PR = EXTI_PR_PR0;
так?
нигде же не сказано, чтобы беречь другие биты.

и Ваш код корректен
EXTI->PR = EXTI->PR & EXTI_PR_PR0;
равносилен верхнему. Т.к. EXTI_PR_PR0 = 0x00000001

вывел через USART содержание EXTI->PR в момент прерывания

как только вошел, значение 0х01
очистили бит, стал 0х00

а если будет несколько прерываний, будет несколько единичек стоять в соотв. местах.
т.е. правильно писать
EXTI->PR |= EXTI_PR_PR0;
так мы накладываем маску 0x00000001 и стираем т.о. только нулевой бит.
ну разве не так?
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 24 2014, 20:43
Сообщение #44


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

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Aug 24 2014, 20:55
Сообщение #45


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



давайте по шагам.
у меня сработали прерывания EXTI0 и EXTI3
регистр EXTI_PR = 0x00000009
пока верно?

дальше, зашел в обработчик EXTI0
делаю
PR= 0x00000001 (утверждаете, что сотрется только нулевой бит)
и все, потеряли мы прерывание от EXTI3!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 26th August 2025 - 00:05
Рейтинг@Mail.ru


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