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

STM32F100 USART1 виснет в прерывании. Что делаю не так?

STM32F100 UART1 когда уходит на прерывание - зависает. Точку останова на прерывании не

ставиться (IAR 6.21).

Если обработчик прерывания оставляю пустым (оставляю только сброс прерывания)- тоже

виснет.

Причем программа работает, а как только от компьютера отправляю байт контроллеру - он

виснет, даже если функция по приему прерывания пустая.

Может неправильно биты прерывания сбрасываю и он в цикл уходит?

Полная программа во вложении. Помогите пожалуйста.

.... инициализация ....

.....

USART1->CR1 |= USART_CR1_TE;

USART1->CR1 |= USART_CR1_RE;

USART1->CR1 |= USART_CR1_RXNEIE;

.....

Обработчик прерывания (отправляет/принемает в буфер)

....

void USART1_IRQHandler(void)

{

if((USART1->SR & USART_SR_RXNE)) //Если прием

{

USART1->SR &= ~USART_SR_RXNE; //сброс флага

rx1_buffer[rx1w] = USART1->DR ; // сохраняем байт в буфер

if(rx1w >= (RX1_BUFFER_SIZE - 1)) //

{

rx1w = 0; //

} else {

rx1w++; //

};

};

if((USART1->SR & USART_SR_TXE)) //по опустошению

{

USART1->SR &= ~USART_SR_TXE; //сброс флага

USART1->DR = tx1_buffer[tx1r];

if(tx1r >= (TX1_BUFFER_SIZE - 1)) //

{

tx1r = 0; //

} else {

tx1r++; //

};

tx1_count++;

if(tx1_count == TX1_BUFFER_SIZE) USART1->CR1 &= ~USART_CR1_TXEIE; //Если все отправили -

выключаем прерывание на отправку

}

}

USART1.ZIP

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


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

Не скажу точно по этому контроллеру, но, как правило, регистра состояния прерывания в самом начале читается в отдельную переменную

В конце прерывания нужно еще делать

 

VICVectAddr = 0; /* Acknowledge Interrupt */

 

но это для ARM7 NXP

 

ну или в любом случае сбрасывать флаг прерывания. Как он сбрасывается - чтением регистра состояния или обнулять нужно конкретные биты - лезем в даташит в VIC

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


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

Написано, что флаг сбрасывается при чтении регистра. Но я его еще на всякий случай сбрасываю:

USART1->SR &= ~USART_SR_RXNE; //сброс флага

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


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

Но я его еще на всякий случай сбрасываю:

USART1->SR &= ~USART_SR_RXNE; //сброс флага

Интересно на какой случай?

 

Написано, что флаг сбрасывается при чтении регистра.

Так же написано такое:

This clearing sequence is recommended only for multibuffer

communication.

 

P.S. Интересно что такое "multibuffer communication"?

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


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

У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция.

Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана.

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


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

У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция.

Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана.

прочь, мухи, прочь! даешь котлеты!

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


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

STM32F100 UART1 когда уходит на прерывание - зависает.

 

Как зависает? Вываливается в Hard Fault или зацикливается в обработчике?

 

Попробуйте считывать статус-регистр в буффер, потом уже с буфера проверять, установлены ли флаги. Вот работающий пример, проверьте, может где-то ошиблись:

 

void init_uart()
{
RCC->APB2ENR|= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций GPIO.
RCC->APB2ENR|= RCC_APB2ENR_USART1EN; // Включение тактирования USART1.
GPIOA->CRH |= GPIO_CRH_MODE9; // Вывод TX PA.9 - на выход.
GPIOA->CRH &=~GPIO_CRH_CNF9; GPIOA->CRH |=GPIO_CRH_CNF9_1; // Альтернативный выход.
USART1->CR1 |=(USART_CR1_RE | USART_CR1_TE); // Разрешить выводы RX, TX.
	  // Скорость 9.6 kbps. USARTDIV=FSYS/(16*baud) = 24e6/(16*9600)=156.25
USART1->BRR=(156<<4); // Целая часть коэффициента деления USART1. 
USART1->BRR|=4; // Дробная часть*16 = 0,25*16 = 4.
USART1->CR1 |=USART_CR1_UE; // Включение USART1.
USART1->CR1 |=USART_CR1_RXNEIE; // Разрешить прерывания  RXNE.
NVIC_EnableIRQ(USART1_IRQn); // Разрешить прерывание USART1_IRQn в NVIC.
NVIC_SetPriority(USART1_IRQn, 3); //Задать приоритет прерыванию
}

void USART1_IRQHandler (void) // Обработчик USART1.
{
uint16_t status = USART1->SR;
if (status & USART_SR_RXNE)// Если прерывание по приёму.
 	{
	....
	}		 
else	if (status & USART_SR_TXE) // Если прерывание по осовобождению передатчика.
	{
   	....
	}
USART1->SR&=~(USART_SR_TXE|USART_SR_RXNE); //очистка флагов
}

void begin_uart_transm()
{
USART1->CR1 |=USART_CR1_TXEIE;
}

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

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


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

У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция.

Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана.

kan35, Именно так. Спасибо. Как только добавил startup_stm32f10x_ld_vl.s в проект все заработало.

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


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

kan35, Именно так. Спасибо. Как только добавил startup_stm32f10x_ld_vl.s в проект все заработало.

тогда мне непонятно. Зачем подключать s-файл с объявленными именами обработчиков прерывания? разве недостаточно описать функцию с __irq и прописать ее в VIC?

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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