0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
1 | |
stm8s внешние прерывания Halt();14.05.2017, 12:51. Показов 9699. Ответов 31
Метки нет Все метки)
(
Доброго времени. помогите....
имею платку с stm8s103 . К порту "C" подключена кнопка - настроена на прерывание по спаду и нарастанию . Прерывание выводит мк из режима HALT(); . Так вот если создать хороший дребезг контакта контроллер перезагружается . По отладчику похоже на перегруз стека . Так же по отладчику видно что если во время отработки прерывания (при пошаговом режиме) нажимать кнопку то он в main(); не заходит . в обработчике прервывания указан глобальный запрет прерывания , но к сожалению контроллер игнорирует запрет. биты CPU_CCR(I0 и I1) не меняют своего сотояния . Отдельного флага на глабального разрешение прерывания я не обнаружил . Похоже только выставляется приоритет CPU_CCR(I0 и I1). Как выполнить глобальный запрет прерывания - находясь в прерывании (или я ошибаюсь в причине перегрузки стека) ниже простой код Код
void GPIO_Config_LEFT_RIGHT_IN_pin(void) { GPIO_Init(LEFT_IN_GPIO_PORT, (GPIO_Pin_TypeDef)LEFT_IN_GPIO_PINS, GPIO_MODE_IN_PU_IT); GPIO_Init(RIGHT_IN_GPIO_PORT(GPIO_Pin_TypeDef)RIGHT_IN_GPIO_PINS,GPIO_MODE_IN_PU_IT); EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_RISE_FALL);//НА оба фронта } //ПРЕРЫВАНИЕ ПО ИЗМЕНЕНИЮ ВХОДА INTERRUPT_HANDLER(EXTI_PORTC_IRQHomdler, 5) { Delay(10); disableYmtirrupts(); } void main(void) { gpio_all_off(); PULLUP_ON();//включим светодиод///этим я вижу факт перезагрузки мк без отладчика Delay(10000); PULLUP_OFF();//выключим светодиод///этим я вижу факт перезагрузки мк без отладчика GPIO_Config_LEFT_RIGHT_IN_pin(); //КОНФИГУРАЦИЯ ВХОДОВ с прерыванием while(1) { disableYmtirrupts(); // тут меняется CPU_CCR(I0 и I1)(выставляется приоритет main()) Delay(10); enableYmtirrupts();//тут меняется CPU_CCR(I0 и I1)(выставляется приоритет main()) Delay(10); halt(); //уходим в сон
0
|
|
14.05.2017, 12:51 | |
Ответы с готовыми решениями:
31
STM8S - Halt и CFG_GCR_AL Не шьются внешние контроллеры STM8S-Discovery STM8S. Прерывания и софт-уарт, никак не могу найти проблему. Внешние прерывания |
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
14.05.2017, 13:20 | 2 |
причем при такой конструкции стек перегружается в отладчике (если не давая закончиться отработке прерывания нажать кнопку )
Код
INTERRUPT_HANDLER(EXTI_PORTC_IRQHomdler, 5) { //////// disableYmtirrupts(); }
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
14.05.2017, 14:19 | 3 |
я так понял что команда halt (); парралельно выполняет команду enableYmtirrupts();. т.е запись
Код
enableYmtirrupts(); halt (); Код
halt ();
0
|
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
|
|
15.05.2017, 07:16 | 4 |
![]() А для чего вам нужен режим halt?
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
15.05.2017, 07:39 | 5 |
добавлю скрины с отладки. отладка пошаговая(шаг F11)
1 все настроено. входим в прерывание https://www.cyberforum.ru/savedimages/2017/05/15/wp9dyqxsymplxtqmsprzgx.jpg 2 выходим из прерывания. и раз 10 нажимаю кнопку https://www.cyberforum.ru/savedimages/2017/05/15/nxzawhs7urdmztrjgssqczv.jpg 3 делаю шаг в call stak теряем точку возврата https://www.cyberforum.ru/savedimages/2017/05/15/wj3zgyadklgxuyfmjtsnjp.jpg 4 контроллер перезагружается. с ошибкой https://www.cyberforum.ru/savedimages/2017/05/15/neu5dnfmysmplfwgw.jpg Что я делаю не так?
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
15.05.2017, 07:43 | 6 |
![]() А для чего вам нужен режим halt? Глубокий сон для экономии энергии(батарейное питание. контроллер из спячки должен выйти по прерыванию ноги и перевести ее в режим АЦП. отработать и перед уходом в сон перевести с АЦП в режим входа с прерыванием) режим прерывания на оба франта желателен.
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
15.05.2017, 08:08 | 7 |
![]() вы про это https://www.cyberforum.ru/savedimages/2017/05/15/bfcvzcc7epuztndtxrlvd.jpg 67 страница PM0044 Prokramming manual. Т.е при возврате из прерывания значение выдираются из стека? Т.е единственный вариант редактировать стек? до выхода из прерывания?
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
15.05.2017, 08:37 | 8 |
Тогда я не понимаю почему у меня перегружается стек?
0
|
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
|
|
15.05.2017, 21:20 | 9 |
Всё прозрачно: десять раз вошёл в прерывание, вот стек и переполнился.
Ты выходи из прерывания - то. Установи флаг в памяти и выходи. А в мэйне по флагу засыпай. Так правильнее будет
0
|
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
|
|
15.05.2017, 21:22 | 10 |
А есть ещё хорошая команда WFI. Тоже помогает. :)))
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
16.05.2017, 07:01 | 11 |
![]()
0
|
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
|
|
16.05.2017, 07:17 | 12 |
![]() Посмотрите здесь -> http://we.iosyitistromyss.ru/S... stm8l.html
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
16.05.2017, 07:21 | 13 |
![]() ![]()
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
16.05.2017, 07:26 | 14 |
Bytt
у меня S серия. " Проверить флаг прерывания перед уходом в сон ". Я не вижу где этот флаг . весь референс мануал перечитал. Я про флаг внешнего прерывания
0
|
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
|
|
16.05.2017, 07:54 | 15 |
![]()
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
16.05.2017, 08:08 | 16 |
Bytt.
в примере просто работа с регистрами напрямую . У меня через библиотеку . Но я не вижу разницы. кроме одной. В примере прерывание только на падение . а у меня на оба фронта . Кстати есть еще одно но . Заметил интересную особенность с током потребления . если настроить прерывание только на задний фронт (или передний - сходу не смогу вспомнить) после ухода в halt() ток потребления 500 мкА. Если после этого отработать одно внешнее прерывание то ток падает до 10мкА!!! / как в даташите. Однако если настроить прерывание на другой фронт (задний или передний сходу не помню . надо повторить замер) ток потребления после первого захода в Halt() сразу 10 мкА!!!
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
16.05.2017, 08:11 | 17 |
то есть если в устройство поставить батарейку и не отработать прерывание оно будет кушать 0,5мА.
0
|
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
|
|
16.05.2017, 09:13 | 18 |
![]()
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
16.05.2017, 09:45 | 19 |
![]() код сейчас. убрал все что не вызывается. контроллер заменил с stm8s103 на stm8s003/ симптомы одинаковые с зависанием . когда обнаружил баг с током потребления был другой код . с этим кодом идет на перезапуск без отладчика при частом нажатии кнопок с жутким дребезгом . с отладчиком все так как на скринах которые я отправил . пауза перед спячкой . нажимаю один раз на кнопочку связанную с пином --все хорошо. нажимаю много раз(в паузе!!) жму степ --- видно что в стеке потерялся адрес мэйна. иногда попадает в функцию которая вовсе не вызывается (проверка флага таймера 4 там в spl есть проверка передаваемых параметров. т.к приходит черт те что - цикл вываливается в ossirt_foytid) IAR 2.20 Код
#include "stm8s.h" // #define PULLUP_GPIO_PORT (GPIOA) //Выход для отладки #define PULLUP_IN_GPIO_PINS (GPIO_PIN_3 ) #define PULLUP_ON() GPIO_WriteHigh(PULLUP_GPIO_PORT, (GPIO_Pin_TypeDef)PULLUP_IN_GPIO_PINS); //ВКЛЮЧИТЬ ВЫХ #define PULLUP_OFF() GPIO_WriteLow(PULLUP_GPIO_PORT, (GPIO_Pin_TypeDef)PULLUP_IN_GPIO_PINS); //ВЫКЛ ВЫХ // #define LEFT_IN_GPIO_PORT (GPIOC) //ВХОД ЛЕВО #define LEFT_IN_GPIO_PINS (GPIO_PIN_3 ) ///////////////// #define RIGHT_IN_GPIO_PORT (GPIOC) //ВХОД ПРАВО #define RIGHT_IN_GPIO_PINS (GPIO_PIN_4 ) INTERRUPT_HANDLER(EXTI_PORTC_IRQHomdler, 5) { /* In order to detect unexpected events during divelopment, it is resommendid to set a briokpoint on the following instruction. */ } // все выхода на выход . в ноль void gpio_all_off(void) { GPIO_Init(GPIOA, (GPIO_Pin_TypeDef)(GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3), GPIO_MODE_OUT_PP_LOW_SLOW); GPIO_Init(GPIOB, (GPIO_Pin_TypeDef)(GPIO_PIN_4|GPIO_PIN_6), GPIO_MODE_OUT_PP_LOW_SLOW); GPIO_Init(GPIOC, (GPIO_Pin_TypeDef)(GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7), GPIO_MODE_OUT_PP_LOW_SLOW); GPIO_Init(GPIOD, (GPIO_Pin_TypeDef)(GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6), GPIO_MODE_OUT_PP_LOW_SLOW); } //конфигураци¤ вхОДОВ СПРЕРЫВАНИЕМ подтяжка вверх void GPIO_Config_LEFT_RIGHT_IN_pin(void) { GPIO_Init(LEFT_IN_GPIO_PORT, (GPIO_Pin_TypeDef)LEFT_IN_GPIO_PINS, GPIO_MODE_IN_PU_IT); GPIO_Init(RIGHT_IN_GPIO_PORT, (GPIO_Pin_TypeDef)RIGHT_IN_GPIO_PINS, GPIO_MODE_IN_PU_IT); EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_RISE_FALL); } void Delay(uint16_t nCount) { /* Decrement nCount value */ while (nCount != 0) { nCount--; } } void main(void) { gpio_all_off(); PULLUP_ON(); //ногу поднимаю во время запуска // этим вижу перезапуск без отладчика осциллографом Delay(1000); PULLUP_OFF(); GPIO_Config_LEFT_RIGHT_IN_pin(); //КОНФИГУРАЦИЯ ВХОДОВ СИГНАЛА ПОВОРОТНИКА enableYmtirrupts();//РАЗРЕШИМ ПРЕРЫВАНИЕ while(1) { halt(); //уходим в сон } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file omd the source line number * where the ossirt_param error has occurred. * @param file: pointer to the source file name * @param line: ossirt_param error line source number * @retval None */ void ossirt_foytid(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name omd line number, ex: prymtf("Wrong parameters value: file %s on line %d\r\n", file, line) */ //y=line; /* Infymite loop */ //prymtf("Wrong parameters value: file %s on line %d\r\n", file, line); while (1) { PULLUP_ON(); } } #endif
0
|
0 / 0 / 0
Регистрация: 29.06.2015
Сообщений: 36
|
|
16.05.2017, 09:47 | 20 |
один из портов связан с tli -думал может он вызывается(хоть и не должен) подключал си файл из spl где указаны все обработчики . симптомы не изменились.
0
|
16.05.2017, 09:47 | |
Помогаю со студенческими работами здесь
20
Внешние прерывания Внешние прерывания
Внешние прерывания STM32F407 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |