查看: 4401|回复: 11

[求助] 请教KL系列的LPSCI的block接收异常的问题

[复制链接]

该用户从未签到

5

主题

19

帖子

0

注册会员

Rank: 2

积分
73
最后登录
2016-4-5
发表于 2016-2-23 11:36:32 | 显示全部楼层 |阅读模式
本帖最后由 kojidong 于 2016-2-23 11:40 编辑

MCU型号:MKL02Z32VFM4
KSDK_1.2.0
示例代码中有三种接收,lpsci_blocking、lpsci_non_blocking、lpsci_polling
我用的是lpsci_blocking,我想实现接收一帧22字节固定长的数据,希望能处理异常接收,如:不足22字节的接收,继续等待直至接收满22个字节;如果多出22个字节,希望能丢弃22字节后的数据。不足22字节的情况经试验没有问题;超出22字节的接收出现了问题。
void RxComTest(void)函数进行了两次接收22字节。
  1. void RxComTest(void)
  2. {
  3.         uint8_t i = 0;
  4.         uint8_t cmdBuff1[22] = {0};

  5.         PRINTF("\r\n块接收函数测试");
  6.         PRINTF("\r\n第一次测试接收22字节");
  7.         while(kStatus_LPSCI_Success != LPSCI_DRV_ReceiveDataBlocking(BOARD_DEBUG_UART_INSTANCE, cmdBuff1, sizeof(cmdBuff1), 50u));
  8. //        LPSCI_DRV_AbortReceivingData(BOARD_DEBUG_UART_INSTANCE);
  9.         for(i=0; i<sizeof(cmdBuff1); i++)        /* 主板发帧指令到待测MCU板 */
  10.         {
  11.                 PRINTF("\t%2x", cmdBuff1[i]);
  12.         }

  13.         PRINTF("\r\n第二次测试接收22字节");
  14.         while(kStatus_LPSCI_Success != LPSCI_DRV_ReceiveDataBlocking(BOARD_DEBUG_UART_INSTANCE, cmdBuff1, sizeof(cmdBuff1), 50u));
  15.         for(i=0; i<sizeof(cmdBuff1); i++)        /* 主板发帧指令到待测MCU板 */
  16.         {
  17.                 PRINTF("\t%2x", cmdBuff1[i]);
  18.         }
  19. }
复制代码

我向串口发送了两帧39字节的数据(AA 55 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 15 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37),每次发送间隔1S以上,串口打印出来的结果是:
  1. 块接收函数测试
  2. 第一次测试接收22字节: aa        55        23        24        25        26        27        28        29        30        31        32        33        34        35        36        37        15        17        18        19        20
  3. 第二次测试接收22字节: 21        22         6         7         8         9        10        11        12        13        14        15        15        17        18        19        20        21        22        23        24        25
复制代码
很明显,第一次我发出的39个字节中超过22字节并没有被丢弃,进入了第二次接收的缓冲区并被打印出来,奇怪的是第二次接收到的值也并不完全第一次剩余的数据。
曾有人建议增加LPSCI_DRV_AbortReceivingData(BOARD_DEBUG_UART_INSTANCE)函数来将丢弃多余接收到字节,即代码中的第9行。我取消屏蔽这行代码后,仍然发送两次39个同样的字节,打印出来的结果是(测试中只发一次39个字节即打印出如下数据):
  1. 块接收函数测试
  2. 第一次测试接收22字节        aa        55         1         2         3         4         5         6         7         8         9        10        11        12        13        14        15        15        17        18        19        20
  3. 第二次测试接收22字节        21        55         1         2         3         4         5         6         7         8         9        10        11        12        13        14        15        15        17        18        19        20
复制代码



请教大家如何用 LPSCI_DRV_ReceiveDataBlocking()实现接收时将多余的字节丢弃掉?




我知道答案 目前已有11人回答
回复

使用道具 举报

该用户从未签到

124

主题

3600

帖子

0

金牌会员

Rank: 6Rank: 6

积分
5781
最后登录
1970-1-1
发表于 2016-2-23 15:21:04 | 显示全部楼层
根据你的实验结果,你可以试试在LPSCI_DRV_AbortReceivingData指令前,空读一下receive data register中的数据。
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

19

帖子

0

注册会员

Rank: 2

积分
73
最后登录
2016-4-5
 楼主| 发表于 2016-2-23 15:23:51 | 显示全部楼层
FSL_TICS_ZP 发表于 2016-2-23 15:21
根据你的实验结果,你可以试试在LPSCI_DRV_AbortReceivingData指令前,空读一下receive data register中的 ...

请问读receive data register如何操作呢,是在仿真时,查看cmdBuff1[22]中的值吗?
回复 支持 反对

使用道具 举报

该用户从未签到

124

主题

3600

帖子

0

金牌会员

Rank: 6Rank: 6

积分
5781
最后登录
1970-1-1
发表于 2016-2-23 15:26:04 | 显示全部楼层
就是空读取一下UART0_D寄存器
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

19

帖子

0

注册会员

Rank: 2

积分
73
最后登录
2016-4-5
 楼主| 发表于 2016-2-23 15:33:26 | 显示全部楼层
FSL_TICS_ZP 发表于 2016-2-23 15:26
就是空读取一下UART0_D寄存器

能给一个具体的执行语句吗?刚接触freescale,暂时还没深入研究到寄存器的地步
回复 支持 反对

使用道具 举报

该用户从未签到

124

主题

3600

帖子

0

金牌会员

Rank: 6Rank: 6

积分
5781
最后登录
1970-1-1
发表于 2016-2-23 16:48:21 | 显示全部楼层
你的定义一个变量,然后将UART0_D赋值给它
char value.
value=UART0_D;
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

19

帖子

0

注册会员

Rank: 2

积分
73
最后登录
2016-4-5
 楼主| 发表于 2016-2-24 09:52:54 | 显示全部楼层
本帖最后由 kojidong 于 2016-2-24 09:54 编辑
FSL_TICS_ZP 发表于 2016-2-23 16:48
你的定义一个变量,然后将UART0_D赋值给它
char value.
value=UART0_D;

修改后的代码如下:
  1. void RxComTest(void)
  2. {
  3.         uint8_t i = 0, tmp;
  4.         uint8_t cmdBuff1[22] = {0};

  5.         PRINTF("\r\n块接收函数测试");
  6.         PRINTF("\r\n第一次测试接收22字节");
  7.         while(kStatus_LPSCI_Success != LPSCI_DRV_ReceiveDataBlocking(BOARD_DEBUG_UART_INSTANCE, cmdBuff1, sizeof(cmdBuff1), 50u));
  8.         tmp = UART0_D;
  9.         PRINTF("\r\nUART0_D value is %2x\r\n", tmp);
  10.         LPSCI_DRV_AbortReceivingData(BOARD_DEBUG_UART_INSTANCE);
  11.         for(i=0; i<sizeof(cmdBuff1); i++)      
  12.         {
  13.                 PRINTF("\t%2x", cmdBuff1[i]);
  14.         }

  15.         PRINTF("\r\n第二次测试接收22字节");
  16.         while(kStatus_LPSCI_Success != LPSCI_DRV_ReceiveDataBlocking(BOARD_DEBUG_UART_INSTANCE, cmdBuff2, sizeof(cmdBuff2), 50u));
  17.         for(i=0; i<sizeof(cmdBuff2); i++)
  18.         {
  19.                 PRINTF("\t%2x", cmdBuff2[i]);
  20.         }
  21. }
复制代码


打印结果:
  1. 块接收函数测试
  2. 第一次测试接收22字节
  3. UART0_D value is  0
  4.         55        aa         1         2         3         4         5         6         7         8         9        10        11        12        13        14        15        15        17        18        19        20
  5. 第二次测试接收22字节         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0         0
复制代码



执行的操作也是发送上述那39个字节,并且只发一次,两次打印都出来了。UART0_D值为0


回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
发表于 2016-2-24 11:11:46 | 显示全部楼层
kojidong 发表于 2016-2-24 09:52
修改后的代码如下:

楼主你好!
根据lpsci_status_t LPSCI_DRV_AbortReceivingData的描述,这个函数只是用来结束接收函数的。
所以,我认为,既然你的串口数据已经自定义了帧头,可以再设计下你的帧格式。
通常我们规定的帧包含这些东西:帧头(0XAA+0X55),数据长度(后面要接收的数据长度),数据。
帧规定好之后,可以在程序中做帧头识别,一旦检测到0XAA,0X55,然后根据接收到的数据长度去识别后面应该接多少数据,这样就算超出,也可以不关心,不存储到自定义的buff中,直到下次的帧头来临。
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

19

帖子

0

注册会员

Rank: 2

积分
73
最后登录
2016-4-5
 楼主| 发表于 2016-2-24 11:21:49 | 显示全部楼层
FSL_TICS_ZJJ 发表于 2016-2-24 11:11
楼主你好!
根据lpsci_status_t LPSCI_DRV_AbortReceivingData的描述,这个函数只是用来结束接收函数的。 ...

谢谢答复!
你说的先判断帧头再根据接收长度去接收后面的数据的方式和我目前先接收一帧数据再对此帧进行协议解析我觉得只是处理方式不一样,但如何丢弃后面无效的数据才是我说的问题所在。
也就是你说的“这样就算超出,也可以不关心”正是现在的问题所在,"不关心"是希望丢弃后面超出的字节,实际上测试时这些超出帧长度的“不关心”的数据依然进入并影响了第二次接收缓冲区。
回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
发表于 2016-2-24 12:35:31 | 显示全部楼层
kojidong 发表于 2016-2-24 11:21
谢谢答复!
你说的先判断帧头再根据接收长度去接收后面的数据的方式和我目前先接收一帧数据再对此帧进行协 ...

其实KSDK的代码都是封装好的。
如果是你自己直接写的话,会比较灵活一些。
比如在中断中判断记录,如果超出接收的字节,就算接收到,也不存入到缓冲区就行了。
所以,我建议你自己写个底层,不用KSDK封装好的函数。
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

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

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

GMT+8, 2025-7-22 12:58 , Processed in 0.106537 second(s), 30 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

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