Hardware platform: STM32F103 (with 5 serial ports)
5 serial ports work simultaneously without packet loss-_-
Related macro definitions
typedef enum
{
UartPort1,
UartPort2,
UartPort3,
UartPort4,
UartPort5,
UartPort_USB,
}UARTPORT;
#define RXTIMEOUT 10 // Receive timeout. If no data is received within 10mSec, it will be considered as a received packet.
#define UART_TXBUFFERLEN 0x100 //Send buffer size
#define UART_RXBUFFERLEN 0x400 //Receive buffer size
typedef struct
{
//take over
volatile Uint rxHead;
volatile Uint rxTail;
volatile Uchar rxBuf[UART_RXBUFFERLEN];
volatile Uchar rxTimeOut_Base;
volatile Uchar rxTimeOut;
//send
volatile Uint txHead;
volatile Uint txTail;
volatile BOOLEAN txEmpty;
volatile Uchar baudrate;
volatile Volatile txIdleTimeOut;
volatile Uchar txIdleTimeOut_Base;
volatile Volatile txBuf[UART_TXBUFFERLEN];
}UART_STRUCT;
static UART_STRUCT uart1;
static UART_STRUCT uart2;
static UART_STRUCT uart3;
static UART_STRUCT uart4;
static UART_STRUCT uart5;
Serial port 1 initialization
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE );
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
/* Configure USART1 Tx (PA9) as alternate function push-pull */
GPIO_InitStruct.GPIO_Pin = PIN_USART1_TXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( PORT_USART1_TXD, &GPIO_InitStruct );
/* Configure USART1 Rx (PA10) as input floating */
GPIO_InitStruct.GPIO_Pin = PIN_USART1_RXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( PORT_USART1_RXD, &GPIO_InitStruct );
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStruct);
/* Enable the USARTx Interrupt */
#if 1
// USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
#endif
USART_Cmd(USART1, ENABLE);
Serial port 2 initialization
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE );
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
/* Configure USART2 CTS (PA0) as input floating */
#if UART2_HARDWARE_FLOW
GPIO_InitStruct.GPIO_Pin = PIN_USART2_CTS;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( PORT_USART2_CTS, &GPIO_InitStruct );
#endif
/* Configure USART2 Rx (PA3) as input floating */
GPIO_InitStruct.GPIO_Pin = PIN_USART2_RXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( PORT_USART2_RXD, &GPIO_InitStruct );
/* Configure USART2 RTS (PA1) as alternate function push-pull */
#if UART2_HARDWARE_FLOW
GPIO_InitStruct.GPIO_Pin = PIN_USART2_RTS;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( PORT_USART2_RTS, &GPIO_InitStruct );
#endif
/* Configure USART2 Tx (PA2) as alternate function push-pull */
GPIO_InitStruct.GPIO_Pin = PIN_USART2_TXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( PORT_USART2_TXD, &GPIO_InitStruct );
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
#if UART2_HARDWARE_FLOW
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS;
#else
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
#endif
USART_Init(USART2, &USART_InitStruct);
#if 1
// USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
#endif
USART_Cmd(USART2, ENABLE);
Serial port 3 initialization
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3, ENABLE );
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
/* Configure USART1 Tx (PC10) as alternate function push-pull */
GPIO_InitStruct.GPIO_Pin = PIN_UART3_TXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( PORT_UART3_TXD, &GPIO_InitStruct );
/* Configure USART1 Rx (PC11) as input floating */
GPIO_InitStruct.GPIO_Pin = PIN_UART3_RXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( PORT_UART3_RXD, &GPIO_InitStruct );
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART3, &USART_InitStruct);
/* Enable the USARTx Interrupt */
#if 1
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
#endif
USART_Cmd(USART3, ENABLE);
Serial port 4 initialization
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_UART4, ENABLE );
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
#if 0
GPIO_InitStruct.GPIO_Pin = PIN_UART4_CTS;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( PORT_UART4_CTS, &GPIO_InitStruct );
// GPIO_ResetBits(PORT_UART4_CTS,PIN_UART4_CTS);
#endif
/* Configure USART1 Tx (PC10) as alternate function push-pull */
GPIO_InitStruct.GPIO_Pin = PIN_UART4_TXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( PORT_UART4_TXD, &GPIO_InitStruct );
/* Configure USART1 Rx (PC11) as input floating */
GPIO_InitStruct.GPIO_Pin = PIN_UART4_RXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( PORT_UART4_RXD, &GPIO_InitStruct );
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(UART4, &USART_InitStruct);
/* Enable the USARTx Interrupt */
#if 1
// USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
#endif
USART_Cmd(UART4, ENABLE);
Serial port 5 initialization
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_UART5, ENABLE );
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
/* Configure USART1 Tx (PC10) as alternate function push-pull */
GPIO_InitStruct.GPIO_Pin = PIN_UART5_TXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( PORT_UART5_TXD, &GPIO_InitStruct );
/* Configure USART1 Rx (PC11) as input floating */
GPIO_InitStruct.GPIO_Pin = PIN_UART5_RXD;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( PORT_UART5_RXD, &GPIO_InitStruct );
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(UART5, &USART_InitStruct);
/* Enable the USARTx Interrupt */
#if 1
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
#endif
USART_Cmd(UART5, ENABLE);
Interrupt handling
void USART_Irq_Function(UART_STRUCT *uart,USART_TypeDef *uartdef)
{
//Receive data USART_ GetITStatus
while (USART_GetITStatus(uartdef, USART_IT_RXNE))
{
Flying tempo;
USART_ClearFlag(uartdef, USART_FLAG_RXNE | USART_FLAG_ORE);
temp = USART_ReceiveData(uartdef);
if (((uart->rxHead + 1) % UART_RXBUFFERLEN) != uart->rxTail)
{
uart->rxBuf[uart->rxHead] = temp;
uart->rxHead = (uart->rxHead + 1) % UART_RXBUFFERLEN;
uart->rxTimeOut = uart->rxTimeOut_Base;
}
}
//send data
if (USART_GetITStatus(uartdef,USART_IT_TXE))
{
// USART_ClearFlag(uartdef, USART_FLAG_TXE);
if (uart->txHead == uart->txTail)
{
uart->txEmpty = TRUE;
USART_ITConfig(uartdef, USART_IT_TXE, DISABLE);
}
else
{
USART_SendData(uartdef, uart->txBuf[uart->txTail]);
uart->txTail = (uart->txTail + 1) & (UART_TXBUFFERLEN - 1);
uart->txIdleTimeOut = uart->txIdleTimeOut_Base;
}
}
}
extern void USART1_IRQHandler(void)
{
USART_Irq_Function(&uart1,USART1);
}
extern void USART2_IRQHandler(void)
{
USART_Irq_Function(&uart2,USART2);
}
extern void USART3_IRQHandler(void)
{
#ifdef INCLUDE_UARTPORT3
USART_Irq_Function(&uart3,USART3);
#endif
}
extern void UART4_IRQHandler(void)
{
#ifdef INCLUDE_UARTPORT4
USART_Irq_Function(&uart4,UART4);
#endif
}
extern void UART5_IRQHandler(void)
{
#ifdef INCLUDE_UARTPORT5
USART_Irq_Function(&uart5,UART5);
#endif
}
Timeout Check
//Function: Check if a data packet has been received, called once every 1ms
//Parameters None
//Return: None
extern void checkUartRxTimeOut()
{
if (uart1.rxTimeOut)
{
if (--uart1.rxTimeOut == 0)
{
pushEvent(evCOM1,uart1.rxHead);
}
}
if (uart2.rxTimeOut)
{
if (--uart2.rxTimeOut == 0)
{
pushEvent(evCOM2,uart2.rxHead);
}
}
if (uart3.rxTimeOut)
{
if (--uart3.rxTimeOut == 0)
{
pushEvent(evCOM3,uart3.rxHead);
}
}
if (uart4.rxTimeOut)
{
if (--uart4.rxTimeOut == 0)
{
pushEvent(evCOM4,uart4.rxHead);
}
}
if (uart5.rxTimeOut)
{
if (--uart5.rxTimeOut == 0)
{
pushEvent(evCOM5,uart5.rxHead);
}
}
if (uart1.txIdleTimeOut) uart1.txIdleTimeOut--;
if (uart2.txIdleTimeOut) uart2.txIdleTimeOut--;
#ifdef INCLUDE_UARTPORT3
if (uart3.txIdleTimeOut) uart3.txIdleTimeOut--;
#endif
#ifdef INCLUDE_UARTPORT4
if (uart4.txIdleTimeOut) uart4.txIdleTimeOut--;
#endif
#ifdef INCLUDE_UARTPORT5
if (uart5.txIdleTimeOut) uart5.txIdleTimeOut--;
#endif
}
Previous article:Basic use of STM32F407 serial port
Next article:STM32F4 USART [library function operation]
Recommended ReadingLatest update time:2024-11-16 18:09
- Popular Resources
- Popular amplifiers
- The STM32 MCU drives the BMP280 absolute pressure sensor program and has been debugged
- DigiKey \"Smart Manufacturing, Non-stop Happiness\" Creative Competition - Small Weather Station - STM32F103 Sensor Driver Code
- LwIP application development practical guide: based on STM32
- FreeRTOS kernel implementation and application development practical guide: based on STM32
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- 【GD32L233C-START Review】4. Porting RT-Thread to GD32L233
- Analog input and output buffers
- XMC4800 ECAT Evaluation Board First Experience - Unboxing Review
- Notes on wiring for st-link and jlink debugging stm32
- Misunderstanding of using XF pin in DSP program interruption during programming
- Share the correct use and maintenance guide of NiMH batteries
- Vicor: Innovative solutions for powering computing applications and data centers
- [Raspberry Pi Pico Review] - USB CDC serial communication (BSP compiled, not MicroPython)
- What should I do if the number of IO pins of the microcontroller is insufficient?
- DSP GPIO Programming