Всем привет.
Разбираюсь в UARTe на STM32F100.
UART запутился, передачу и прием реализовал на прерываниях по окончанию передачи и приему.
В связи с этим есть вопросы:
Необходимо: Сделать передачу сообщения по событию, например - установке флага при нажатии на кнопку. (в программе message_must_send=1)
Проблема: Если реализовать это в прерывании, то прерывание по окончанию передачи просто напросто не генерируется и не происходит передача.(даже в обработчик не заходит, смотрел в отладчике)
Передача начинается только после того, как был отправлен хотя бы один байт вне обработчика прерывания.Т.е. нажимаю кнопкку на отладочной - ничего не передается, пока через терминал не пошлю любое примитивное соообщение(возвращается эхо, где и происходит отправка сообщения).
Если же первый элемент строки передавать во время установки флага, а все остальные уже в обработчике - все отлично работает.(хоть что-то записать в регистр данных, чтоыб потмо сработало прерывание по окончанию передачи) Но решать таким образом проблему как-то совсем глупо. Я надеюсь, вы мне подскажете поинтереснее варианты её решения.
Код ниже прилагается:
Инициализация:
Код
//инициализация юарта
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_TCIE|USART_CR1_RXNEIE; // Разрешить прерывания TC, RXNE.
NVIC_EnableIRQ(USART1_IRQn); // Разрешить прерывание USART1_IRQn в NVIC.
NVIC_SetPriority(USART1_IRQn, 3); //задать приоритет прерыванию
}
Обработчик:
Код
void USART1_IRQHandler (void) // Обработчик прерывания USART1.
{
if (USART1->SR & USART_SR_RXNE) USART1->DR=USART1->DR; // Если прерывание по приёму, то возвращаем эхо
if (USART1->SR & USART_SR_TC) // Если прерывание по завершению передачи.
{
if(message_must_send==1)
{
if (message[tmp])
{
USART1->DR=message[tmp];
tmp++;
}
else
{
tmp=0;
message_must_send=0;
}
}
USART1->SR&=~(USART_SR_TC|USART_SR_RXNE); // Очистить флаги прерывания.
}
}
Теперь
вопросы:
1. Есть ли какой-то способ программно сгенерировать прерывание по окончанию передачи? Т.е. установить в статус-регистре SR бит ТС? Перерыл всю документацию - такой инфы не нашел.
2. Каким образом лучше производить передачу сообщения - в обработчике прерывания или же в основном цикле?
3. Если описать передачу в основном цикле - есть ли смысл в прерывании по окончанию передачи? Ведь можно просто отслеживать с таким же успехом состояние битов в статус-регистре.
Возможно, получилось несколько сбито и сумбурно, но столько вопросов и предложений вертится в голове, что сразу все и не вспомнишь. Буду очень благодарен за обьяснения и советы.