通常,uart为单对单通信,当用到一对多时可以用RS485。然而有时候我们MCU的uart口只剩一个,又要接多个uart的外围芯片,这时如果转成RS485需要加多个485收发器,成本增加,布板空间也要增加。
那么能不能像上图那样直接将多个uart外设接到MCU同一个uart口呢?显然不行。因为uart空闲电平为高电平。当要发送数据时,TX管脚将电平拉低。上图中,MCU发送数据时,MCU的TX管脚拉低电平,此时两个从机的RX均被MCU的TX拉低,意味着从机可以收到MCU发送的数据;但是当从机给MCU发送数据时就出问题了,U3的TX发送数据,将MCU的RX拉低,此时U2的TX未发送数据,仍然在维持高电平,这时MCU的RX所接的两个从机,一个拉低电平,一个拉高电平,显然会出问题。
解决办法其实很简单,给从机的TX串一个二极管即可。如上图所示,当 U4的TX发送数据,将MCU的RX拉低,此时U5的TX未发送数据,仍然在维持高电平,但是由于二极管D2的存在,此时MCU的RX电平会被U4的TX正常拉低,所以此时从机U4可以正常给MCU发送数据了,同理U5也可以正常给MCU发送数据。
这个电路电平逻辑看起来没问题了,但实际应用仍然有个问题,那就是MCU发送的数据所有的从机均可以收到,类似于MCU是以广播形式给从机发送数据。从机怎么确定MCU是不是给自己发送数据呢?这是就需要协议支持了,比如我们给U4定义地址为0X01,给U5定义地址为0X02,MCU发送数据时只需要在数据包中加上地址就可以了,从机收到数据后可以根据数据包中的地址字段来判断数据是不是发送给自己的。
到这里看起来一切都解决了,其实不然。如果从机不支持协议呢?比如从机是同型号的一个uart口的温度传感器,只支持简单的查询命令,该怎么处理?
如上图所示,我们还可以通过MCU的IO口 来控制给特定从机发送数据。当我们要给U8发送数据时,只需要让PA0输出高电平,PA1输出低电平。此时Q2导通,Q1截至;这样MCU的TX输出低电平时就只有U8的RX被拉低,U7的RX仍然维持低电平。反之,给U7发送数据时只需要让Q1导通,Q2截至即可。
最后再啰嗦两句,一般芯片的uart口的TX和RX管脚内部都有上拉。如果芯片内部没有上拉,上面的两种电路都需要在RX管脚外部加上拉来确保空闲电平为高。如果所带从机过多,需要考虑主机TX的下拉能力够不够。
/*
这是一段测试代码
*/
# deb cdrom:[Ubuntu 16.04 LTS _Xenial Xerus_ - Release amd64 (20160420.1)]/ xenial main restricted
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security multiverse
//为了防止系统判断推荐受影响