STM32–USART FIFO
18 Апреля 2011
К комментариям
Перенес реализацию FIFO буфера с STM8L, вроде работает , пока не уверен только на счет правильности в чтении ошибок и при передачи 9-бит нужно поправить код.
Код для проверки работы (простой эхо-ответ):
//-----------------------------------------------------------------------------
int main(void)
{
uint8_t rx_data;
// инициализируем систему тактирования
RCC_Configuration();
// инициализируем контроллер прерываний
NVIC_Configuration();
// настраиваем линии ввода-вывода
PIN_CONFIGURATION(USART1_RXD);
PIN_CONFIGURATION(USART1_TXD);
PIN_CONFIGURATION(PIN_TEST);
// конфигурируем USART1
mcu_usart1_init(38400);
while (1)
{
// ожидаем приема данных
while (mcu_usart1_fifo_receive(&rx_data) & USART_FIFO_NO_DATA)
{
}
// передаем принятый байт
mcu_usart1_fifo_transmit(rx_data);
}
return 0;
}
Реализация самого буфера:
/*
* File: mcu_usat.c
* Date: 18.04.2011
* Denis Zheleznjakov http://ziblog.ru
*/
#include "mcu_usart.h"
struct usart_fifo
{
volatile uint8_t rx_last_error;
volatile uint8_t rx_buffer[USART_RX_BUFFER_SIZE];
volatile uint8_t rx_buffer_head;
volatile uint8_t rx_buffer_tail;
volatile uint8_t tx_buffer[USART_TX_BUFFER_SIZE];
volatile uint8_t tx_buffer_head;
volatile uint8_t tx_buffer_tail;
} usart1_fifo;
//------------------------------------------------------------------------------
void mcu_usart1_init(uint32_t baud_rate)
{
USART_InitTypeDef USART_InitStructure;
// инициализируем буфер
usart1_fifo.rx_buffer_head = 0;
usart1_fifo.rx_buffer_tail = 0;
usart1_fifo.rx_last_error = 0;
usart1_fifo.tx_buffer_head = 0;
usart1_fifo.tx_buffer_tail = 0;
// разрешаем тактирование модуля
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// конфигурируем USART1
USART_InitStructure.USART_BaudRate = baud_rate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl
= USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStructure);
// разрешаем прерывания по приёму
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// разрешаем работу модуля
USART_Cmd(USART1, ENABLE);
}
//------------------------------------------------------------------------------
void mcu_usart1_fifo_transmit(uint8_t data)
{
uint8_t tx_head;
tx_head = (uint8_t)((usart1_fifo.tx_buffer_head + 1) & (uint8_t)(
USART_TX_BUFFER_SIZE - 1));
while (tx_head == usart1_fifo.tx_buffer_tail)
{
}
usart1_fifo.tx_buffer[tx_head] = data;
usart1_fifo.tx_buffer_head = tx_head;
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
//------------------------------------------------------------------------------
void handler_usart1_tx(void)
{
uint8_t tx_tail;
uint8_t tx_head;
tx_head = usart1_fifo.tx_buffer_head;
tx_tail = usart1_fifo.tx_buffer_tail;
if (tx_head != tx_tail++)
{
tx_tail &= USART_TX_BUFFER_SIZE - 1;
usart1_fifo.tx_buffer_tail = tx_tail;
USART1->DR = usart1_fifo.tx_buffer[tx_tail];
}
else
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
//------------------------------------------------------------------------------
uint8_t mcu_usart1_fifo_receive(uint8_t * data)
{
uint8_t rx_head;
uint8_t rx_tail;
rx_head = usart1_fifo.rx_buffer_head;
if (rx_head == usart1_fifo.rx_buffer_tail)
return USART_FIFO_NO_DATA;
rx_tail = (uint8_t)((usart1_fifo.rx_buffer_tail + 1) & (uint8_t)(
USART_RX_BUFFER_SIZE - 1));
usart1_fifo.rx_buffer_tail = rx_tail;
*data = usart1_fifo.rx_buffer[rx_tail];
return usart1_fifo.rx_last_error;
}
//------------------------------------------------------------------------------
void handler_usart1_rx(void)
{
uint16_t status;
uint8_t rx_data;
uint8_t rx_last_error;
uint8_t rx_head;
status = USART1->SR;
rx_data = USART1->DR;
rx_last_error = 0;
if (status & USART_SR_FE)
rx_last_error |= USART_FIFO_ERROR_FRAME;
if (status & USART_SR_ORE)
rx_last_error |= USART_FIFO_ERROR_OVERRUN;
if (status & USART_SR_NE)
rx_last_error |= USART_FIFO_ERROR_NOISE;
rx_head = (uint8_t)((usart1_fifo.rx_buffer_head + 1) & (uint8_t)(
USART_RX_BUFFER_SIZE - 1));
if (rx_head == usart1_fifo.rx_buffer_tail)
{
rx_last_error |= USART_FIFO_ERROR_BUFFER_OVERFLOW;
}
else
{
usart1_fifo.rx_buffer[rx_head] = rx_data;
usart1_fifo.rx_buffer_head = rx_head;
}
usart1_fifo.rx_last_error = rx_last_error;
}
проект целиком (для STM32F103CB):
comments powered by Disqus