本帖最后由 netlhx 于 2015-11-15 21:53 编辑 UART在所有的STM32中应该都是标配外设了吧。所以这个讨论应该是适用所有STM32开发板或产品的。 自己设想的东西,未必适合。当然杀猪杀屁股,各有各的杀法,欢迎大家一起讨论. 在HAL出现之前,对UART编程一般来说都是这样子一个步骤:配置UART外设参数及引脚,然后发送或接收数据,或是单个收发,或是通过DMA来收发。不管使用哪种方式,都离不开对状态寄存器的查询来采取相应的处理。不过HAL库函数封装得更加厉害,简化成配置好UART外设后,直接发送或接收就行了,当然在收发完成后,提供了相应的中断函数供用户调用以便处理相应的数据。 过程简化了,但是仔细看函数参数,发现不管是接收还是发送,都是定长的。这样子对于发送来说,问题不大,但接收的话呢,如果碰到不定长的输入数据,就要另行处理了。 以中断接收和发送为例,函数中都有一个指定的长度,也就是说,我们只能实现定长的发送和接收。 进一步跟踪代码发现,如果接收或发送的值没有达到,HAL_UART_RxCpltCallback(huart)函数就不会被调用,而这个函数是提供给用户的中断钩子函数,我们没有办法来处理实际已完成的数据的处理,这个是个大问题! 有代码为证 不过进一步跟踪代码,发现其实中断还是启用了的。在每个接收和发送完成后,都会调用相应的中断处理器,但是不到数据完成,不会调用钩子函数。 所以要实现不定长数据的接收,要么改变HAL库的原代码,要么自己单独监视接收到的每一个字符。这里提供一种效率不是很高的处理方法,使用中断模式来接收单个字符,然后人为设定一个输入结束标志,用回车来做为结束标志是一个比较好的选择。 通过仔细研究HAL处理中断的原理,通过添加一个简单的回调函数,就可以实现该功能,步骤记录如下: 1. 声明回调函数原型 2. 添加回调函数,以weak方式实现,便于用户添加代码 3. 添加用户处理代码 4. 在接收回调完成函数中将收到的数据再发回去,验证正确性。 这里的东西,说白了,就是加入自己的处理机制,一旦检测到回车或换行,这里检测的是0X0D,即回车符,就强制将接收过程结束。以回调的方式来实现用户检测功能,既不破坏原有的HAL功能,又实现了不定长检测。 当然在具体的应用中,可以设计自己的UART通信协议,实现定长数据FRAME的发送和接收,这样就和HAL非常吻合。但这里只是一个尝试! 为测试效果做的一个“复读机”,如下 上面是输入的字符,下面是原样输出的内容。很没有意思的东西,就是一个复读机 其实还有一种方法,利用超时来控制不定长数据接收的计算,只不过需要知道在指定的参数情况下,发送一个字符大致需要多长的时间,然后再通过计算来得到超时的情况。只不过这样做的话,有点舍本逐末了。下面用LA抓的一张图,看看一个字符要多少时间。 参数 一个字符发送的时间 工程文件: |
基础的东西,
多谢分享
我也干过在某个时候把couter改为1,怎么没想到用来做不定长呢