Перейти к содержанию
    

Помогите настроить внешнее прерывание STM32, IDE CooCOX, плата discovery

Код инициализации:

 

// 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
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что сделал не так? Инициализацию сделал на основе примера в CooCox

А что у Вас не работает-то?

Что подключено к PA0?

А на плате discovery?

Кнопка USER?

А где обработчик прерывания?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И что Вы хотите выделенным сделать? Может в одном месте надо GPIOC->ODR &= (uint16_t)(~(GPIO_ODR_ODR9));

И в EXTI_ClearITPendingBit(EXTI_Line7) в параметре передавать EXTI_Line0;

Для установки-сброса битов порта изучите лучше регистр GPIO->BSRR.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я прописал 2 раза зажигание светодиода - вдруг не выполнится условие.

 

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

 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

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

 

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я прописал 2 раза зажигание светодиода - вдруг не выполнится условие.

Вообще светодиод не загорается?

А вывод PC9 подключен к светодтоду?

Настроен на вывод?

Такторование на порт подано?

Зажигается из main (не из прерывания)?

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

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

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

Приоритеты Вам не нужны. Это тонкий инструмент для совершенно других задач. Можно обсудить их позже - когда светодиод будет зажигаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще светодиод не загорается?

А вывод PC9 подключен к светодтоду?

Настроен на вывод?

Такторование на порт подано?

Зажигается из main (не из прерывания)?

 

Светодиод загорается принудительно, соотв-но PC9 подключен к нему и настроен на вывод. Тактирование подано (видно из кода). Из main соответственно зажигается

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тактирование подано (видно из кода).

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

 

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

 

EXTI_ClearITPendingBit(EXTI_Line7) поправили на EXTI_ClearITPendingBit(EXTI_Line0)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё поправил, что мне тут написали. Разумеется я и порт C затактировал, светодиод же горит. Используется только USART1 - открыты прерывания по приёму и передаче

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Используется только USART1 - открыты прерывания по приёму и передаче

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

 

А лучше покажите обработчик USART1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я и передавать буду

 

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

 

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
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Так не пойдет...

Кто дал Вам право читать USART1->DR, не проверив соответствующий флаг в USART1->SR?

Почему не обрабатываете флаг переполнения?

С таким обработчиком нельзя разрешать прерывания на передачу.

 

Если запретить прерывания от USART1, то прерывание от PA0 работает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, прерывание от PA0 как не работало, так и не работает. Давайте не отвлекаться на usart?

Посмотрите мой код. Что видите подозрительного? Чего не хватает? Или всё на первый взгляд в порядке?

Изменено пользователем OlegALL

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или всё на первый взгляд в порядке?

С учетом всех исправленных замечаний и за исключением замечаний к USART1 - все в порядке.

Проверьте действительно ли обработчик EXTI0_IRQHandler так называется (в стартапе).

А лучше название скопировать из стартапа.

Может стоит добавить объявление типа такого

void EXTI0_IRQHandler(void) __attribute__((interrupt("IRQ")));
void EXTI0_IRQHandler(void)
{
  ... Ваш код ...
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...