树莓派最大的魅力就是接口丰富,借助这些开放的接口,可以实现很多好玩又实用的功能,比如通过接口控制电机实现智能小车的动力控制、通过接口控制LED灯珠亮灭给心上人制造IT男独有的浪漫等等。
同时我们也将树莓派用在了一系列智能化改造的项目中,通过树莓派的GPIO进行串口通讯,控制智能电量表、水表、电子阀门等工业设备,将传统工业设备管理升级改造为智能化工业物联网设备管理。这里先给大家介绍一下开启树莓派串口的设置步骤。然后会另起一篇文章,以项目实例的形式通过控制电量表来了解树莓派串口通讯在项目中的应用。
注:文章中的树莓派串口设置,默认使用的是官方系统。第三方系统的串口设置请大家结合这篇文章按第三方系统参数说明自行测试。
基本介绍:
树莓派3/4B有两个串口,分别为“硬件串口” /dev/ttyAMA0 和“mini串口” /dev/ttyS0。“硬件串口”有单独的波特率时钟源,性能高、可靠,“mini串口”性能低,功能也简单,并且没有波特率专用的时钟源而是由CPU内核时钟提供,因此“mini串口”有个致命的弱点是:波特率受到内核时钟的影响,内核若在智能调整功耗降低主频时,相应的这个mini串口的波特率便受到牵连。
其实这里说的时钟的影响对我来说太高深了,对此真的是没有太多的认知,只是查找的相关资料中是这么描述的。那么个人的理解是“硬件串口”是全功能的,而“mini串口”则是阉割过的。
在实际项目中遇到的问题是,如果使用“mini串口” /dev/ttyS0,在通讯需要奇偶校验时会报错。所以项目中为了稳定还是推荐使用“硬件串口” /dev/ttyAMA0 。
在树莓派3/4B中,由于板载蓝牙模块,因此这个“硬件串口”被默认分配给与蓝牙模块通信了,而把“mini串口”默认分配给了排针引出的GPIO Tx Rx。在开启串口通讯不做任何设置的时候,默认的串口通讯使用的是“mini串口”。如果要在项目中使用,为了通讯稳定,需要进行“硬件串口”与“mini串口”默认映射对换,把“硬件串口” /dev/ttyAMA0映射分配给GPIO的Tx Rx。
GPIO的对照表,Tx Rx的BCM编码为14 15
设置步骤
1.启动串口
先查看一下串口启动的情况:
ls -l /dev
如果没配置过串口,那么正常情况应该会得到下面的结果:
...
crw-rw---- 1 root video 237, 0 1月 15 15:17 rpivid-vp9mem
lrwxrwxrwx 1 root root 7 1月 15 15:17 serial1 -> ttyAMA0
drwxrwxrwt 2 root root 40 2月 14 2019 shm
...
只有serial1 -> ttyAMA0,没有看到ttyS0的相关映射。之所以在没有开启串口的时候能看到ttyAMA0的映射,就是上面讲过的,树莓派3/4B将ttyAMA0默认用于板载蓝牙通讯。
启动串口:
修改系统配置文件/boot/config.txt
sudo vi /boot/config.txt
在配置文件中添加:
#ENABLE UARTenable_uart=1
重启树莓派
sudo reboot
启动起来以后,再查看一下串口启动情况
ls -l /dev
结果如下:
...
crw-rw---- 1 root video 238, 0 1月 15 15:17 rpivid-vp9mem
lrwxrwxrwx 1 root root 7 1月 15 15:17 serial0 -> ttyS0
lrwxrwxrwx 1 root root 5 1月 15 15:17 serial1 -> ttyAMA0
drwxrwxrwt 2 root root 40 2月 14 2019 shm
...
在设置中启用串口后,会发现 /dev目录下变成了两个: serial0 -> ttyS0 和 serial1 ->ttyAMA0,这就是开启成功了。
2.禁用蓝牙(硬件串口与mini串口映射对换)
因为蓝牙也使用硬件串口,所以我们在 /boot/config.txt里面加上 dtoverlay=pi3-disable-bt ,ttyAMA0 得以释放,这时候树莓派也自动交换了ttyAMA0和ttyS0,把serial0 分配给了 ttyAMA0 。
映射对换的目的是将硬件串口作用在GPIO接口的Tx Rx上。我的项目上没有用到蓝牙通讯,所以禁用蓝牙后也没有再次开启,也没有测试再次开启蓝牙通讯是否正常,如果项目中有用到蓝牙通讯,那么进行这一步的时候要谨慎。
修改系统配置文件/boot/config.txt
sudo vi /boot/config.txt
在文件中添加:
dtoverlay=pi3-disable-bt
这里有个坑要注意一下:树莓派4B的参数值也是pi3-disable-bt。别问为什么,我也不知道。。。一开始查资料都是关于树莓派3的设置,于是想当然地在树莓派4B上就用pi4-disable-bt,结果不行。折腾了好几个小时,抱着试试看的心态,把pi4改成pi3后成功了。
重启树莓派
sudo reboot
查看一下串口状态,看看ttyAMA0和ttyS0的映射是否对调
ls -l /dev
可以看到结果中,ttyAMA0和ttyS0的映射对调了
...
crw-rw---- 1 root video 238, 0 1月 15 15:17 rpivid-vp9mem
lrwxrwxrwx 1 root root 7 1月 15 15:17 serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 1月 15 15:17 serial1 -> ttyS0
drwxrwxrwt 2 root root 40 2月 14 2019 shm
...
3.禁用串口控制台功能
树莓派默认将IO引出的串口用作于控制台使用,在没有网络的时候,可以通过串口对树莓派进行控制管理
所以经过前面的步骤做好串口映射交换后,还是不能正常地使用串口模块进行通讯。需要禁用串口控制台功能,使串口为我们自由使用。
分别通过如下两个命令停止和禁用串口的控制台功能。(由于我们前面已经交换了串口的映射关系,因此这里注意是ttyAMA0。)
sudo systemctl stop [email protected]
sudo systemctl disable [email protected]
最后还需要删除一个东西:
sudo vi /boot/cmdline.txt
在打开的文件中删去或注释掉
console=serial0,115200
这样树莓派的串口就设置好了,可以通过串口进行通讯收发消息了。
测试通讯示例代码
这里给出一个小的测试示例,来测试串口通讯。下一篇文章会详细写一下通讯示例和详细的测试过程。 示例是Python写的,如果没有serial库,要安装一下
sudo apt-get install python-serial
代码:
# -*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import serial
ser = serial.Serial("/dev/ttyAMA0",9600,timeout=1)
ser.parity = serial.PARITY_EVEN # 奇偶校验设置,在没有交换端口的时候,这里就是错误产生的地方
print(ser.portstr)
command = "hello world"print("send:" + command)
len = ser.write(command.encode())
print("len = " + str(len))
print("You can always send data, press Ctrl + C to exit")
while 1:
# strInput = raw_input('enter some words:') # python2.7的交互方式
strInput = input('enter some words:')
ser.write(strInput.encode())
ser.flush()
以上就是树莓派3/4B串口的全部设置过程,在项目中实际遇到了不少坑后总结出来的。我会尽快更新一篇串口使用实战,把用到的设备,开发代码,踩过的坑都会详细讲一下,希望大家喜欢。
最后,大家觉得有用就点个关注呗:)