Jump to content

    
Sign in to follow this  
Plexus

STM32F100 Непроизвольное срабатывание прерывания

Recommended Posts

Вы всерьёз думаете, что ошибка в библиотечных функциях? Причём в функциях конфигурирования, которыми пользуется огромное количество народа?

А вы видели весь код ТС, чтобы быть уверенным что нигде неправильно не вызвана функция?

 

 

В целом все свои мысли по этому вопросу сказал, полезны или без покажет время...

 

 

Share this post


Link to post
Share on other sites

Столкнулся с похожей проблемой что и автор топика. Контроллер STM32F100RB на плате STM32VLDISCOVERY.

 

На плате имеется штатная кнопка USER при нажатии на которую на ножку PA0 подаётся высокий уровень (2.9V - питание контроллера). Ножка PA0 изначально подтянута внешним резистором к общему проводу (к земле). Мне хочется чтобы при нажатии срабатывало прерывание EXTI и светодиод LD3 менял своё состояние на противоположное. Пример как можно видеть простейший и всё работает как и задумано, но есть БОЛЬШАЯ проблема с устойчивостью всей этой системы. При любом касании ножки PA0 металлическим пинцетом или щупом мультиметра происходит прерывание. Ничего подобного на других МК мною раньше не наблюдалось.

 

Как пробовал бороться:

 

1. Проверил подтяжку ножки осцилогафом - при касании уровень не меняется (или осцилографф не успевает это зафиксировать). Попробовал подтянуть через резистор меньшего номинала (вплоть до 100 Ом) - НЕ ПОМОГАЕТ

2. Пробовал ставить RC фильтр на ножку (100 Ом 100 нФ) - НЕ ПОМОГАЕТ.

3. Пробовал менять процедуру инициализации ножки и внешнего прерывания. Вместо SPL пробовал инициализацию через прямую запись в регистры - НЕ ПОМОГАЕТ. Также пробовались разные варианты инициализации из разных примеров/форумов/руководств - НЕ ПОМОГАЕТ.

4. Пробовал другие линии EXTI и другие ножки МК - НЕ ПОМОГАЕТ.

 

Устойчивость достигается только в одном случае - при прямой (без резистора) подтяжке ноги к питанию или земле. Тогда реакции на касания пинцетом нет. Сомнений в качестве разводки платы быть не может. Всё-таки это фирменная плата от STM. Поведение МК абсолютно не поддаётся логике и если честно уже начинают опускаться руки. В процессе поиска решения натыкался на темы форумов где описывались похожие глюки этих МК судя по всему авторам так и не смогли помочь с этим. Вообще какая-то засада...

 

Схема платы

 

mc131-8.png

 

Код проекта. IDE CooCox 1.7.8

 

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_exti.h"
#include "misc.h"


void EXTI_USER_Button_init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

// Set pin PA0 as input
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// Tell system that you will use PA0 for EXTI_Line0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);

EXTI_InitTypeDef EXTI_InitStructure;
// PA0 is connected to EXTI_Line0
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
// Interrupt mode
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
// Triggers on rising edge
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
// Enable interrupt
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
// Add to EXTI
EXTI_Init(&EXTI_InitStructure);


// Add IRQ vector to NVIC
NVIC_InitTypeDef NVIC_InitStruct;
// PA0 is connected to EXTI_Line1, which has EXTI0_IRQn vector
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
// Set priority
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
// Set sub priority
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
// Enable interrupt
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
// Add to NVIC
NVIC_Init(&NVIC_InitStruct);
}

int main(void)
{
// Инициализируем светодиоды LD3 и LD4
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8 | GPIO_Pin_9; 	// PC8 - LD4, PC9 - LD3
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;			// Set pin PC8 and PC9 as output
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_SetBits(GPIOC,GPIO_Pin_9);
GPIO_SetBits(GPIOC,GPIO_Pin_8);

EXTI_USER_Button_init();

while(1)
{
	//
}
}

void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)	// Judge whether a line break
{
	GPIOC->ODR ^= GPIO_Pin_9;
	for(uint32_t i = 0; i < 500000; i++); // Simple delay
}
EXTI_ClearITPendingBit(EXTI_Line0);	// Remove LINE interrupt flag bit
}

Edited by IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Share this post


Link to post
Share on other sites
Мне хочется чтобы при нажатии срабатывало прерывание EXTI и светодиод LD3 менял своё состояние на противоположное. Пример как можно видеть простейший и всё работает как и задумано, но есть БОЛЬШАЯ проблема с устойчивостью всей этой системы.

Вы в курсе, что есть такая штука, как дребезг металлического контакта? Самый простой способ бороться с ним - не опрашивать состояние кнопки после его изменения в течение 50-100 мс. Это автоматически реализуется, если состояние кнопки опрашивается с периодом 50-100 мс. Если вам так нравится прерывание, можно запрещать прерывание на это время, используя таймер и его прерывание, но это просто лишний геморрой.

Share this post


Link to post
Share on other sites
Вы в курсе, что есть такая штука, как дребезг металлического контакта? Самый простой способ бороться с ним - не опрашивать состояние кнопки после его изменения в течение 50-100 мс. Это автоматически реализуется, если состояние кнопки опрашивается с периодом 50-100 мс. Если вам так нравится прерывание, можно запрещать прерывание на это время, используя таймер и его прерывание, но это просто лишний геморрой.

 

Про дребезг контактов и методы борьбы с ним мне известно, но то что я описываю это не дребезг. Прерывание срабатывает именно от касания (не замыкание на на что либо!) вывода МК любым металлическим предметом (палец такого эффекта не даёт). При этом не спасает даже подтяжка вывода к питанию или земле через резистор. Программно в обработчике прерывания удалось отследить что это всё-таки не случайность, а кратковременное изменение уровня на ножке при касании проводящим предметом. Удивляет поразительная чувствительность STM32 к такому. Тот же AVR на такое никогда не реагировал. И как в таком случае мерить потенциал на ножке если любое касание её даже щупом тестера вызывает подобные эффекты?

Edited by ISF

Share this post


Link to post
Share on other sites
При любом касании ножки PA0 металлическим пинцетом или щупом мультиметра происходит прерывание. Ничего подобного на других МК мною раньше не наблюдалось.

....

Тот же AVR на такое никогда не реагировал. И как в таком случае мерить потенциал на ножке если любое касание её даже щупом тестера вызывает подобные эффекты?

Удивительные вещи вы пишете, в том плане, что такого раньше не наблюдали.

А я вот обратного никогда не наблюдал. :cranky:

 

Если коснуться металлическим пинцетом (если он еще и не изолированный, и в руке, то еще похлеще будет) высокоомной ножки МК, там помеха будет в десятки вольт. Ограничена будет только входными защитными диодами МК. И на осциллографе это тоже прекрасно видно.

 

Тестером измерять можно, но помеху при касании никто не отменит и прерывание все равно произойдет.

 

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

Share this post


Link to post
Share on other sites

Вы все про высокое, а причина может быть намного проще - и в SPL и в HAL до сих пор есть элементарная ошибка - при совместном использовании ног порта могут менятся "не свои" пины. Например функция установки бита может быть прописана как GPIOx->ODR |= 0b0001000... т.е. последовательность - чтение, модификация, запись. Если при этом будет прерывание и в нем будет изменен другой бит - произойдет ошибка - восстановится его старое значение. Для предотвращения этого нужно использовать либо запрет прерываний, либо специальный регистр BSRR, сделанный специально для того, чтобы сделать операции установки/сброса бит атомарными.

 

В последних версиях SPL и HAL установка и сброс бита уже сделаны правильно (через BSRR), а вот операция toggle - по прежнему GPIOx->ODR ^= ...

 

Проверьте весь код на наличие работы с отдельными битами GPIO не через BSRR.

 

Понятно, что EXTI работает не с ODR, а с IDR, но точной реализации харда GPIO нет, так что стоит проверить, мало-ли что.

Share this post


Link to post
Share on other sites
Удивительные вещи вы пишете, в том плане, что такого раньше не наблюдали.

А я вот обратного никогда не наблюдал. :cranky:

 

Если коснуться металлическим пинцетом (если он еще и не изолированный, и в руке, то еще похлеще будет) высокоомной ножки МК, там помеха будет в десятки вольт. Ограничена будет только входными защитными диодами МК. И на осциллографе это тоже прекрасно видно.

 

Тестером измерять можно, но помеху при касании никто не отменит и прерывание все равно произойдет.

 

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

 

Почему же тогда на моей отладочной плате с ATmega16A подобных приколов с прерываниями нет и в помине. Касаюсь я щупом или пинцетом или нет всё работает устойчиво и чётко. К тому же я уже раз 5 повторил что ножка никакая не высокоомная - она ПОДЯТНУТА к питанию или земле через резистор. При поиске решения я испытывал даже 100 Ом в качестве подтягивающего резистора и эффект ничуть меньше не становился.

 

К тому же я уже писал что подобную проблему на STM32 наблюдали и раньше, но тогда всё списали на плохую разводку и на этом всё и заглохло

 

http://forum.easyelectronics.ru/viewtopic....76&start=50

 

Крутаните до 3 страницы (последнее сообщение) - там человек описывает ровно туже проблему

 

Вы все про высокое, а причина может быть намного проще - и в SPL и в HAL до сих пор есть элементарная ошибка - при совместном использовании ног порта могут менятся "не свои" пины. Например функция установки бита может быть прописана как GPIOx->ODR |= 0b0001000... т.е. последовательность - чтение, модификация, запись. Если при этом будет прерывание и в нем будет изменен другой бит - произойдет ошибка - восстановится его старое значение. Для предотвращения этого нужно использовать либо запрет прерываний, либо специальный регистр BSRR, сделанный специально для того, чтобы сделать операции установки/сброса бит атомарными.

 

В последних версиях SPL и HAL установка и сброс бита уже сделаны правильно (через BSRR), а вот операция toggle - по прежнему GPIOx->ODR ^= ...

 

Проверьте весь код на наличие работы с отдельными битами GPIO не через BSRR.

 

Понятно, что EXTI работает не с ODR, а с IDR, но точной реализации харда GPIO нет, так что стоит проверить, мало-ли что.

 

Спасибо за совет. Нужно будет внимательно проверить. Версия CooCox у меня далеко не новая. Возможно библиотеки действительно с багами. Хотя я пробовал инициализацию через прямой доступ к регистрам и это не дало положительного результата..

Edited by ISF

Share this post


Link to post
Share on other sites

По моему STM ведёт себя абсолютно правильно. Фронт есть - прерывание должно быть.

Вообще кнопки и прерывания по входу - вещи плохо сочетаемые. В реальных условиях (при наличии помех) гарантируются случайные срабатывания.

Правильно будет - опрашивать с определенной частотой. И если из 100 опросов больше 50 единиц, значит кнопка нажата.

И посмотрите на наличие на плате конденсатора C22. Похоже его нет. Если поставить примерно 100n, то в Вашем случае должно помочь.

Share this post


Link to post
Share on other sites
По моему STM ведёт себя абсолютно правильно. Фронт есть - прерывание должно быть.

Вообще кнопки и прерывания по входу - вещи плохо сочетаемые. В реальных условиях (при наличии помех) гарантируются случайные срабатывания.

Правильно будет - опрашивать с определенной частотой. И если из 100 опросов больше 50 единиц, значит кнопка нажата.

И посмотрите на наличие на плате конденсатора C22. Похоже его нет. Если поставить примерно 100n, то в Вашем случае должно помочь.

 

Согласен что кнопка и прерывание = неудачное решение, но тут даже до нажатия кнопки дело не доходит. Достаточно просто коснуться вывода PA0 щупом тестера для замера напряжения и БАЦ!, получите прерывание. Я бы ещё понял если бы вывод болтался без подтяжки в воздухе и я его касался проводником - тут уж без вариантов будет многократное срабатывание прерывания от наводок, емкости щупов и т.п. Но почему себя так ведёт полностью обвязанный и прикрытый от всех случайностей вывод мне совершенно неясно (

 

Конденсатора C22 на плате нет, но я специально проверял на выводе PA1 схему с внешней подтяжкой и полной RC цепью - результат отрицательный, лучше не становиться. Вот проверенные мною варианты. Подтягивающий резистор менял от 100 Ом до 10к

wf_HUB.png

 

Share this post


Link to post
Share on other sites
К тому же я уже писал что подобную проблему на STM32 наблюдали и раньше, но тогда всё списали на плохую разводку и на этом всё и заглохло

...

Крутаните до 3 страницы (последнее сообщение) - там человек описывает ровно туже проблему

Просмотрел по диагонали предыдущие страницы - не обнаружил той же проблемы. Человек жаловался на самопроизвольное возникновение прерываний. В его случае причин может быть много, о чем и была дельная дискуссия.

 

В вашем же случае, вы сами касаетесь пинцетом ножки и удивляетесь, почему возникает прерывание. Это же тест на электростатический разряд "Human Body Model" (HBM), там киловольты могут быть. Не выбивает ножку МК - и хорошо, производитель ничего больше и не обещал.

 

Почему же тогда на моей отладочной плате с ATmega16A подобных приколов с прерываниями нет и в помине. Касаюсь я щупом или пинцетом или нет всё работает устойчиво и чётко.

возможно:

- питание 5В

- частота низкая, аппаратная выборка ножки редкая + аппаратный фильтр

- была программная обработка дребезга в прерывании, когда в прерывание попадаете, но действия не происходит из-за фильтрации

- какие-нибудь еще нюансы забыли, как все делали...

 

Достаточно просто коснуться вывода PA0 щупом тестера для замера напряжения и БАЦ!, получите прерывание. Я бы ещё понял если бы вывод болтался без подтяжки в воздухе и я его касался проводником - тут уж без вариантов будет многократное срабатывание прерывания от наводок, емкости щупов и т.п. Но почему себя так ведёт полностью обвязанный и прикрытый от всех случайностей вывод мне совершенно неясно (

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

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

Share this post


Link to post
Share on other sites
Согласен что кнопка и прерывание = неудачное решение, но тут даже до нажатия кнопки дело не доходит. Достаточно просто коснуться вывода PA0 щупом тестера для замера напряжения и БАЦ!, получите прерывание. Я бы ещё понял если бы вывод болтался без подтяжки в воздухе и я его касался проводником - тут уж без вариантов будет многократное срабатывание прерывания от наводок, емкости щупов и т.п. Но почему себя так ведёт полностью обвязанный и прикрытый от всех случайностей вывод мне совершенно неясно (

Почему то мне кажется, что во время экспериментов плата у Вас не заземлена, а на запястье нет браслета для снятия статики.

А значит в момент касания Вы подключаете к выводу микросхемы конденсатор на несколько десятков пикофарад, заряженный до нескольких киловольт.

Это эквивалент Вашего тела в достаточно сухом воздухе, если что.

А далее получается емкостной делитель, где ток разряда Вашей емкости заряжает емкость на входе. И вполне может быть, что эквивалентное напряжение на входе превысит логический уровень. А если бы это был просто висячий вход, то таким образом легко его убить.

Недаром всех монтажников заставляют браслеты одевать и работать заземленным инструментом.

Бывает, что у некоторых процессоров есть система внутренней синхронизации, которая не пропускает наносекундные (иногда и микросекундные) импульсы.

Видимо в STM такого нет. Это не значит, что процессоры плохие. Просто Вы использовать пытаетесь их не совсем правильно.

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
А попробовать одной рукой взяться за плату, за цепь земли, а другой пинцетом в кнопку тыкать. Сработает?

 

 

Попробовал, всё равно срабатывает, но ощутимо реже чем раньше

Edited by ISF

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this