|
Помогите настроить внешнее прерывание STM32, IDE CooCOX, плата discovery |
|
|
|
Sep 16 2013, 06:23
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275

|
Код инициализации: 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
Сообщение отредактировал IgorKossak - Sep 16 2013, 17:28
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Sep 16 2013, 07:38
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(OlegALL @ Sep 16 2013, 10:23)  Что сделал не так? Инициализацию сделал на основе примера в CooCox А что у Вас не работает-то? Что подключено к PA0? А на плате discovery? Кнопка USER? А где обработчик прерывания?
|
|
|
|
|
Sep 17 2013, 04:39
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275

|
Код 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, который должен работать
Сообщение отредактировал OlegALL - Sep 17 2013, 04:45
|
|
|
|
|
Sep 17 2013, 06:11
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275

|
Я прописал 2 раза зажигание светодиода - вдруг не выполнится условие. Я не очень понял эти моменты: Код NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; Видимо как-то настраивается приоритет. Но для каждого прерывания приоритет уже настроен в той же таблице прерываний, мне приоритет менять не нужно. Сейчас отрабатывает прерывание по приёму в USART1.
|
|
|
|
|
Sep 17 2013, 06:40
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(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. Приоритеты Вам не нужны. Это тонкий инструмент для совершенно других задач. Можно обсудить их позже - когда светодиод будет зажигаться.
|
|
|
|
|
Sep 17 2013, 10:40
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275

|
Цитата(adnega @ Sep 17 2013, 10:40)  Вообще светодиод не загорается? А вывод PC9 подключен к светодтоду? Настроен на вывод? Такторование на порт подано? Зажигается из main (не из прерывания)? Светодиод загорается принудительно, соотв-но PC9 подключен к нему и настроен на вывод. Тактирование подано (видно из кода). Из main соответственно зажигается
|
|
|
|
|
Sep 18 2013, 11:29
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275

|
Всё поправил, что мне тут написали. Разумеется я и порт C затактировал, светодиод же горит. Используется только USART1 - открыты прерывания по приёму и передаче
|
|
|
|
|
Sep 19 2013, 07:43
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275

|
я и передавать буду Обработчик прерывания 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);
}
Сообщение отредактировал IgorKossak - Sep 19 2013, 08:26
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Sep 19 2013, 08:13
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(OlegALL @ Sep 19 2013, 11:43)  Обработчик прерывания usart: Так не пойдет... Кто дал Вам право читать USART1->DR, не проверив соответствующий флаг в USART1->SR? Почему не обрабатываете флаг переполнения? С таким обработчиком нельзя разрешать прерывания на передачу. Если запретить прерывания от USART1, то прерывание от PA0 работает?
|
|
|
|
|
Sep 19 2013, 08:38
|
Участник

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275

|
Нет, прерывание от PA0 как не работало, так и не работает. Давайте не отвлекаться на usart? Посмотрите мой код. Что видите подозрительного? Чего не хватает? Или всё на первый взгляд в порядке?
Сообщение отредактировал OlegALL - Sep 19 2013, 08:39
|
|
|
|
|
Sep 19 2013, 08:57
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

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