cn_x 发表于 2014-9-4 14:04:43

【分享】KL关闭后重启串口不能正常运行解决办法——转帖

本帖最后由 cn_x 于 2014-9-4 14:17 编辑

原文链接:http://blog.sina.com.cn/s/blog_7e76c0810102uypr.html
1. 适用范围
本文所描述现象适合于Kinetis L系列单片机,目前已测试过MKL25Z128VLK4、MKL26Z128VFM4两款芯片。其中MKL25Z128VLK4芯片的测试是基于FRDM-KL25Z开发套件。软件开发平台为Keil Review MDK 4.74 。2. 原理概述2.1      现象描述当UART0在接收数据的时候,如果在这时关闭UART0的串口接收中断,即停止接收数据(此时RXD引脚还有数据输入),那么在再次打开接收中断后,UART0不能进入接收中断继续接收数据。2.2      现象还原2.2.1   还原办法使用两个串口,一个串口作为测试对象,另外一个串口用于与PC进行通信,给MCU发送测试命令。本测试使用UART0作为被测试对象,UART1用于PC机向MCU发送命令。UART0使用端口为PTA1、PTA2,FRDM-KL25Z开发套件已将其通过USB转串口芯片连接到SDA接口上,使用时只需使用USB连接线直接连接到PC机即可。UART1使用端口为PTE0和PTE1,使用时需要外接USB转串口线连接到PC机。UART0采用中断接收方式,并且中断里面回传接收的数据。默认开启接收中断。在关闭UART0的接收中断后再次向UART0发送数据,故意使接收数据溢出。之后打开接收中断,观察UART0能否正常接收数据。UART1也采用中断接收方式,在UART1的中断函数中判断接收命令,并且置位相应的标志位,之后在主函数中根据标志位的变化对UART0进行操作,操作命令及功能如下。除此之外UART1还会回传UART0_SI寄存器的值。UART1发送指令:Ø“A”:关闭串口0接收中断;Ø“B”:开启串口0接收中断;Ø“C”:清除UART0_S1寄存器OR标志位;2.2.2   还原步骤1.         通过UART0向MCU发送字符串“01234567889”,从串口助手接收到数据中可以看出UART0能够正常的回传数据(能够进入接收中断)。2.         通过UART1向MCU发送关闭UART0接收中断命令“A”。3.         再次向UART0发送字符串“abcdef”,从串口助手接收到数据中可以看出UART0并没有回传数据,由此可以推断UART0并没有进入接收中断程序。并且此时UART0_S1寄存器的值变为了0XD8,OR标志位被置位。UART0接收数据有溢出。4.         通过UART1向MCU发送开启UART0接收中断命令“B”。此时可以看到UART0回传了一个字节数据‘a’。此现象是由于UART0_S1接收数据寄存器满标志并没有被清除(因为之前关闭了接收中断,所以没有读数据寄存器),当打开接收中断后就会进入接收中断回传数据。5.         通过UART0向MCU发送字符串“0123456789”,UART0并没有回传数据,因此可以推断UART0并没有进入接收中断程序。因为OR标志位置位,RXD引脚接收到的数据直接丢失。6.         根据MKL25用户手册我们可以得知(如图2.1 ),UART0清除OR的办法是写1清零。发送命令“C”清除UART0_S1寄存器OR标志位,随即可以从UART1回传的数据中得知UART0_S1寄存器的值变为了0XD0,这时再次通过UART0发送数据即可正常的得到返回(能够进入接收中断),UART0恢复正常接收接收状态。
图2 .1   UART0_S1标志位描述2.3      原因及解决办法2.3.1   问题原因:从数据手册中可以得知,UART接收采用的是双缓冲结构,在UART_S1被置位后内核都会有一个字节的时间从数据寄存器中读出数据,在新的接收数据被移入数据寄存器中时,如果上次接收的数据没有被读出,那么UART_S1则会被置位,当OR标志位被置位后,新的串口数据会直接丢失,不会接收。表现形式就是不能够进入接收中断程序继续接收数据。
图2. 2OR标志位描述2.3.2   解决办法:在开启接收中断的同时清除UART0_S1寄存器中的OR标志位。3. 注意事项1.         当OR标志位被置位后,串口将停止接收新的数据,新的数据直接丢失,直到OR标志位被清除。2.         在关闭接收中断后,新数据的第一个字节仍然能够被接收到数据寄存器,当第二个字节到来时才会产生接收数据溢出。3.         UART1、UART2 和UART0的OR标志位清除方法不同如 图3.1 、图3.2 所示,串口1和串口2清除OR标志位的方法是读UART_S1寄存器。而串口0清除OR标志位的方法是写1清零。
图3 .1   UART1_S1、UART2_S1标志位描述
图3 .2   UART0_S1标志位描述4. 参考资料      KL25P80M48SF0RM      Rev. 3, September 2012      FRDM-KL25Z_SCH

mypear 发表于 2014-9-4 14:07:18

图片挂了,建议转帖时,把图拿来这边上传

cn_x 发表于 2014-9-4 14:18:17

mypear 发表于 2014-9-4 14:07
图片挂了,建议转帖时,把图拿来这边上传

OK了,贴上了

yzb1019 发表于 2014-9-4 14:22:42

楼主真是辛苦了,估计发帖的时间还有找资料的时间得花去大半天

RainKing 发表于 2014-9-4 14:24:21

不错....就是有点看不懂.......

bluestone2012 发表于 2014-9-4 14:25:49

楼主真是飞思卡尔的搬运工,资料很好,收下了

mypear 发表于 2014-9-4 14:27:35

cn_x 发表于 2014-9-4 14:18
OK了,贴上了

不错,学习了         

wangpengcheng 发表于 2014-9-4 14:28:19

友情帮顶!

湛泸骏驰 发表于 2014-9-4 14:34:01

帮助楼主,{:lol:}。。也在帮自己。。

zhaotyue 发表于 2014-9-10 08:29:23

谢谢分享!         
页: [1]
查看完整版本: 【分享】KL关闭后重启串口不能正常运行解决办法——转帖