实际应用中经常会遇到微控制器(MCU)内置的UART个数不足的情况,通常有几种处理方式可供选择:
-
重新选择一款拥有更多UART的芯片,但这样做会增加成本。 -
外部添加接口转换芯片,例如SPI/I2C转UART芯片。这种方式需要对电路板进行修改,并且会增加成本。 -
选择使用RS485外设来替代RS232外设。这种方式需要进行软件修改,并且有可能改变外部的连接方式,增加了终端电阻。虽然电路板的成本几乎没有太大增加,但外设的成本可能会有所变化。 -
通过GPIO口加定时器的方式来模拟UART。这种方式的好处是可以将任意GPIO分配给芯片,并且不会增加成本。但需要进行软件修改,同时会增加CPU的负荷,特别是在发送/接收过程中,CPU会频繁进入中断,从而增加负荷。 -
利用MCU的引脚复用功能,将一个UART分时应用于不同的引脚,使其看起来像是多个串口。
本文主要介绍了第5种方法,通过这种方法,可以在UART个数受限的情况下,以较低的成本实现多个串口的数据收发。当然,这种方法有一些应用限制:
-
MCU必须作为每个UART数据通信的发起者,也可以认为是UART协议的主设备,每次数据交换都由MCU发起。 -
MCU在发送数据后,必须知道从设备回复数据的超时时间,否则无法判断是否由于数据丢失导致无法查询下一个UART。
以下以NXP Kinetis KW41为例,介绍如何使用UART的分时复用功能:
-
根据Datasheet选择可用的IO口,手册中的Table 52. KW41Z Pin Assignments提供了详细的描述。从图中可以看出,KW41只有一个LPUART0,但它可以复用到38、39、42、43、46、47这三组引脚上,这意味着我们最多可以复用出3个UART:
-
查看芯片管脚复用寄存器,KW41是通过PORTx_PCRn寄存器的MUX位域来进行设置的,但该寄存器写入0x01对应的IO为GPIO,写入0x04对应LPUART0功能:
-
修改软件代码,附件提供一个UART_TDM的例子,main函数中只需要调用初始化函数以及周期处理函数即可:
-
UART_TDM_Init初始化函数中主要是初始化了LPUART:
5.UART_TDM_Process本质上是一个状态机,其中有5种状态,芯片复位后为等待状态,然后等待一个UART0的发送周期进入Send状态,发送数据完毕后,会进入Receive状态,接收完毕后进入Done状态,如果超时没有接收到数据,则进入ReceiveTimeOut状态,进行异常处理,处理完毕后继续进入Done状态,Done状态后会重新进入Wait状态,等待下一个UART口的周期时间,进入第二个串口的周期,依次循环:
typedef enum _uart_tdm_status
{
kUART_TDM_Wait = 0U, /*!
其中有几个用户参数是可以设置的:
#define BOARD_DEBUG_UART_BAUDRATE 115200 //设置波特率`
#define TDM_RING_BUFFER_SIZE 11 //设置Buffer大小以及发送数据的个数
g_u16ReceiveTimeout[UART_TDM_NUMBER] = {100, 100, 100}; //响应超时,Uint ms.
g_u16CycleTime[UART_TDM_NUMBER] = {500, 500, 500}; //访问周期,Uint ms.
g_u16ReceiveTimeout该变量用于判断串口接收是否超时,如果本串口发送完毕后100ms内数据没有接收完成,则认为判断为超时,数据接收完毕的标志在接收中断服务程序中置位,这里仅仅示例,用户可以根据自己协议设置:
g_u16CycleTime该变量用于判断各个串口的发送间隔,当UART0接收(或超时)后,等待g_u16CycleTime[1]的时间后,发送UART1,UART1接收(或超时)后,等待g_u16CycleTime[2]的时间发送UART2,UART2接收(或超时)后,等待g_u16CycleTime[0]的时间发送UART0
extern uint32_t g_u32Timer; 本示例使用PIT生成了1ms的中断,并在中断复位程序中使用g_u32Timer++记录1ms的时间,如果用户希望降低CPU的负荷,可以使用Systick来计算超时。
-
下载并运行程序,如果三个串口都接到PC端,可以在3个终端分别看到HelloUart1,HelloUart2,HelloUart3,如果PC端没有发送任何数据,那么MCU每周期都会进入kUART_TDM_ReceiveTimeOut状态,这样可以计算出每个串口的时间分别是500+100,500+100,500+100,总的周期是1800ms。
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !