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;
}
相关推荐
Dillon Dong3 分钟前
STM32嵌入式开发:巧用位运算,打造高效参数ID管理方案
stm32·单片机·嵌入式硬件
亿道电子Emdoor10 分钟前
【Arm】Arm DS如何导出Build log文件
stm32·单片机·嵌入式硬件
DIY机器人工房14 分钟前
解决方法:关于上传经纬度绑定到onenet可视化平台地图上位置偏移的问题
stm32·单片机·嵌入式硬件·gps·定位·diy机器人工房
墨染倾城殇26 分钟前
蓝牙车钥匙方案:低功耗蓝牙模块引领科技与生活完美融合
科技·嵌入式硬件·生活·蓝牙模块·低功耗蓝牙·车钥匙解决方案
richxu2025100127 分钟前
嵌入式学习之路>单片机核心原理篇>(14) ARM 架构
arm开发·单片机·学习
清风6666661 小时前
基于单片机的蔬菜大棚温湿度远程测报系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
电子科技圈1 小时前
SiFive车规级RISC-V IP获IAR最新版嵌入式开发工具全面支持,加速汽车电子创新
嵌入式硬件·tcp/ip·设计模式·汽车·代码规范·risc-v·代码复审
民乐团扒谱机2 小时前
十字路口交通信号灯控制器设计(Multisim 电路 + Vivado 仿真)
单片机·fpga开发·verilog·状态机·仿真·时序逻辑·multism
bai5459362 小时前
STM32 CubeIDE 按键控制LED
stm32·单片机·嵌入式硬件
小π军2 小时前
51单片机第2讲:数码管
单片机·嵌入式硬件·51单片机