вопрос по STM8S и внешним прерываниям
- mark13121971
- Открыл глаза
- Сообщения: 54
- Зарегистрирован: Вт янв 05, 2010 14:51:04
вопрос по STM8S и внешним прерываниям
В STM8S отсутствует статусный регистр, где устаналиваются флаги прерывания от пинов либо от порта в целом. В системе проектирования IAR, как известно, в обработчиках прерываний необходимо сразу сбрасывать флаг прерывания. Соответственно вопрос: если я использую STM8S, то какой флаг мне, собственно говоря, сбрасывать при прерывании от порта? Или вообще ничего не нужно сбрасывать? В STM8L есть статусный регистр SR, в котором нужно сбрасывать флаги внешних прерываний при обработке.
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: вопрос по STM8S и внешним прерываниям
Приветствую. Давно не писал под stm8s, не помню как там - нет проектов старых под рукой.
вот пример обработчика внешнего прерывания из библиотеки:
нет никаких сбросов флагов.
вот пример обработчика внешнего прерывания из библиотеки:
Код: Выделить всё
INTERRUPT_HANDLER(EXTI_PORTB_IRQHandler, 4)
{
if ((GPIO_ReadInputData(JOYSTICK_PORT) & JOYSTICK_LEFT_PIN) == 0x00)
{
GPIO_WriteReverse(LEDS_PORT, LED1_PIN);
}
if ((GPIO_ReadInputData(JOYSTICK_PORT) & JOYSTICK_RIGHT_PIN) == 0x00)
{
GPIO_WriteReverse(LEDS_PORT, LED2_PIN);
}
if ((GPIO_ReadInputData(JOYSTICK_PORT) & JOYSTICK_UP_PIN) == 0x00)
{
GPIO_WriteReverse(LEDS_PORT, LED3_PIN);
}
if ((GPIO_ReadInputData(JOYSTICK_PORT) & JOYSTICK_DOWN_PIN) == 0x00)
{
GPIO_WriteReverse(LEDS_PORT, LED4_PIN);
}
}Ставим плюсы: )
- mark13121971
- Открыл глаза
- Сообщения: 54
- Зарегистрирован: Вт янв 05, 2010 14:51:04
Re: вопрос по STM8S и внешним прерываниям
Спасибо. Приму к сведению. Просто ужасно мало внятного описания на эти камни. Да и в даташите ни слова об этом.
Re: вопрос по STM8S и внешним прерываниям
Да, я в свое время тоже флаг искал, который надо сбросить.
Нет такого в STM8S.
Кроме того, после выхода из обработчика, если условие для прерывание все еще выполняется - то оно будет сгенерировано опять, и опять, и опять, и опять, и опять...
Поэтому в большинстве случаев приходится инвертировать условие
Вот пример кода из одного моего проектика:
Также не нашел простого способа (флага) что бы понять какое из внешних событий вызвало прерывание, в случае когда на несколько ног один обработчик.
Нет такого в STM8S.
Кроме того, после выхода из обработчика, если условие для прерывание все еще выполняется - то оно будет сгенерировано опять, и опять, и опять, и опять, и опять...
Поэтому в большинстве случаев приходится инвертировать условие
Вот пример кода из одного моего проектика:
Код: Выделить всё
//Process external interrupt
char PCIS = EXTI_CR1_PCIS;
char IDR = PC_IDR_IDR5;
if ((PCIS + IDR) == 2) { //Check is external interrupt //В этом проекте у меня один обработчик на разные типы прерываний, поэтому проверяю что было причиной
EXTI_CR1_PCIS = ~PCIS; //Invert interrupt sensivity
<здесь логика обработки>
}Также не нашел простого способа (флага) что бы понять какое из внешних событий вызвало прерывание, в случае когда на несколько ног один обработчик.
Re: вопрос по STM8S и внешним прерываниям
Здравствуйте.
Разбираюсь с STM8S103F3, дошол до внешних прерываний. Не могу понять как работают приоритеты.
По задумки я вхожу в прерывание порта D, не выходя из прерывания активирую прерывание порта С. Т. к. порт С приорететней я должен оказаться в нем, но я остаюсь в D. Подскажите в чем ошибка.
Разбираюсь с STM8S103F3, дошол до внешних прерываний. Не могу понять как работают приоритеты.
По задумки я вхожу в прерывание порта D, не выходя из прерывания активирую прерывание порта С. Т. к. порт С приорететней я должен оказаться в нем, но я остаюсь в D. Подскажите в чем ошибка.
Код: Выделить всё
#include "iostm8s103f3.h"
#define STRINGVECTOR(x) #x
#define ISR( a, b ) \
_Pragma( STRINGVECTOR( vector = (b) ) ) \
__interrupt void (a)( void )
void SomeDelay()
{
for (unsigned long delay=0; delay<50000; delay++);
};
ISR(PortD_interrupt, EXTI3_vector) //прерывание D порта
{
while (PD_IDR_bit.IDR4 == 0)
{
PB_ODR_bit.ODR5 ^= 1;
SomeDelay();
SomeDelay();
};
};
ISR(PortC_interrupt, EXTI2_vector) //прерывание C порта
{
while (PC_IDR_bit.IDR4 == 0)
{
PB_ODR_bit.ODR5 ^= 1;
SomeDelay();
};
};
int main( void )
{
CLK_CKDIVR = 0;
PB_DDR = 0xFF;
PB_CR1 = 0xFF;
//Настраиваем первую кнопку
PC_DDR_DDR4 = 0; //На вход..
PC_CR1_bit.C14 = 1; //Включаем внутренний подтягивающий резистор
PC_CR2_bit.C24 = 1; //Прерывание разрешено
//Настраиваем вторую кнопку
PD_DDR_DDR4 = 0;//На вход..
PD_CR1_bit.C14 = 1; //Включаем внутренний подтягивающий резистор
PD_CR2_bit.C24 = 1; //Прерывание разрешено
//Светодиод, управляемый кнопкой
PB_DDR_bit.DDR5 = 1; //На выход
PB_CR1_bit.C15 = 1; //В режиме push-pull
//Настраиваем оба прерывания на срабатывание по спаду напряжения (задний фронт)
EXTI_CR1_bit.PCIS = 2;
EXTI_CR1_bit.PDIS = 2;
//Устанавливаем приоритеты для прерывания порта С и D
//ITC_SPR1_VECT2SPR=1;
//ITC_SPR1_VECT3SPR=3;
asm("RIM"); //Глобально разрешаем прерывания
while (1); //Затупляемся в цикле
{
}
}Re: вопрос по STM8S и внешним прерываниям
1) установка приоритетов закомментирована
2) для портов C и D оно лежит в регистре ISPR2, по номерам векторов называтся будут наверно VECT5 и VECT6, хз как там в IAR-е.
2) для портов C и D оно лежит в регистре ISPR2, по номерам векторов называтся будут наверно VECT5 и VECT6, хз как там в IAR-е.
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: вопрос по STM8S и внешним прерываниям
добавлю
из документа RM0016
Software priority register x (ITC_SPRx)
Reset value: 0xFF
номера векторов (смотрел правда документ STM8S003, должно быть также вроде)
5 EXTI2 Port C external interrupts
6 EXTI3 Port D external interrupts
значит в регистре (Software priority register x (ITC_SPRx) который Reset value: 0xFF)
конкретно ITC_SPR2 раз у него есть установка битов VECT7SPR[1:0] VECT6SPR[1:0] VECT5SPR[1:0] VECT4SPR[1:0]
осталось установить биты приоритетов
з.ы. вроде так,мог конечно подзабыть, но таймерах приоритеты у меня работали
из документа RM0016
Software priority register x (ITC_SPRx)
Reset value: 0xFF
номера векторов (смотрел правда документ STM8S003, должно быть также вроде)
5 EXTI2 Port C external interrupts
6 EXTI3 Port D external interrupts
значит в регистре (Software priority register x (ITC_SPRx) который Reset value: 0xFF)
конкретно ITC_SPR2 раз у него есть установка битов VECT7SPR[1:0] VECT6SPR[1:0] VECT5SPR[1:0] VECT4SPR[1:0]
осталось установить биты приоритетов
Код: Выделить всё
I1 I0 Priority Level
1 0 Level 0 (main)
0 1 Level 1 Low
0 0 Level 2 High
1 1 Level 3 (= software priority disabled*)з.ы. вроде так,мог конечно подзабыть, но таймерах приоритеты у меня работали
Re: вопрос по STM8S и внешним прерываниям
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3199708#p3199708"]1) установка приоритетов закомментирована[/uquote]
Закоментировал умышленно, по задумке должны работать аппаратные приоритеты.
Закоментировал умышленно, по задумке должны работать аппаратные приоритеты.
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: вопрос по STM8S и внешним прерываниям
Вот же, буквально недавно обсуждали приоритеты в stm8 в соседнем топике.
Re: вопрос по STM8S и внешним прерываниям
Всем спасибо. Удалось настроить программные приоритеты
Только почему не сработали аппаратные?
Код: Выделить всё
//Устанавливаем более низкий приоритет для прерывания порта С, чем для остальных
ITC_SPR2_VECT5SPR=1;Только почему не сработали аппаратные?
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: вопрос по STM8S и внешним прерываниям
почему не сработали аппаратные?
не понятный вопрос. От D сработало ж вроде:
но я остаюсь в D
Потом от C не попадает?
имхо SomeDelay() в прерывании лишнее - например, кроме светодиодов в прерывании, можно программные флаги установить, а SomeDelay() в цикле main вызывать по флагу
Re: вопрос по STM8S и внешним прерываниям
[uquote="Valek174",url="/forum/viewtopic.php?p=3201693#p3201693"]Только почему не сработали аппаратные?[/uquote]
аппаратный приоритет определяет, какое прерывание будет выполняться после завершения текущего.
Concurrent interrupt management mode
In this mode all interrupts are interrupt priority level 3 so that none of them can be interrupted, except by a TLI, RESET, or TRAP
аппаратный приоритет определяет, какое прерывание будет выполняться после завершения текущего.
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: вопрос по STM8S и внешним прерываниям
Valek174 писал(а):Код:
//Устанавливаем более низкий приоритет для прерывания порта С, чем для остальных
ITC_SPR2_VECT5SPR=1;
Только почему не сработали аппаратные?
Этот регистр отвечает за вектора 7:4.
Для векторов 7:5 Вы установили левел 2 (00b). Это порты CDE.
Для вектора 4 левел 1 (01b). Порт B.
Т.е. Вы одинаково опустили CDE и еще на один уровень ниже порт B.
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: вопрос по STM8S и внешним прерываниям
Я был невнимателен. ITC_SPR2_VECT5SPR - это видимо структура с битовыми полями. Тогда все что я написал тут , конечно же неверно.
