硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1000|回复: 4
收起左侧

[技术讨论] 串口解析数据问题

[复制链接]

24

主题

50

回帖

122

积分

初级会员

积分
122
发表于 2024-8-24 09:34:25 | 显示全部楼层 |阅读模式
现在一个问题是我的串口接收了21帧数据,并且这21帧数据是连续接收的,就是说就算在串口的空闲中断中打断点,他21帧数据也会发完,现在这21帧数据接收全了,但是解析的时候没有解析完全,并且我的解析函数就是在主循环中的,上面也没有任何的条件判断,这种情况可能是什么原因造成的呢?

微信图片_20240824092648.png

接收到了全部的数据,但是解析的时候没有解析完全,像是跳着解析的,但是有没有规律

微信图片_20240824092939.png
下面是解析的函数,就在主循环中调用的,没有判断他退出的条件,只有一条就是当串口接收完一帧数据的时候,将标志位flag置为1,只有当flag为1的时候才能往下执行解析程序,搞不懂为什么会解析不全
[C] 纯文本查看 复制代码
static int aBleRecPro(COM_TypeDef com)
{
    int8 pass;
    BLUETOOTH_DWN_DATA_TypeDef dat;
    int i = 0;
    uint16 j;
    uint8_t *s = NULL;
    int count = 0;
    // uint32_t tick = 0;
    if (!bleAppConfig.rxAct)
        return 0;
    // tick = calTim15Tmr(bleAppConfig.tmrResp, &htim15, SYSTEM_CLOCK);
    // if (tick <= CONST_BLE_APP_MAX_FRAM_DLY)
    // {
    //     freeUart3Rx(&bleAppConfig); // 帧未结束
    //     return 0;
    // }
    // adjustFrontToNearestElement(&uart[com].Rx, 0x55);
    if (uart[_COM3].flag == 0)
        return 0;
    uart[_COM3].flag = 0;
    count = QueueLen(uart[com].Rx);
    if (count < MIN_BLUETOOTH_LEN)
        return 0;
    s = (uint8_t *)calloc_mem(count + 1, sizeof(uint8_t));
    if (!s)
        return 0;
    rdBlockQueue(s, &uart[com].Rx, count); // 读取数据
    // 搜寻帧头 有效的帧头 55 A9 - 55 AC || A9 - AC
    for (i = 0; i < count; i++)
    {
        if (s[i] == 0x55)
            break;
    }
    if (i >= count)
    {
        s = (uint8_t *)free_mem(s);
        return 0; // 没有帧头,抛弃
    }
    dat.head = s[i++];
    dat.ctrCode = s[i++];
    if ((dat.ctrCode < 0xA9) || (dat.ctrCode > 0xAC))
    {
        s = (uint8_t *)free_mem(s);
        return 0;
    }
    i += _rdInt16(dat.id, s + i);
    // 地址
    if ((dat.id[0] != myParam.location[0]) && (dat.id[1] != myParam.location[1]))
    {
        s = (uint8_t *)free_mem(s); // ID 错误抛弃
        return 0;
    }

    switch (dat.ctrCode)
    {
    case B_APP_09: // 读取参数
        if ((count - i) < 10)
            break;
        // 读取密码 4B +参数地址 2B + 参数长度 2B + crc 2B
        dat.s = (char *)(&s[i]);
        if (checkCrcBlueTooth(dat, 10))
        {
            sendParamBluetoothToApp(dat);

            // bleAppConfig.tmrRxHold = __HAL_TIM_GET_COUNTER(&htim15);
        }
        break;
    case B_APP_0A: // 写参数
        if ((count - i) < 8)
            break;
        // 读取密码 4B +参数地址 2B + 参数长度 2B
        dat.s = (char *)(s + i);
        _rdInt16(j, dat.s + 6); // 读取长度
        if (j > 6)
            break;
        if ((count - i) < (10 + j))
            break;
        if (checkCrcBlueTooth(dat, 10 + j)) // crc
        {
            // 比较密码
            pass = passwordCompare(&dat.s[0]);
            if (pass)
            {
                wrBlueToothTemp(dat, pass);
            }

            // bleAppConfig.tmrRxHold = __HAL_TIM_GET_COUNTER(&htim15);
        }
        break;
}
    s = (uint8_t *)free_mem(s);
    return i;
}

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-8-25 10:35:50 | 显示全部楼层
帮顶下吧,

看了楼主写的解析代码,这个解析代码捋顺不太容易。
回复

使用道具 举报

102

主题

573

回帖

894

积分

金牌会员

积分
894
QQ
发表于 2024-8-25 20:56:28 | 显示全部楼层
没看懂bleAppConfig.rxAct这个变量是干啥的,也没看到它在哪里被置0。
回复

使用道具 举报

102

主题

573

回帖

894

积分

金牌会员

积分
894
QQ
发表于 2024-8-25 20:58:11 | 显示全部楼层
肯定是你哪里条件没满足return掉了。
你在你解析函数里的每个退出的地方,加个标志打印。
看看是哪里退出的解析就能找到了。
回复

使用道具 举报

5

主题

19

回帖

34

积分

新手上路

积分
34
发表于 2024-8-28 17:52:00 | 显示全部楼层
可以搞个队列,收到数据就入队,解析的时候就出队。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 06:32 , Processed in 0.046372 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表