STM32F103 внешние прерывания, проблема

Всем привет.

Использую внешнюю линию прерывания на порту GPIOA9.
Прерывание должно происходить по заднему фронту (на нем висит соответствующая нога W5100).
Все настроено, железо дергает ногу как положено, но контроллер после этого зацикливается на прерывании, независимо от состояния ноги. Для эксперимента воткнул в код обработчика выключение прерывания. Подействовало, но как только разрешаю прерывание — система зацикливается на нем не зависимо от состояния вывода мк.

код инициализации:

	EXTI->IMR |= EXTI_IMR_MR9; // Line 9		(GPIOA)
	EXTI->FTSR |= EXTI_FTSR_TR9; // falling edge
	NVIC_EnableIRQ(EXTI9_5_IRQn);
	NVIC_SetPriority (EXTI9_5_IRQn, 1);


код обработчика:

void   EXTI9_5_IRQHandler(void)        //; EXTI Line 9..5
{
	NVIC_ClearPendingIRQ (EXTI9_5_IRQn);
	if ((~(GPIOA->IDR)&(1<<9))==(1<<9))
	{
		NVIC_DisableIRQ(EXTI9_5_IRQn);
		GPIOA->BSRR |= 0x02;
		pCurrent_mode->stat.W5100_interrupt = 1;
		GPIOA->BSRR |= (0x02<<16);
	};
	return;
}

Кто знает, подскажите плиз что я не учитываю. В отладчике как только очищаю бит активности прерывания, сразу выставляется pending и команда сброса не помогает.

Спасибо.

UPD:

Проблема решена. Я неправилино сбрасывал pending.
добавил в обработчик строчку

	EXTI->PR |= (1<<9);

и все нормализовалось
  • 0
  • 21 января 2012, 13:40
  • Ultrin

Комментарии (17)

RSS свернуть / развернуть
EXTI->PR |= (1<<9);
Если начать разбираться с микроконтроллерами STM32, то часто встречается подобная конструкция на языке Си. А что оно означает?
0
  • avatar
  • Aneg
  • 21 января 2012, 19:33
Полю PR структуры EXTI выставить девятый справа бит в единицу.
0
Ну в данном случае это фактически не поле, а регистр EXTI.PR. Смысл регистра надо смотреть в даташите, но видимо это Pending Requests, а 9-й бит — запрос на прерывание от 9-й ножки, который после обработки и сбрасывается.

Но мне вот интересней, а почему «NVIC_ClearPendingIRQ(EXTI9_5_IRQn);» не работает?
0
Как выставить несколько бит одновременно в регистре или в порту?
0
REG |= (1 << BITNUM1) | (1 << BITNUM2) |…
А вообще-то это стандартно. Неоднократно обсасывалось, в том числе и в курсе на easyelectronics.ru.
0
EXTI->PR |= (1<<9); эквивалентно EXTI_ClearITPendingBit(EXTI_Line9);
0
это эквивалентно, если использовать библиотеку от ST.
В данном случае я ей не пользуюсь.

То Vga:
NVIC_ClearPendingIRQ(EXTI9_5_IRQn) очищает бит общей линии прерывания (он к тому же очищается автоматом при входе) а сброс в EXTI->PR очищает конкретную линию порта.
0
А не CMSIS?
0
Функции NVIC_* — часть CMSIS (соответственно, одни и те же для всех Cortex'ов), а EXTI_* — часть периферийной библиотеки от ST (у каждого производителя своя).
0
Я не про функции, а про определения периферии как структуры. В CMSIS есть ядерная часть, а есть периферийная от каждого проца своя. И вот все структуры именно там. Но у ST есть еще периферийная либа, которая может быть подключена отдельно, без CMSIS и у ней несколько иной способ доступа к регистрам. Через точку, емнип.
0
Единственное, что я вспомнил — что-то типа

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // точка
//…
GPIO_Init(GPIOB, &GPIO_InitStructure);

Но тут точка исключительно потому, что доступ к структуре не через указатель. И регистры тут не при чем (смысл всего этого в том, чтобы защитить пользователя от страшных регистров). Да и без CMSIS все это не работает, оно активно использует его внутри.

Или вы имели в виду что-то другое?
0
Я натыкался год назад на нечто похожее на CMSIS только не CMSIS. Какая то своя либа от STM Обьявления периферии там были чуток по другому.
0
Не это? libopencm3.org/wiki/Main_Page (хотя это не от STM.)
0
Не. Где то на сайте stm выложено. А вот где…
0
NVIC_ClearPendingIRQ(EXTI9_5_IRQn); сбрасывает флаг «прерывание ожидает» в NVIC, однако линия запроса прерывания остается активной, поэтому NVIC немедленно ставит этот флаг снова. Чтобы указать, что прерывание обработано, надо трогать не NVIC, а контроллер внешних прерываний (EXTI), из которого эта линия и выходит. У него есть регистр EXTI->PR, в котором предусмотрены биты для каждой ноги. Эти биты должны сбрасываться пользователем после обработки прерывания.

Сделано это доя того, чтобы не терять события. Если вы зашли в прерывание, чтобы обработать событие (фронт/спад) на ноге 9, а в это время произошло событие на ноге 8, сразу же произойдет еще одно такое же прерывание (если нет более приоритетных). Иначе бы на ногу 8 вы не отреагировали. (Конечно, механизм зависит от правильной очистки флагов пользователем — обработал ногу 9, сбросил 9-й бит в EXTI->PR).
0
Это вы сами написали или где-то уже готовый мануал? В даташите вроде не настолько развернутый ответ. Может поделитесь ссылкой?
0
Источники информации по ядру Cortex-M — в ARMv7-M ARM, Cortex-M3/M4/… TRM, ARM Infocenter (все на arm.com) и книга The Definitive Guide to the ARM Cortex-M3, 2 издание. Документация STM32 со всем этим практически не пересекается — описывает только свою периферию, электрические параметры микросхем и т. п. В этом главная сложность изучения микроконтроллеров с ядром Cortex.

По обсуждаемой теме можно посмотреть гл. 7.4 в The Definitive Guide, только оттуда не очень понятно, что некоторые interrupt inputs остаются asserted, пока их специально не сбросить. Но если внимательно почитать RM0008 (10.2.4), окажется, что EXTI держит соответствующую линию IRQ, пока пользователь не сбросит бит в PR. То же самое и в других местах, где одно прерывание может вызываться несколькими событиями (хотя бы UART).
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.