1.到底使用哪种方式,或者说有哪几种方式?
STM32 中的 UART 允许使用不同的发送 ( TX
) 和接收 ( RX
) 模式进行配置,有什么区别和优势?:
- 轮询模式(简单来说就是无 DMA,无 IRQ,在循环里不断的读取)
- 原理:不断地轮询状态位看看是否传输/接收到任何字符,然后可以快速的读取
- 好处1: 易于实现,只需很少的代码行。
- 坏处1:如果mcu的频率不够快地读取寄存器,在较为复杂的应用程序中很容易错过接收到的数据。
- 坏处2:仅适用于比较低的波特率,
9600
或更低,否则可能丢失数据。
- 中断模式(简单地说就是收到一个触发一次中断,不使用 DMA)
- 原理: UART 触发中断,然后跳转到中断处理每个接收到的字节
- 好处1:嵌入式应用中常用的方法
- 好处2:适用于常见的波特率,
115200
最高~921600
波特率 - 坏处1:中断服务程序为每个接收到的字符执行
- 坏处2:如果在高速时波特率的每个字符都触发中断,就有可能降低系统性能
- DMA模式
- 原理:DMA 用于在硬件级别将数据从 USART RX 数据寄存器传输到用户内存。此时不需要设计函数获取,当需要处理时再处理接收到的数据;
- 原理:从 USART 外设到内存的传输是在硬件级别完成的,无需 CPU 交互
- 好处1:可以很容易地与操作系统一起工作
- 好处2:针对最高波特率
> 1Mbps
和低功耗应用进行了优化 - 好处3:如果出现大量数据突发,增加数据缓冲区大小可以改善功能
- 坏处1: DMA 硬件必须事先知道要传输的字节数(可接收不定长,但是,要有范围)
- 坏处2:如果通信失败,DMA 可能不会通知应用程序所有已传输的字节
2.HAL库的函数为什么直接调用有时可以有时不行?
1.HAL的函数库只提供基本的使用流程,但是并不能符合所有的要求。
2.尤其是上述的三种方式中的最后两种,需要使用中断进行操作,这时候每个人的需求就不一样了。有些需要空闲,有些需要收取到数据等等,
3,HAL库的基本函数并没有包含所有的想法,有时候需要使用__HAL开启中断宏进行补充。附上宏函数名称:
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
3.我怎么知道有哪些中断?
1.看手册,推荐
2.看调试窗口的简介
3.看svd文件,在HAL的包下面,但是不推荐。
4.我怎么知道用哪些中断?
根据不同的方法,然后收取思路有一个清晰的认识,就知道用哪些中断,可以参考网络上的教程,但是切记,请勿照抄。
5.我遇到问题,但是找不到答案,怎么办?
1.Keil中可以在debug中查看外设寄存器
2.Clion中可以在debug中加载svd之后查看外设中的寄存器
3.在行为操作后打断点,然后查看外设寄存器中的中断部分。一般的问题就会浮现。
4.思考当前的操作是否会出现当前的中断问题。
5.代码精简,然后进行测试。
6.跟踪HAL库,查看库的流程(重要)
6.我的UART为什么卡死了?为什么发一条卡死了?为什么发长了卡死了?为什么1个字节卡死了?为什么启动就卡死了?
排查流程:
- 打开外设寄存器
- 看ORE
- 看RXNEIE
- 看IDLEIE
- 不要在中断函数里处理数据!!!!!!!!!!!!!!!!!!!
7.我的UART为什么无法进入中断?为什么接收不到数字?
排查流程:
- 打开外设寄存器CR1
- 看UE
- 看RE
- 看TE
- 看是不是用了print 函数?
- 看看是不是自己定义了中断函数?
8.看了上述寄存器但是不知道到底有没有问题?
- 百度/google
- 手册
- 理解流程之后才能知道到底有没有问题。
9.为啥一发数就跑飞了
- 看看初始化
- 看看代码
- 看看是不是内存引用失效等等
- rtos有没有使用互斥量防止串口共用?
10.我用RTOS为啥接收有问题
1.不要在中断函数里处理数据!!!!!!!!!!!!!!!!!!!
2.合理使用信号量,队列,邮箱等方法。
3.部分rtos需要使用特殊的函数通知任务,请参考rtos手册
4.合理使用与调度相关的临界区、调度锁等,否则任务不调度,没人处理你的数据。
11.为啥我收到的数奇奇怪怪??
1.看看数据处理方式,考虑一下完整的数据读取。
2.看看buf的容量,有没有被覆盖
3.看看有没有其他地方的内存溢出,覆盖了你的buf区域
4.打开内存查看器一直看,大概就知道问题所在。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)