查看: 9889|回复: 20

[分享] 串口接收不定长数据帧算法

[复制链接]
  • TA的每日心情

    2017-1-4 08:05
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    85

    主题

    1629

    帖子

    1

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2569

    优秀版主

    最后登录
    2019-3-28
    发表于 2016-12-6 16:02:33 | 显示全部楼层 |阅读模式
    /******************************************************************************************
        发现很多网友不会用单片机接收RS485数据帧(无规律的不定长数据帧),其实这个问题并不难,如
    果用K6X这类芯片,串口自带IDLE中断的,关于什么是IDLE中断,请找度娘。但对于KL系列的芯片是没有
    这个功能的。那就是我今天分享的方法,用一个定时器做辅助,即使你100个串口也是占用一个定时器资
    源,说下思路:
        众所周知,串口无论接收多少数据,都是一个字节一个字节读进去的。我们通过判断接收字节之间的
    时间即可判断出是否接收完成。具体的看代码吧。需要资源提供一个1-2ms的中断即可。啰嗦几句对于定时
    器这类宝贵的资源,要合理的使用。代码没编译,只是写了一下逻辑流程。
    ******************************************************************************************/
    #define REVMAXSIZE        128
    #define MAX_COUNT_VALUE 0xFFFFFFFF
    volatile uint32_t SysTimeCount  = 0;
    typedef struct{
            uint8_t  RevBuff[REVMAXSIZE];
            uint8_t  RevFlag;
            uint16_t RevSize;
            uint32_t RevTime;
    }USART_RevInfo;

    USART_RevInfo RevInfo;

    void HardtimerInterruptCallBack(void)
    {
            SysTimeCount ++;
    }

    uint32_t GetSysTimeCount(void)
    {
           
            return SysTimeCount;
    }


    int DiffentSysTimeCount(uint32_t Start,uint32_t End)
    {

            uint32_t dwValue;

            if (End >= Start)
            {
                    dwValue = End - Start;
            }
            else
            {
                    dwValue = MAX_COUNT_VALUE + End - Start;
            }

            return dwValue;
    }

    void USARTInterruptCallBack(uint8_t inData)
    {
            if(RevInfo.RevSize < REVMAXSIZE)
            {
                    RevInfo.RevBuff[RevInfo.RevSize++] = inData;
                    RevInfo.RevTime = GetSysTimeCount();
                    RevInfo.RevFlag = 0xff;
            }
    }

    int USARTRevLoop(uint32_t TimeOut,uint8_t *outData,uint16_t *Size)//main_loop
    {
            if(RevInfo.RevFlag = 0xff)
            {
                    if(DiffentSysTimeCount(RevInfo.RevTime,GetSysTimeCount()) >= TimeOut)
                    {
                            memcpy(outData,RevInfo.RevBuff,RevInfo.RevSize);
                            *Size = RevInfo.RevSize;
                            memset(RevInfo,0,sizeof(USART_RevInfo));
                           
                            return 1;
                    }
            }
            else
                    return 0;
    }


    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-11-30 16:16
  • 签到天数: 206 天

    连续签到: 1 天

    [LV.7]常住居民III

    74

    主题

    2793

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    7908
    最后登录
    2025-4-11
    发表于 2016-12-6 18:18:25 | 显示全部楼层
    IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。
    来根华子
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2021-11-30 16:16
  • 签到天数: 206 天

    连续签到: 1 天

    [LV.7]常住居民III

    74

    主题

    2793

    帖子

    5

    金牌会员

    Rank: 6Rank: 6

    积分
    7908
    最后登录
    2025-4-11
    发表于 2016-12-6 18:18:54 | 显示全部楼层
    老哥稳,感谢分享
    来根华子
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-1-21 08:52
  • 签到天数: 861 天

    连续签到: 1 天

    [LV.10]以坛为家III

    75

    主题

    2523

    帖子

    24

    金牌会员

    Rank: 6Rank: 6

    积分
    5867
    最后登录
    2025-1-22
    发表于 2016-12-6 20:38:57 | 显示全部楼层
    谢谢分享,
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2017-11-15 10:33
  • 签到天数: 79 天

    连续签到: 1 天

    [LV.6]常住居民II

    89

    主题

    2169

    帖子

    3

    金牌会员

    Rank: 6Rank: 6

    积分
    1779
    最后登录
    2020-8-22
    发表于 2016-12-6 21:12:23 | 显示全部楼层
    谢谢分享
    签到
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16860
    最后登录
    1970-1-1
    发表于 2016-12-6 21:26:17 | 显示全部楼层
    多谢分享
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16860
    最后登录
    1970-1-1
    发表于 2016-12-6 21:27:32 | 显示全部楼层
    之前ST上有个断帧检测的分享,使用DMA,思路也可用
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2017-1-4 08:05
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    85

    主题

    1629

    帖子

    1

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    2569

    优秀版主

    最后登录
    2019-3-28
     楼主| 发表于 2016-12-7 07:59:31 | 显示全部楼层
    lkl0305 发表于 2016-12-6 21:27
    之前ST上有个断帧检测的分享,使用DMA,思路也可用

    DMA不错,但是比不是所有的片子都有,就像不是所有牛奶都叫特仑苏一样
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    35

    主题

    356

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3305
    最后登录
    2023-6-23
    发表于 2016-12-7 21:39:46 | 显示全部楼层
    IDLE和断帧的概念不同
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2016-12-30 14:34
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    0

    主题

    35

    帖子

    0

    注册会员

    Rank: 2

    积分
    134
    最后登录
    2017-9-15
    发表于 2016-12-8 09:15:21 | 显示全部楼层
    支持,感谢lz分享
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-9-4 14:16 , Processed in 0.104865 second(s), 28 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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