Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите настроить внешнее прерывание STM32, IDE CooCOX, плата discovery
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
OlegALL
Код инициализации:

CODE
// NVIC configuration

NVIC_InitTypeDef NVIC_InitStructure;

// Set the Vector Table base location at 0x08000000 !!!!!!
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

// Configure one bit for preemption priority
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// Enable the EXTI0 Interrupt

//NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; // !!!

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


// GPIO configuration
GPIO_InitTypeDef GPIO_InitStructure;
// Configure PA0 as input floating (EXTI Line0)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); // можно ли последовательно?
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOA, &GPIO_InitStructure);


// Configure EXTI Line0 to generate an interrupt on rising or falling edge
GPIO_EXTILineConfig(GPIOA,GPIO_PinSource0);

EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);


NVIC_EnableIRQ(EXTI0_IRQn);

Что сделал не так? Инициализацию сделал на основе примера в CooCox
adnega
Цитата(OlegALL @ Sep 16 2013, 10:23) *
Что сделал не так? Инициализацию сделал на основе примера в CooCox

А что у Вас не работает-то?
Что подключено к PA0?
А на плате discovery?
Кнопка USER?
А где обработчик прерывания?
OlegALL
Код
EXTI0_IRQHandler(void){

    GPIOC->ODR |= (GPIO_ODR_ODR9);
    //flags.button_pressed = 1;
    //turn_on_led();
    if(EXTI_GetITStatus(EXTI_Line0) != RESET)
    {
        //Handle the interrupt
        GPIOC->ODR |= (GPIO_ODR_ODR9);
        EXTI_ClearITPendingBit(EXTI_Line7);
    }
}


Вот обработчик. Он не отрабатывает, хочу, чтобы загорался светодиод. К PA0 подключена кнопка User, да. Голубая. Я не уверен в настройках векторов прерываний и приоритетов, не очень понял. Код взял из примера в coocox, который должен работать
DmitryM
Цитата(OlegALL @ Sep 17 2013, 08:39) *
EXTI0_IRQHandler(void){

GPIOC->ODR |= (GPIO_ODR_ODR9);
//flags.button_pressed = 1;
//turn_on_led();
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
//Handle the interrupt
GPIOC->ODR |= (GPIO_ODR_ODR9);
EXTI_ClearITPendingBit(EXTI_Line7);
}
}


Вот обработчик. Он не отрабатывает, хочу, чтобы загорался светодиод. К PA0 подключена кнопка User, да. Голубая. Я не уверен в настройках векторов прерываний и приоритетов, не очень понял. Код взял из примера в coocox, который должен работать


И что Вы хотите выделенным сделать? Может в одном месте надо GPIOC->ODR &= (uint16_t)(~(GPIO_ODR_ODR9));
adnega
Цитата(DmitryM @ Sep 17 2013, 08:49) *
И что Вы хотите выделенным сделать? Может в одном месте надо GPIOC->ODR &= (uint16_t)(~(GPIO_ODR_ODR9));

И в EXTI_ClearITPendingBit(EXTI_Line7) в параметре передавать EXTI_Line0;
Для установки-сброса битов порта изучите лучше регистр GPIO->BSRR.
OlegALL
Я прописал 2 раза зажигание светодиода - вдруг не выполнится условие.

Я не очень понял эти моменты:

Код
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;



Видимо как-то настраивается приоритет. Но для каждого прерывания приоритет уже настроен в той же таблице прерываний, мне приоритет менять не нужно. Сейчас отрабатывает прерывание по приёму в USART1.
adnega
Цитата(OlegALL @ Sep 17 2013, 10:11) *
Я прописал 2 раза зажигание светодиода - вдруг не выполнится условие.

Вообще светодиод не загорается?
А вывод PC9 подключен к светодтоду?
Настроен на вывод?
Такторование на порт подано?
Зажигается из main (не из прерывания)?
Цитата
Я не очень понял эти моменты:
Код
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

Видимо как-то настраивается приоритет. Но для каждого прерывания приоритет уже настроен в той же таблице прерываний, мне приоритет менять не нужно. Сейчас отрабатывает прерывание по приёму в USART1.

Приоритеты Вам не нужны. Это тонкий инструмент для совершенно других задач. Можно обсудить их позже - когда светодиод будет зажигаться.
OlegALL
Цитата(adnega @ Sep 17 2013, 10:40) *
Вообще светодиод не загорается?
А вывод PC9 подключен к светодтоду?
Настроен на вывод?
Такторование на порт подано?
Зажигается из main (не из прерывания)?


Светодиод загорается принудительно, соотв-но PC9 подключен к нему и настроен на вывод. Тактирование подано (видно из кода). Из main соответственно зажигается
adnega
Цитата(OlegALL @ Sep 17 2013, 14:40) *
Тактирование подано (видно из кода).

Где? В коде из первого поста? Там только GPIOA.

Какие еще прерывания используются?

EXTI_ClearITPendingBit(EXTI_Line7) поправили на EXTI_ClearITPendingBit(EXTI_Line0)?
OlegALL
Всё поправил, что мне тут написали. Разумеется я и порт C затактировал, светодиод же горит. Используется только USART1 - открыты прерывания по приёму и передаче
adnega
Цитата(OlegALL @ Sep 18 2013, 15:29) *
Используется только USART1 - открыты прерывания по приёму и передаче

Если нечего передавать, то прерывание на передачу должно быть запрещено. Это Вы знаете?

А лучше покажите обработчик USART1.
OlegALL
я и передавать буду

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

CODE
USART1_IRQHandler(void){

if (flags.wait_message_usart1){
switch (rx_stage){
case 1: // байт признака начала
if (USART1->DR == BEGIN){
rx_stage++;
} else {
rx_stage = 1; // в начало посылки
}
break;

case 2: // байт адреса
if (USART1->DR == ADDRESS_STM32){
rx_stage++;
} else {
rx_stage = 1;
}
break;

case 3: // байт функции
if (USART1->DR == FUNCTION){
rx_stage++;
} else {
rx_stage = 1;
}
break;

case 4: // старший байт crc
rx_stage++;
break;
case 5: // младший байт crc
rx_stage++;
break;
case 6: // старший байт признака конца CR
if (USART1->DR == CR){
rx_stage++;
} else {
rx_stage = 1;
}
break;

case 7: // младший байт признака конца LF
if (USART1->DR == LF){
rx_stage++;
} else {
rx_stage = 1;
}
break;
}
}
//GPIOC->ODR |= (GPIO_ODR_ODR9);

}
adnega
Цитата(OlegALL @ Sep 19 2013, 11:43) *
Обработчик прерывания usart:

Так не пойдет...
Кто дал Вам право читать USART1->DR, не проверив соответствующий флаг в USART1->SR?
Почему не обрабатываете флаг переполнения?
С таким обработчиком нельзя разрешать прерывания на передачу.

Если запретить прерывания от USART1, то прерывание от PA0 работает?
OlegALL
Нет, прерывание от PA0 как не работало, так и не работает. Давайте не отвлекаться на usart?
Посмотрите мой код. Что видите подозрительного? Чего не хватает? Или всё на первый взгляд в порядке?
adnega
Цитата(OlegALL @ Sep 19 2013, 12:38) *
Или всё на первый взгляд в порядке?

С учетом всех исправленных замечаний и за исключением замечаний к USART1 - все в порядке.
Проверьте действительно ли обработчик EXTI0_IRQHandler так называется (в стартапе).
А лучше название скопировать из стартапа.
Может стоит добавить объявление типа такого
Код
void EXTI0_IRQHandler(void) __attribute__((interrupt("IRQ")));
void EXTI0_IRQHandler(void)
{
  ... Ваш код ...
}
Builder
Цитата(OlegALL @ Sep 19 2013, 11:38) *
Нет, прерывание от PA0 как не работало, так и не работает. Давайте не отвлекаться на usart?
Посмотрите мой код. Что видите подозрительного? Чего не хватает? Или всё на первый взгляд в порядке?

Тоже была проблема настроить прерывание.
Мне помогло изучение примеров и "stm32f2xx_stdperiph_lib" для используемой серии.
Там есть папка "STM32F2xx_StdPeriph_Examples", найдите то что Вам нужно и тупо сделайте как в примере.
В первую очередь Вс будет интересовать пример из папки "EXTI", но и стальное смотрите.
nx6310
Посмотрите отладчиком что у вас происходит в программе
RuSTA
Лучше скажите что за камень у вас используется!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.