STM32xx系列单片机串口数据收发

1. 串口初始化

void ShockWaveHandle_USART2Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    // RCC_APB1PeriphClockCmd: usart2 is hanging under APB1, only usart1 is hanging under APB2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // TX3 - PB10 - ch1
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // RX3 - PB11 - ch1
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;

    GPIO_Init(GPIOA, &GPIO_InitStruct);

    USART2_Configuration();

    NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = PreemptionPriority_0;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = SubPriority_1;

    NVIC_Init(&NVIC_InitStruct);

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    USART_Cmd(USART2, ENABLE);
}

2. 串口中断服务函数

void USART2_IRQHandler(void)
{
    if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        uint8_t data;

        data = USART_ReceiveData(USART2);

        ch1_msg_rx(USART2, data);
    }
}

3. 串口数据接收

void ch1_msg_rx(USART_TypeDef *USARTx, uint8_t receiveData)
{
    UartMsgRecvHandler(USARTx, &ch1_msg[ch1_re], &ch1_re, receiveData);
}

void UartMsgRecvHandler(USART_TypeDef *USARTx, TUartMsg *ptUartMsg, uint16_t *rev, BYTE ucRecvDate)
{
    if (FALSE == (ptUartMsg->ucRecvSta & RECV_FLG_HEAD1)) // Not receive first data (0x55)
    {
        ptUartMsg->ucRecvSta = 0; // set flag

        if (DATA_HEAD_1 == ucRecvDate) // receive first data (0x55)
        {
            ptUartMsg->aucBuf[0] = DATA_HEAD_1;
            ptUartMsg->ucRecvSta |=  RECV_FLG_HEAD1;
        }
    }
    else // 1. receive first data (0x55)
    {
        if (FALSE == (ptUartMsg->ucRecvSta & RECV_FLG_HEAD2)) // Not receive second data (0xAA)
        {
            if (DATA_HEAD_2 == ucRecvDate) // receive second data (0xAA)
            {
                ptUartMsg->aucBuf[1] = DATA_HEAD_2;
                ptUartMsg->ucRecvSta |=  RECV_FLG_HEAD2;
            }
            else
            {
                ptUartMsg->ucRecvSta = 0;
            }
        }
        else // 2. receive second data (0xAA)
        {
            if (FALSE == (ptUartMsg->ucRecvSta & RECV_FLG_LEN)) // not receive third data (cmdLen)
            {
                if ((UART_LEN >= ucRecvDate) && (2 <= ucRecvDate)) // receive third data (cmdLen)
                {
                    ptUartMsg->aucBuf[2] = ucRecvDate;
                    ptUartMsg->ucRecvSta |= RECV_FLG_LEN;

                    ptUartMsg->ucRecvCount = ucRecvDate + 5;
                    ptUartMsg->ucRecvIndex = 3;
                }
                else
                {
                    ptUartMsg->ucRecvSta = 0;
                }
            }
            else // 3. receive third data (cmdLen)
            {
                ptUartMsg->aucBuf[ptUartMsg->ucRecvIndex] = ucRecvDate; // 4. receive cmd data (payload)
                ptUartMsg->ucRecvIndex++;

                if ((ptUartMsg->ucRecvIndex >= ptUartMsg->ucRecvCount)) // 5. receive complete
                {
                    ptUartMsg->bFlagRecv = TRUE;
                    ptUartMsg->ucRecvSta = 0;
                    ptUartMsg->USARTx = USARTx;
                    *rev += 1;
                    if (*rev >= UART_MSG_LEN)
                    {
                        *rev = 0;
                    }
                }
                else
                {
                    ptUartMsg->bFlagRecv = FALSE;
                }
                
            }
        }
    }
}

4. 串口数据接收处理

static void ch1_PackageAnalyze(void)
{
    cmd_TypeDef msg;
    BYTE value;

    taskENTER_CRITICAL();
    msg.cmd_main = ch1_msg[ch1_prc].aucBuf[CMD1_ADDH];
    msg.cmd_main <<= 8;
    msg.cmd_main |= ch1_msg[ch1_prc].aucBuf[CMD1_ADDL]; // get main cmd

    msg.cmd_type = ch1_msg[ch1_prc].aucBuf[CMDTYPE_ADD]; // cmd type high
    msg.cmd_target = ch1_msg[ch1_prc].aucBuf[CMD2_ADD];

    value = ch1_msg[ch1_prc].aucBuf[CMD3_VALUE_INDEX];
    taskEXIT_CRITICAL();

    // receive data format: [head1, head2, msg_len1, msg_len2, cmd_main1, cmd_main2, cmd_type, cmd_target, value, crc1, crc2]
    switch (msg.cmd_main)
    {
        case CMD_31: // 0x06, 0x31
        {
            switch (msg.cmd_type)
            {
                case CMD_TYPE_SET: // 0x02
                {
                    ShockWaveHandle_PowerCtrlAndSetParameterAndWorkingCtrl(CH1_UART, msg.cmd_target, value);
                }
                break;
                case CMD_TYPE_ACK:
                {
                    // TODO
                }
                break;
                default:
                {
                    // TODO
                }
                break;
            }
        }
        break;
        case CMD_32: // 0x06, 0x32, recevi handle shake packet or heart beat first packet
        {
            ShockWaveHandle_HandShakeAndHeartBeatPacketHandle(CH1_UART, msg.cmd_type, msg.cmd_target);
        }
        break;
        case CMD_33: // 0x06, 0x33, receive heart beat seconde packet
        {
            // TODO
        }
        break;
        default:
        {
            // TODO
        }
        break;
    }
    UartMsgRecvFlagClr(&ch1_msg[uart_msg_prc]);
}

void UartMsgRecvFlagClr(TUartMsg *ptUartMsg)
{
    if(NULL == ptUartMsg)
    {
        return;
    }
    ptUartMsg->bFlagRecv = FALSE;
    ptUartMsg->ucRecvSta = 0;
    ptUartMsg->ucRecvCount = 0;
}
相关推荐
善 .3 小时前
单片机的内存是指RAM还是ROM
单片机·嵌入式硬件
超级码农ProMax3 小时前
STM32——“SPI Flash”
stm32·单片机·嵌入式硬件
Asa3193 小时前
stm32点灯Hal库
stm32·单片机·嵌入式硬件
end_SJ5 小时前
初学stm32 --- 外部中断
stm32·单片机·嵌入式硬件
gantengsheng6 小时前
基于51单片机和OLED12864的小游戏《贪吃蛇》
单片机·嵌入式硬件·游戏·51单片机
嵌入式小强工作室7 小时前
stm32 查找进硬件错误方法
stm32·单片机·嵌入式硬件
委员7 小时前
基于NodeMCU的物联网窗帘控制系统设计
单片机·mcu·物联网·智能家居·iot
wenchm7 小时前
细说STM32F407单片机DMA方式读写SPI FLASH W25Q16BV
stm32·单片机·嵌入式硬件
南城花随雪。7 小时前
单片机:实现自动关机电路(附带源码)
单片机·嵌入式硬件
逝灮8 小时前
【蓝桥杯——物联网设计与开发】拓展模块4 - 脉冲模块
stm32·单片机·嵌入式硬件·mcu·物联网·蓝桥杯·脉冲测量