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;
}
相关推荐
balance_rui13 分钟前
FreeRTOS
笔记·stm32
LCG元23 分钟前
STM32实战案例:基于HC-SR04的超声波测距与倒车雷达系统
stm32·单片机·嵌入式硬件
华清远见IT开放实验室1 小时前
智能手表完整项目实现,比赛求职双向加分,基于嵌入式大赛推荐开发板(STM32U5)
stm32·单片机·嵌入式硬件·学习·智能手表·嵌入式大赛
BackCatK Chen1 小时前
STM32保姆级入门教程|第8章:PT100高精度测温实战 + ADS1232驱动 + 24位ADC数据解析(功能超详细+CubeIDE手把手)
stm32·stm32cubeide·高精度测温·ads1232·pt100·24位adc·工业实战
危桥带雨1 小时前
FLASH理论基础
stm32·单片机·嵌入式硬件
进击的小头2 小时前
第18篇:嵌入式电机控制专用外设:正交编码脉冲模块原理与闭环控制应用
arm开发·单片机·嵌入式硬件
feifeigo1232 小时前
STM32 LCD彩色液晶屏显示汉字、英文、数字
stm32·单片机·嵌入式硬件
实在太懒于是不想取名4 小时前
STM32N6的开发日记(4):快速上手LTDC显示图片-让屏幕刷新丝滑流畅
stm32·单片机·嵌入式硬件
实在太懒于是不想取名4 小时前
STM32N6的开发日记(1):上手难度拉满的N6有哪些不同?
stm32·单片机·嵌入式硬件
LingLong_roar4 小时前
keil未指定 PY32F0 具体芯片型号导致编译报错及无法烧录问题
单片机·嵌入式硬件