您的位置 首页 主动

单片机之串口数据处理

随着硬件系统的模块化发展,很多电子产品都做出模块并采用串口进行数据通信。例如:GPRS模块、GPS模块、语音模块、热敏微型打印机、串口摄…

跟着硬件体系的模块化开展,许多电子产品都做出模块并选用串口进行数据通讯。例如:GPRS模块、GPS模块、语音模块、热敏微型打印机、串口摄像头等等。在与这些模块进行数据通讯都离不开串口,而关于串口的操作,因为串口自身没有规范的通讯协议,所以很难做到十分共同的操作进程。一般来说,不同的模块其有着特别的通讯协议,咱们只能依据其协议进行数据解码。

尽管说串口没有规范协议,可是咱们却能够把它们的类似部分提取出来,做成模块化的程序,便利代码的移植和了解。下面咱们简略谈到串口数据的处理办法。。。。。

串口数据处理流程:

一般来说,串口数据的接纳都是选用中止方法,中止中只仿制把串口发送的数据放入数据缓冲区中。而发送一般都是选用查询方法比较便利。不管是与什么设备通讯,这一点完全是共同的。所以,咱们完全能够把这部分代码独立起来。

界说数据结构如下:

  1. typedef struct
  2. {
  3. u16 WtCnt; // 写指针
  4. u16 RdCnt;// 读指针
  5. u16 BufLen;缓冲尺度
  6. u8*RwBuf;// 读写缓冲
  7. } DF_RCV;

仿制代码

关于这个结构来说十分简略,参数1是用于完毕数据计数,参数2为处理数据计数,参数3为缓冲的巨细,参数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. pRcv->WtCnt = 0x0000;
  11. pRcv->RdCnt = 0x0000;
  12. for (i=0; iBufLen; i++)
  13. {
  14. pRcv->RwBuf[i] = 0x00;
  15. }
  16. }

仿制代码

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. if (++(pRcv->WtCnt) >= pRcv->BufLen) // 缓冲判别
  11. {
  12. pRcv->WtCnt = 0;
  13. }
  14. }

仿制代码

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. val = pRcv->RwBuf[pRcv->RdCnt]; // 读取一字节
  11. if (++(pRcv->RdCnt) >= pRcv->BufLen)
  12. {
  13. pRcv->RdCnt = 0; // 清零
  14. }
  15. return val; // 回来数据
  16. }

仿制代码

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. }

仿制代码

有了以上几个函数,串口的处理就十分简略了。这几个函数能够使用到任何串口中,也能够使用到使命微处理器上,共同十分简略,使用也十分便利。下面咱们说说实践的使用。

这部分代码为使用代码

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

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. u8tmpDat;
  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. }

仿制代码

函数AU_PrcRcvDat(tmpDat)是数据处理函数,首要是数据帧判别,如果是一帧数据,就进行相应操作,并把操作成果回来。了解了这个进程,串口的编程就变得十分简略。并且咱们在读程序时,只需看懂一个串口处理进程,其他串口的程序就天然懂了,十分便利吧。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/276026.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部