13406|49

4996

帖子

19

TA的资源

裸片初长成(初级)

楼主
 

单片机之串口数据处理 [复制链接]

 
随着硬件系统的模块化发展,很多电子产品都做出模块并采用串口进行数据通信。例如:GPRS模块、GPS模块、语音模块、热敏微型打印机、串口摄像头等等。在与这些模块进行数据通信都离不开串口,而对于串口的操作,由于串口本身没有标准的通信协议,所以很难做到非常统一的操作过程。一般来说,不同的模块其有着特殊的通信协议,我们只能根据其协议进行数据解码。

      虽然说串口没有标准协议,但是我们却可以把它们的相似部分提取出来,做成模块化的程序,方便代码的移植和理解。下面我们简单谈到串口数据的处理方法。。。。。
此帖出自NXP MCU论坛

最新回复

Mark ,有空再详细看。  详情 回复 发表于 2015-9-22 08:25
点赞 关注(4)
个人签名我的博客
 

回复
举报

4996

帖子

19

TA的资源

裸片初长成(初级)

推荐
 
这部分代码为应用代码

为了保证数据的相对独立和模块化,下面代码将写入应用代码中,和上面的程序不能放在相同的文件中。

1. 数据定义

     首先需要定义一个缓冲区,这个缓冲区的大小根据实际应用定义,其大小一般为数据帧的最大值的2倍。之后需要定义一个DF_RCV数据,在这个数据中需要初始化这个结构图的参数。特别需要注意,缓冲的大小,和缓冲区指针赋值。
  1. u8 AU_Buf[AU_BUF_ZISE] = {0};
  2. DF_RCV AU_Rvc = {0, 0, AU_BUF_ZISE, AU_Buf};
复制代码
2. 编写数据接收函数

    本函数把串口数据放入缓冲区中,此函数必须在串口中断中调用。
  1. /**************************************************************************************
  2. * FunctionName   : AURcvDat()
  3. * Description    : 串口数据接收(串口中断服务调用)
  4. * EntryParameter : None
  5. * ReturnValue    : None
  6. **************************************************************************************/
  7. void AURcvDat(u8 dat)
  8. {
  9.     DFWriteByte(dat, &AU_Rvc);
  10. }
复制代码
3. 数据处理函数

    本函数判断缓冲区中是否有数据,如果有,逐个读取并处理。
  1. /**************************************************************************************
  2. * FunctionName   : AUTaskCtrl()
  3. * Description    : 通信数据处理
  4. * EntryParameter : None
  5. * ReturnValue    : None
  6. **************************************************************************************/
  7. void AUTaskCtrl(void)
  8. {
  9.     u8  tmpDat;
  10.     u16 i, len = 0;
  11.     static u8 sendMark = 0;

  12.     len = DFGetLen(&AU_Rvc);                                                    // 获取未读数据长度
  13.     for (i=0; i < len; i++)
  14.     {
  15.         tmpDat = DFReadByte(&AU_Rvc);                                           // 读一字节数据
  16.         AU_PrcRcvDat(tmpDat);
  17.     }
  18. }
复制代码

[ 本帖最后由 zhaojun_xf 于 2013-8-23 13:24 编辑 ]
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

沙发
 
串口数据处理流程:



此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

板凳
 
一般来说,串口数据的接收都是采用中断方式,中断中只复制把串口发送的数据放入数据缓冲区中。而发送一般都是采用查询方式比较方便。不管是与什么设备通信,这一点完全是一致的。所以,我们完全可以把这部分代码独立起来。

定义数据结构如下:
  1. typedef struct
  2. {
  3.     u16 WtCnt; // 写指针
  4.     u16 RdCnt;// 读指针
  5.     u16 BufLen;缓冲尺寸
  6.     u8  *RwBuf;// 读写缓冲

  7. } DF_RCV;
复制代码
对于这个结构来说非常简单,参数1是用于结束数据计数,参数2为处理数据计数,参数3为缓冲的大小,参数4为缓冲区指针,这里用指针是为了保证这个结构的独立,否则无法满足各种需求。
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

4
 
实现函数:

1. 初始化函数

    本函数用于对串口结构体中的各种数据进行初始化。
  1. /**************************************************************************************
  2. * FunctionName   : DFInit()
  3. * Description    : 初始化
  4. * EntryParameter : None
  5. * ReturnValue    : None
  6. **************************************************************************************/
  7. void DFInit(DF_RCV *pRcv)
  8. {
  9.     u16 i;
  10.    
  11.     pRcv->WtCnt = 0x0000;
  12.     pRcv->RdCnt = 0x0000;
  13.    
  14.     for (i=0; iBufLen; i++)
  15.     {
  16.         pRcv->RwBuf[i] = 0x00;
  17.     }
  18. }
复制代码
2. 接收一字节数据

    本函数用于把串口中断接收的数据放入数据缓冲区中,并且接收计数器加1.
  1. /**************************************************************************************
  2. * FunctionName   : DFWriteByte()
  3. * Description    : 数据接收(接收中断调用)
  4. * EntryParameter : None
  5. * ReturnValue    : None
  6. **************************************************************************************/
  7. void DFWriteByte(u8 dat, DF_RCV *pRcv)
  8. {
  9.     pRcv->RwBuf[pRcv->WtCnt] = dat;                                                    // 数据存入
  10.    
  11.     if (++(pRcv->WtCnt) >= pRcv->BufLen)                                            // 缓冲判断
  12.     {
  13.         pRcv->WtCnt = 0;
  14.     }
  15. }
复制代码
3. 读取一字节数据

    本函数用于从接收缓冲区中读取未处理的一字节数据,读计数器加1.
  1. /**************************************************************************************
  2. * FunctionName   : DFReadByte()
  3. * Description    : 从接受缓冲中读取一字节数据
  4. * EntryParameter : None
  5. * ReturnValue    : 返回读取数据
  6. **************************************************************************************/
  7. u8 DFReadByte(DF_RCV *pRcv)
  8. {
  9.     u8 val = 0x00;
  10.    
  11.     val = pRcv->RwBuf[pRcv->RdCnt];                                             // 读取一字节
  12.     if (++(pRcv->RdCnt) >= pRcv->BufLen)
  13.     {
  14.         pRcv->RdCnt = 0;                                                        // 清零
  15.     }
  16.    
  17.     return val;                                                                   // 返回数据
  18. }
复制代码
4. 获取缓冲区中未处理数据的长度

    本函数用于读取串口缓冲区中还未处理的数据的大小。
  1. /**************************************************************************************
  2. * FunctionName   : DFGetLen()
  3. * Description    : 获取缓冲区中未读数据长度
  4. * EntryParameter : None
  5. * ReturnValue    : 返回数据长度
  6. **************************************************************************************/
  7. u16 DFGetLen(DF_RCV *pRcv)
  8. {
  9.     return ((pRcv->WtCnt >= pRcv->RdCnt) ? ((pRcv->WtCnt - pRcv->RdCnt)) :
  10.            ((pRcv->WtCnt + pRcv->BufLen) - pRcv->RdCnt));
  11. }
复制代码
有了以上几个函数,串口的处理就非常简单了。这几个函数可以应用到任何串口中,也可以应用到任务微处理器上,一致非常简单,应用也非常方便。下面我们说说实际的应用。
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

6
 
函数AU_PrcRcvDat(tmpDat)是数据处理函数,首先是数据帧判断,如果是一帧数据,就进行相应操作,并把操作结果返回。了解了这个过程,串口的编程就变得非常简单。而且我们在读程序时,只要看懂一个串口处理过程,其他串口的程序就自然懂了,非常方便吧。
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

177

帖子

20

TA的资源

一粒金砂(高级)

7
 
感谢分享
此帖出自NXP MCU论坛

点评

本以为很有用的东西,发现很少有人看:@:  详情 回复 发表于 2013-8-26 11:07
 
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

8
 

回复 7楼fanlly 的帖子

本以为很有用的东西,发现很少有人看
此帖出自NXP MCU论坛

点评

老大,下次应该结合某个东东来讲,弄点现象啥的比较形象:lol :lol :lol  详情 回复 发表于 2013-8-26 20:25
哈哈:Laugh: :Laugh: :Laugh:  详情 回复 发表于 2013-8-26 20:16
大师,能留个Q不,我有些问题需要你帮忙,我是想接收从蓝牙发送过来的字符,怎样在单片机进行判断。。。。可以帮忙不  详情 回复 发表于 2013-8-26 11:19
 
个人签名我的博客
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

9
 

回复 8楼zhaojun_xf 的帖子

大师,能留个Q不,我有些问题需要你帮忙,我是想接收从蓝牙发送过来的字符,怎样在单片机进行判断。。。。可以帮忙不
此帖出自NXP MCU论坛

点评

直接在论坛发吧,我尽快回复你。。。。。  详情 回复 发表于 2013-8-26 11:29
 
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

10
 

回复 9楼Jod_King 的帖子

直接在论坛发吧,我尽快回复你。。。。。
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

11
 
是这样的,我现在将数据通过蓝牙发送到单片机,我要怎样在单片机中判断是否有收到从蓝牙发送过来的数据,如果有,我应该怎样对这些数据进行识别,例如我用蓝牙发送“ABC123”给单片机,我在单片机里面应该怎样读出这个数据?
此帖出自NXP MCU论坛

点评

把所有串口数据接收到缓冲区中,在缓冲区中读取数据,如果有通信协议,先通过协议判断并提取一帧数据,进行处理。如果没有专门的通信协议,按照接收数据直接解码。  详情 回复 发表于 2013-8-26 12:26
 
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

12
 

回复 11楼Jod_King 的帖子

把所有串口数据接收到缓冲区中,在缓冲区中读取数据,如果有通信协议,先通过协议判断并提取一帧数据,进行处理。如果没有专门的通信协议,按照接收数据直接解码。
此帖出自NXP MCU论坛

点评

可以帮我写下例程吗??RXD就是P30,TXD就是P31,我对串口基本都不怎么明白,麻烦你帮我写个例子可以吗?  详情 回复 发表于 2013-8-26 16:53
 
个人签名我的博客
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

13
 

回复 12楼zhaojun_xf 的帖子

可以帮我写下例程吗??RXD就是P30,TXD就是P31,我对串口基本都不怎么明白,麻烦你帮我写个例子可以吗?
此帖出自NXP MCU论坛

点评

他哪来的功夫给你写例子啊:lol  详情 回复 发表于 2013-8-26 22:19
本贴就是一个很好的例子。。。。  详情 回复 发表于 2013-8-26 17:36
 
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

14
 

回复 13楼Jod_King 的帖子

本贴就是一个很好的例子。。。。
此帖出自NXP MCU论坛

点评

恩,可是我看不懂,不知道数据到底存到哪里去了,我要读出来,如果这个数据跟我程序上设置的数据一样,我就让P1.1低电平。你复制下整体的程序我看看可以不  详情 回复 发表于 2013-8-26 18:02
 
个人签名我的博客
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

15
 

回复 14楼zhaojun_xf 的帖子

恩,可是我看不懂,不知道数据到底存到哪里去了,我要读出来,如果这个数据跟我程序上设置的数据一样,我就让P1.1低电平。你复制下整体的程序我看看可以不
此帖出自NXP MCU论坛
 
 
 

回复

3

帖子

1

TA的资源

一粒金砂(初级)

16
 
此帖出自NXP MCU论坛
 
 
 

回复

577

帖子

9

TA的资源

纯净的硅(中级)

17
 

回复 8楼zhaojun_xf 的帖子

哈哈
此帖出自NXP MCU论坛
 
 
 

回复

577

帖子

9

TA的资源

纯净的硅(中级)

18
 

回复 8楼zhaojun_xf 的帖子

老大,下次应该结合某个东东来讲,弄点现象啥的比较形象
此帖出自NXP MCU论坛

点评

这种东东在我的新书上已经有实例了,这里只是总结一些,本人在意的是思维模式,也希望大家能够理解这种方法,授人鱼不如授人渔。  详情 回复 发表于 2013-8-26 21:23
 
 
 

回复

211

帖子

13

TA的资源

一粒金砂(高级)

19
 
学习了,感谢大师分享!
此帖出自NXP MCU论坛

点评

电子行业是件辛苦的差事,能够理解思想的人有发展前途,总希望获取实例的人难于成事。  详情 回复 发表于 2013-8-26 21:24
 
 
 

回复

4996

帖子

19

TA的资源

裸片初长成(初级)

20
 

回复 18楼季夏木槿 的帖子

这种东东在我的新书上已经有实例了,这里只是总结一些,本人在意的是思维模式,也希望大家能够理解这种方法,授人鱼不如授人渔。
此帖出自NXP MCU论坛

点评

授人以渔,再授人以鱼效果更好。:lol :lol  详情 回复 发表于 2013-8-26 21:53
非常感谢你的分享,我就是不懂,所以要麻烦你指教一下,留个Q学习学习可以吗  详情 回复 发表于 2013-8-26 21:38
 
个人签名我的博客
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表