реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32F100 USART1 виснет в прерывании. Что делаю не так?, Не получается заставить работать USART1 на прерываниях.
NeoMage
сообщение Jun 11 2012, 19:15
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 5-06-12
Пользователь №: 72 183



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 ( 92.34 килобайт ) Кол-во скачиваний: 12
 
Go to the top of the page
 
+Quote Post
toweroff
сообщение Jun 11 2012, 19:28
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



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

VICVectAddr = 0; /* Acknowledge Interrupt */

но это для ARM7 NXP

ну или в любом случае сбрасывать флаг прерывания. Как он сбрасывается - чтением регистра состояния или обнулять нужно конкретные биты - лезем в даташит в VIC
Go to the top of the page
 
+Quote Post
NeoMage
сообщение Jun 11 2012, 19:46
Сообщение #3





Группа: Новичок
Сообщений: 5
Регистрация: 5-06-12
Пользователь №: 72 183



Написано, что флаг сбрасывается при чтении регистра. Но я его еще на всякий случай сбрасываю:
USART1->SR &= ~USART_SR_RXNE; //сброс флага
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 11 2012, 20:13
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(NeoMage @ Jun 11 2012, 22:46) *
Но я его еще на всякий случай сбрасываю:
USART1->SR &= ~USART_SR_RXNE; //сброс флага

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

Цитата(NeoMage @ Jun 11 2012, 22:46) *
Написано, что флаг сбрасывается при чтении регистра.

Так же написано такое:
Цитата
This clearing sequence is recommended only for multibuffer
communication.


P.S. Интересно что такое "multibuffer communication"?
Go to the top of the page
 
+Quote Post
kan35
сообщение Jun 12 2012, 19:14
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция.
Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Jun 12 2012, 20:28
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(kan35 @ Jun 12 2012, 23:14) *
У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция.
Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана.

прочь, мухи, прочь! даешь котлеты!
Go to the top of the page
 
+Quote Post
ierofant
сообщение Jun 13 2012, 12:28
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 3-02-11
Из: Украина, Киев
Пользователь №: 62 695



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


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

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

CODE
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 - Jun 13 2012, 12:31
Go to the top of the page
 
+Quote Post
NeoMage
сообщение Jun 13 2012, 14:54
Сообщение #8





Группа: Новичок
Сообщений: 5
Регистрация: 5-06-12
Пользователь №: 72 183



Цитата(kan35 @ Jun 12 2012, 23:14) *
У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция.
Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана.

kan35, Именно так. Спасибо. Как только добавил startup_stm32f10x_ld_vl.s в проект все заработало.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Jun 13 2012, 16:06
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(NeoMage @ Jun 13 2012, 18:54) *
kan35, Именно так. Спасибо. Как только добавил startup_stm32f10x_ld_vl.s в проект все заработало.

тогда мне непонятно. Зачем подключать s-файл с объявленными именами обработчиков прерывания? разве недостаточно описать функцию с __irq и прописать ее в VIC?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 04:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01411 секунд с 7
ELECTRONIX ©2004-2016