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;
}
相关推荐
a11177624 分钟前
工业视觉软件入门:VisionMaster(VM)、HALCON、VisionPro
嵌入式硬件·数码相机
Kisorge40 分钟前
【电机控制器】 基于STSPIN32G4的FOC控制
stm32·嵌入式硬件·算法
LCMICRO-133108477461 小时前
国产长芯微LD3092完全pin-pin替代LT3092,是一款可编程两端电流源
arm开发·单片机·嵌入式硬件·fpga开发·硬件工程·恒流源·lt3092
nuoxin1142 小时前
BL-M8812CU3 无线 WiFi 模块-富利威
人工智能·嵌入式硬件·fpga开发·硬件工程·dsp开发
z20348315202 小时前
Livox Mid-360S点云图录制
嵌入式硬件·雷达·ros2
JNX_SEMI3 小时前
Hi5000Q/H 6.5~75V宽输入——与H5227A完全对等,无缝适配现有电源方案-聚能芯-智芯官方授权一级代理
驱动开发·单片机·嵌入式硬件·物联网·硬件工程
哥不想学算法3 小时前
STM32零基础教程(五):UART串口通信与协议设计
stm32·单片机·嵌入式硬件
WWJA王文举3 小时前
STM32时钟树怎么看?一步理解SYSCLK、HCLK、PCLK和外设时钟配置
stm32·单片机·嵌入式硬件
十月的皮皮3 小时前
STM32从零到量产开发:四路继电器工业控制模块开发 - 上位机操作说明书
c语言·stm32·单片机·stm32cubemx
ShiMetaPi4 小时前
ShiMetaPi-Pico-G1快速入门:04 系统登录
stm32·单片机·嵌入式硬件