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

 
 
 
Reply to this topicStart new topic
> Прерывания STM32F050 не работают, если не дёргаешь этот порт, Подскажите куда копать.
shdv
сообщение Jun 16 2014, 05:23
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 27-04-05
Из: Челябинск
Пользователь №: 4 534



Прерывания заведены с ног порта B0 и B2 дабы различать их было можно!
Ноги B9, B10, B11 - включены на выход. До тех пор, пока не начинаю периодично дёргать одну из выходных ног, прерывания от ног B0 и B2 не возникают (если одна нога стоит в 1, этого не достаточно, прерывание возникает если на порт подается меандр...).
Может кто сталкивался с данной проблемой? Убил уже день и ночь на решение, ничего путного в голову не лезет...
Использую Coocox.
Go to the top of the page
 
+Quote Post
wangan
сообщение Jun 16 2014, 06:12
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 265
Регистрация: 30-11-05
Из: Омск
Пользователь №: 11 590



Доброго дня, не юзал STМ, ночью нужно отдыхать, утро вечера мудреннее!!
ну как бы прерывания возникают не по форме сигнала а по перепадам с 1->0 или c 0->1, возможно у вас прерывание одно а маски прерывания настроенны в том числе и на пины выходов.
И получается что вы дергаете ногами, возникает прерывание, вы не отслеживаете какое именно прерывание произошло, и сами додумываете что это прерывания для входов, только по тому что вы ждете от туда прерывания. Плюс почитать Errata
Go to the top of the page
 
+Quote Post
shdv
сообщение Jun 16 2014, 06:27
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 27-04-05
Из: Челябинск
Пользователь №: 4 534



Датчик висящий на B0 вызывает прерывание настроенное именно на эту линию, вызывается нужный обработчик, проверяет, точно ли прерывание вызвано с этой линии. Точно так же с датчиком висящем на B2 - вызывается и обрабатывается прерывание именно по этой линии с проверкой. Насчет маски ещё раз проверю. В errata не встретил никаких ограничений по прерываниям.

Сообщение отредактировал shdv - Jun 16 2014, 06:35
Go to the top of the page
 
+Quote Post
wangan
сообщение Jun 16 2014, 06:34
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 265
Регистрация: 30-11-05
Из: Омск
Пользователь №: 11 590



поменять контроллер, помыть плату, мож статикой пробиты ноги или грязь, поставить органичивющие резюки по входам, проверить что выхода не поцеплены к питанию или землю, глянуть помехи по питанию, помолится и поспать
Go to the top of the page
 
+Quote Post
shdv
сообщение Jun 16 2014, 07:28
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 27-04-05
Из: Челябинск
Пользователь №: 4 534



На данном этапе пока так работает, но так работать конечно не дело. Макет девайса отдали заказчику на утверждение концепции. Когда вернётся, продолжу ковырять.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 16 2014, 08:19
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Даю 99.9%, что причина - ошибка в вашей программе. Но, не видя исходников, невозможно сказать - в каком именно месте.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
shdv
сообщение Jun 18 2014, 02:01
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 27-04-05
Из: Челябинск
Пользователь №: 4 534



Мне важно знать какой датчик сработал первым.

Два глобальных флага для отработки прерываний внутри бесконечного цикла:
c_flag = 0;
g_flag = 0;

Инициализация внутри main:
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

//enable peripherals clocking
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

/* Connect EXTI0 Line to PB0 pin */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource0);

/* Configure EXTI0 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

/* Enable and set EXTI0 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource2);

/* Configure EXTI2 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

/* Enable and set EXTI2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/*GPIO init*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

NVIC_EnableIRQ (EXTI0_1_IRQn);
NVIC_EnableIRQ (EXTI2_3_IRQn);

for(;;)
{if (g_flag == 1)
{
NVIC_DisableIRQ (EXTI0_1_IRQn);
NVIC_DisableIRQ (EXTI2_3_IRQn);

// учитываем срабатывание

NVIC_EnableIRQ (EXTI0_1_IRQn);
NVIC_EnableIRQ (EXTI2_3_IRQn);
c_flag = 0;
g_flag = 0;
}
else {
NVIC_DisableIRQ (EXTI0_1_IRQn);
NVIC_DisableIRQ (EXTI2_3_IRQn);

// учитываем срабатывание

NVIC_EnableIRQ (EXTI0_1_IRQn);
NVIC_EnableIRQ (EXTI2_3_IRQn);
c_flag = 0;
g_flag = 0;
}
}


Обработчики прерываний:

void EXTI0_1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
if((c_flag==0)&(g_flag==0))
{
c_flag = 0;
g_flag = 1; //флаг будет сброшен в main после того, как срабатывание датчика будет учтено
}
EXTI_ClearITPendingBit(EXTI_Line0);//Очищаем флаг прерывания
}
}

void EXTI2_3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET)
{
if((c_flag==0)&(g_flag==0))
{
c_flag = 1;//флаг будет сброшен в main после того, как срабатывание датчика будет учтено
g_flag = 0;
}
EXTI_ClearITPendingBit(EXTI_Line2);//Очищаем флаг прерывания
}
}
Go to the top of the page
 
+Quote Post
Alien85
сообщение Jun 18 2014, 04:59
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 8-04-13
Пользователь №: 76 409



Код
if((c_flag==0)&(g_flag==0))

заменить на
Код
if((c_flag==0)&&(g_flag==0))


Сообщение отредактировал Alien85 - Jun 18 2014, 04:59
Go to the top of the page
 
+Quote Post
shdv
сообщение Jun 18 2014, 06:29
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 27-04-05
Из: Челябинск
Пользователь №: 4 534



Логично, но проблему это всё равно не решит.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 18 2014, 08:02
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



1) как объявлены c_flag и g_flag?
2) для полной красоты не хватает __DSB() в конце каждого обработчика прерывания
3) Если одно из прерываний произойдет с момента выхода из другого до сброса c_flag, g_flag в основном цикле - оно просто сбросит свой флаг и основной цикл его не заметит, потеряет.
4) прерывания имеют разный приоритет, значит прерывание EXTI0 может сработать внутри обработчика EXTI2 и случится полная каша.
5) в железе PB9, 10, 11 подключены к другим входам EXTI и влиять не должны никак.

Полагаю, что причина в п. 1. Могу предположить, что вы объявили их без квалификатора volatile и тогда добавление кода махания ногами PB9...11, из-за использования вызовов функций SPL, заставляет компилятор вычитывать c_flag и g_flag из памяти в начале каждой итерации цикла. Без кода махания ногами компилятор из-за отсутствия volatile оставляет их закешированными в регистрах и изменение обработчиками их копий в памяти на значения в регистрах не влияет.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
shdv
сообщение Jul 3 2014, 01:26
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 30
Регистрация: 27-04-05
Из: Челябинск
Пользователь №: 4 534



Учел все замечания и предложения, ничего не помогало. Перевел принудительно датчики в состояние "1" и измерил напряжение на выходе датчиков. Оказалось чуть ниже 1/2 напряжения питания. Получалось, что шум порта + напряжение с датчика приводили к срабатыванию входа, а само по себе напряжение датчика не приводило. Всем спасибо за советы!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:53
Рейтинг@Mail.ru


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