STM32–USART FIFO
Перенес реализацию 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):
Please enable JavaScript to view the comments powered by Disqus.
comments powered by