STM32F103 5個串口同時使用

硬件平臺:STM32F103(自帶5串口)

5個串口同時工作不丟包-_-

相關宏定義

typedef enum
{
    UartPort1,
    UartPort2,
    UartPort3,
    UartPort4,
    UartPort5,
    UartPort_USB,
}UARTPORT;

#define   RXTIMEOUT    10         // 接收超時時間,如10mSec內未接收任何數據,當作一個接收包
#define   UART_TXBUFFERLEN  0x100         //發送緩衝區大小
#define   UART_RXBUFFERLEN  0x400          //接接緩衝區大小

typedef struct
{
    //接收
    volatile Uint       rxHead;
    volatile Uint       rxTail;
    volatile Uchar      rxBuf[UART_RXBUFFERLEN];
    volatile Uchar      rxTimeOut_Base;
    volatile Uchar      rxTimeOut;

    //發送
    volatile Uint       txHead;
    volatile Uint       txTail;
    volatile BOOLEAN    txEmpty;
    volatile Uchar      baudrate;
    volatile Uchar      txIdleTimeOut;
    volatile Uchar      txIdleTimeOut_Base;
    volatile Uchar      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;

串口1初始化

    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);

串口2初始化

    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);

串口3初始化

    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);

串口4初始化

    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);

串口5初始化

    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);

中斷處理


void USART_Irq_Function(UART_STRUCT *uart,USART_TypeDef *uartdef)
{
    //接收到數據USART_ GetITStatus
    while (USART_GetITStatus(uartdef, USART_IT_RXNE))
    {
        Uchar temp;

        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;
        }
    }
    //發送數據
    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
}

超時檢查

//函  數:檢查是否有收到數據包,1ms調用一次
//參  數無
//返  回:無
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
}
發佈了36 篇原創文章 · 獲贊 23 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章