UART的基础知识前面已经介绍过了,本文主要介绍UART的特点以及QuecPython的应用实例。
特点与应用
特点:
-
简单性: UART通信的硬件和编程复杂度相对较低。UART本身通常是在微控制器或其他处理器的硬件中实现的,所以在硬件层面上不需要额外的芯片。
-
无需时钟同步: 因为UART是异步的,所以发送和接收设备不需要共享一个时钟信号。这降低了硬件设计的复杂性。
-
灵活性: UART通信可以调整数据位长度、停止位数量和奇偶校验等参数,以适应不同的通信需求。
-
可靠性: 尽管UART通信没有错误修复功能,但它的奇偶校验能提供一定程度的错误检测。
-
限制: UART的通信速度(波特率)有一定的限制,而且通信速度越高,数据错误的可能性也越大。此外,UART的通信距离通常也有限制,对于很长的距离,可能需要使用RS-422或RS-485等差分信号标准。
应用:
-
嵌入式系统: UART常用于微控制器和其他低级硬件设备的通信,例如传感器、记忆卡、GPS模块等。
-
串行通信: UART可以用于RS-232、RS-422和RS-485接口的串行通信,用于连接如打印机、调制解调器、显示器等设备。
-
电脑硬件: 在早期的电脑硬件中,UART用于鼠标和键盘等外设的接口。
-
电信设备: 在无线通信和电信设备中,UART用于与SIM卡和其他设备通信。
-
蓝牙模块: 在蓝牙模块中,UART用于与主设备进行通信。
-
IOT设备: 在物联网设备中,UART用于低速的设备间通信。
数据流
基于QuecPython EC600U模组介绍UART数据流。
发送数据的数据流:
当软件FIFO中无数据超过500ms时,结束数据传输。
TX通信:发送数据->数据发送完毕发送事件->触发中断->触发回调函数发送事件到对应的线程处理->对应线程触发用户自定义回调函数。
其触发中断类型只有一种:TX_COMPLETE。
接收数据的数据流:
RX通信有两个中断,dma中断(数据接收到64byte),超时中断(接收数据字节数少于64而不产生dma中断的情况,时长40ms)。
其触发中断的类型有两种:RX_ARRIVED 和 RX_OVERFLOW。
当软件FIFO满时,再接收数据会造成数据溢出,出现丢数据问题。溢出的同时会上报RX_OVERFLOW事件。故串口接收数据需要及时处理,否则出现数据丢失,数据接收不全问题,当大量数据传输时,可考虑硬件流控。
RX通信:接收数据满64字节或超时->触发中断->触发回调函数发送事件到对应的线程处理->对应的线程触发用户定义回调函数。
应用示例
主要介绍如何使用 UART 具体的应用示例:
基础收发
QuecPython提供了简化的方法来在通信模组上使用 Python 进行 UART 通信。对于实时应用或需要高效处理 UART 信息的场景,使用回调函数(基于中断)进行 UART 读取是一种非常有效的方法。
实验前需了解UART QuecPython接口,请参考machine.UART
实验步骤:
-
初始化UART
from machine import UART # 初始化 UART1 uart1 = UART(UART.UART1, 115200, 8, 0, 1, 0) -
写入UART
发送数据到 UART 是非常简单的:
uart1.write('Hello UART1') -
使用回调数据读取数据
在 UART 上使用回调函数,通常涉及到设置一个 IRQ(中断请求)来监听 UART 事件,如数据接收。当这些事件触发时,相关的回调函数会被执行。
你需要确保回调函数尽可能短,以减少对其他系统任务的干扰。同时数据来之后,应立即读取,防止底层软件FIFO溢出导致数据丢失
def uart_callback(arg): _queue.put(para[2]) # 设置中断 uart1.set_callback(uart_callback)
示例:
import _thread
import utime
from machine import UART
from queue import Queue
class Example_uart(object):
def __init__(self, no=UART.UART2, bate=115200, data_bits=8,parity=0, stop_bits=1, flow_control=0):
self.uart = UART(no, bate, data_bits, parity, stop_bits, flow_control)
self._queue = Queue(5)
_thread.start_new_thread(self.handler_thread, ())
self.uart.set_callback(self.callback)
def callback(self, para):
print("call para:{}".format(para))
if(0 == para[0]):
self._queue.put(para[2])
def uartWrite(self, msg):
print("write msg:{}".format(msg))
self.uart.write(msg)
def uartRead(self, len):
msg = self.uart.read(len)
utf8_msg = msg.decode()
print("UartRead msg: {}".format(utf8_msg))
return utf8_msg
def uartWrite_test(self):
for i in range(10):
write_msg = "Hello count={}".format(i)
self.uartWrite(write_msg)
utime.sleep(1)
def handler_thread(self):
while True:
recv_len = self._queue.get()
self.uartRead(recv_len)
if __name__ == "__main__":
uart_test = Example_uart()
uart_test.uartWrite_test()
常见问题和故障
UART是一种非常简单和直接的通信协议,但在实际应用中也可能遇到一些问题。以下是一些常见的问题以及可能的故障排查步骤:
1.数据接收不正确或无法接收数据
这可能是由于几种原因引起的,包括:波特率设置错误、硬件连接问题、中断处理程序问题、缓冲区溢出等。故障排查步骤可能包括:
-
检查发送端和接收端的波特率设置是否一致。如果它们的波特率不匹配,可能会导致接收的数据出现错误。
-
检查硬件连接,确保TX和RX线正确连接,并且地线(GND)也要正确连接。
-
如果使用了中断处理程序,确保它能正确地处理接收到的数据,并且不会错过任何数据。
-
检查接收缓冲区。如果缓冲区太小或处理速度太慢,可能会导致数据丢失。可以考虑增大缓冲区或优化处理程序。
2.数据发送不正确或无法发送数据
这可能是由于几种原因引起的,包括:硬件连接问题、发送缓冲区问题、发送程序问题等。故障排查步骤可能包括:
-
检查硬件连接,确保TX线正确连接,并且地线(GND)也要正确连接。
-
检查发送缓冲区和发送程序。确保发送的数据被正确地放入缓冲区,并且发送程序能正确地从缓冲区取出数据并发送出去。
3.通信距离问题
UART通信的距离有限,如果通信距离过长,可能会导致信号衰减,从而影响数据的接收。如果需要在更长的距离进行通信,可能需要使用RS-422或RS-485等差分信号标准。
4.干扰问题
在有电磁干扰的环境中,UART通信可能会受到影响。如果有可能的话,尝试减少电磁干扰,使用屏蔽线来减少干扰或者采用电容滤波以降低噪声和电磁干扰。如果干扰过大,可能需要使用差分信号标准或光电隔离。
在进行故障排查时,一种常见的方法是使用逻辑分析器或示波器来观察UART的信号,这可以帮助确定问题的来源。在软件层面,也可以使用调试工具来观察和分析程序的运行情况。

