一、前言
串口是嵌入式環(huán)境里面使用最多的通訊方式之一,相信很多接觸過(guò)單片機(jī)的同學(xué)對(duì)串口或多或少都有些了解,老規(guī)矩,通信原理和相關(guān)的一些參數(shù)(如:波特率)我就不介紹了,這些東西都比較簡(jiǎn)單,不清楚的同學(xué)自行查閱相關(guān)資料,我主要講一下大家可能不太清楚的一些知識(shí)點(diǎn)。
串口的冷門知識(shí):
串口的類型其實(shí)不止一種,串口常用的電平有三種:TTL、RS232、RS485,還有一種不常見的RS422,不常用的我就不說(shuō)了,我主要講一下常用的這三種電平的區(qū)別。
TTL:電壓范圍0V至+5V,高電平>2.4V,低電平<0.4V,一般MCU直接輸出的串口就是TTL電平的。
RS232:電壓范圍-15V至+15V,高電平為-3V至-15V,低電平為+3V至+15V。
RS485:電壓范圍-7V至+12V,不同于TTL和RS232,RS485采用的差分信號(hào)負(fù)邏輯,高電平為兩線間的電壓差-2V至-6V,低電平為兩線間的電壓差+2V至+6V。
三種電平之間不能直接連接,需要通過(guò)轉(zhuǎn)換芯片改變電平,一般MCU端出來(lái)的電平都是TTL。
如果MCU的串口需要連接到PC端,一般有三種方法:
1、通過(guò)一個(gè)USB轉(zhuǎn)TTL的芯片轉(zhuǎn)換,可以放在主板上,也可以用那種轉(zhuǎn)換小板,這個(gè)大家應(yīng)該比較熟悉了,某寶上面隨處可見。
2、通過(guò)一個(gè)TTL轉(zhuǎn)232的芯片轉(zhuǎn)換,然后再接一根USB轉(zhuǎn)232的連接線,常用DB9接口。
3、通過(guò)一個(gè)TTL轉(zhuǎn)485的芯片轉(zhuǎn)換,然后再接一根USB轉(zhuǎn)485的連接線。
TTL一般是板內(nèi)模塊間通訊用的比較多,因?yàn)榇诰€過(guò)長(zhǎng)會(huì)有線損,影響通訊,因此,外接的傳感器和MCU的通訊大多使用RS232和RS485這兩種,像RS485,串口線即使長(zhǎng)達(dá)一百米,也不影響正常通訊。
二、配置串口
特別說(shuō)明:關(guān)于串口的配置,我專門查閱了相關(guān)的資料,發(fā)現(xiàn)眾說(shuō)紛紜,一時(shí)間搞得我也有點(diǎn)懵,最后,我用了一種跟大家都不太一樣的方法解決了這個(gè)問(wèn)題,當(dāng)然,我不覺(jué)得他們說(shuō)的就是錯(cuò)的,應(yīng)該是跟樹莓派硬件版本和鏡像版本有關(guān)系。
我總結(jié)了一下網(wǎng)上關(guān)于串口的配置,基本都是修改config.txt和cmdline.txt這兩個(gè)文件,于是在我把串口調(diào)試好了之后,將這兩個(gè)文件的內(nèi)容貼出來(lái),做個(gè)參考。
cmdline.txt文件內(nèi)容如下:
console=tty1 root=PARTUUID=88efaca1-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
config.txt文件內(nèi)容如下:
我這里用的是樹莓派是3B+,鏡像是2021-05-07-raspios-buster-armhf.img,其他版本不確定以下方法是否可行。
配置方法1:通過(guò)配置命令
sudo raspi-config // 打開配置
sudo reboot // 重啟,如果之前沒(méi)有使能,配置完之后要重啟才能生效
配置完成后重啟即可。
注意:如果同時(shí)打開了端口和shell打印,就只能用于shell調(diào)試,不能當(dāng)普通串口使用,不然會(huì)導(dǎo)致串口數(shù)據(jù)傳輸不穩(wěn)定,偶爾出現(xiàn)亂碼。
配置方法2:在可視化界面的設(shè)置里面修改
配置完成后重啟即可。
注意:如果同時(shí)打開了端口和shell打印,就只能用于shell調(diào)試,不能當(dāng)普通串口使用,不然會(huì)導(dǎo)致串口數(shù)據(jù)傳輸不穩(wěn)定,偶爾出現(xiàn)亂碼。
三、串口收發(fā)測(cè)試
1、查詢端口
串口的端口有兩個(gè):ttyAMA0(硬件串口)和ttyS0(mini串口),serial也有兩個(gè)。
serial0:對(duì)應(yīng)的shell調(diào)試串口(引腳有引出,可以直接使用)。
serial1:對(duì)應(yīng)的藍(lán)牙串口(引腳沒(méi)有引出直接連接板載藍(lán)牙,不能直接使用)。
ttyAMA0:硬件串口,默認(rèn)打開,默認(rèn)映射serial1。
ttyS0:mini串口,默認(rèn)不打開。(據(jù)說(shuō)該串口不穩(wěn)定,實(shí)際測(cè)試關(guān)閉shell之后并沒(méi)有出現(xiàn)過(guò)異常情況)
注:serial0和serial1的映射關(guān)系可以通過(guò)配置反過(guò)來(lái)(具體怎么配置這里就不說(shuō)了),據(jù)說(shuō)ttyAMA0比ttyS0穩(wěn)定,實(shí)際測(cè)試都沒(méi)有發(fā)現(xiàn)不穩(wěn)定的情況(也可能是我測(cè)試的次數(shù)不夠多,或者其他進(jìn)程啟動(dòng)的不夠多)。
查詢serial端口是否打開,命令如下:
ls -l /dev // 查詢所有dev
ls -l /dev/serial // 只查詢serial
serial0端口對(duì)應(yīng)的是樹莓派物理引腳的第8腳和第10腳。
2、串口調(diào)試
我這里用的調(diào)試工具是minicom。
1)下載minicom
sudo apt-get install minicom
2)硬件連接
通過(guò)一個(gè)USB轉(zhuǎn)TTL的模塊,連接電腦和樹莓派。(USB轉(zhuǎn)TTL的模塊可以自由選擇,如果你的樹莓派擴(kuò)展板帶有usb轉(zhuǎn)ttl的芯片,也是可以使用的)
3)運(yùn)行minicom
sudo minicom -D /dev/ttyS0 // 默認(rèn)波特率為115200,-D代表端口,/dev/ttyS0 類似于windows中的COM口
3)PC端打開串口助手
隨便打開一個(gè)串口助手,設(shè)置好波特率和com口。
4)PC端和樹莓派相互收發(fā)數(shù)據(jù)
在minicom窗口輸入字符串即可發(fā)送至PC端,窗口默認(rèn)不顯示鍵盤輸入的字符串。
在PC端發(fā)送字符串,會(huì)在minicom的窗口顯示出來(lái)。
minicom使用技巧:
1:輸入crtl+A,再輸入E,可以打開串口發(fā)送顯示(默認(rèn)是關(guān)閉顯示的),再操作一遍則是隱藏顯示。
2:輸入crtl+A,再輸入Q,Enter,可以退出minicom窗口。
四、程序編寫并運(yùn)行
示例代碼:
#!/usr/bin/python
# -*- coding:utf-8 -*-
import serial
#ser = serial.Serial("/dev/ttyAMA0",115200)
ser = serial.Serial("/dev/ttyS0",115200)
print("serial test start ...")
ser.write("Hello Wrold !!!n")
try:
while True:
ser.write(ser.read())
except KeyboardInterrupt:
if ser != None:
ser.close()
示例代碼運(yùn)行結(jié)果:
運(yùn)行后PC端會(huì)收到“Hello Wrold !!!”,PC端隨意發(fā)送一個(gè)字符串,樹莓派會(huì)返回一樣的字符串。
注:代碼運(yùn)行后可通過(guò)Crtl+C退出運(yùn)行。
進(jìn)階代碼:
修改1:波特率改為9600
修改2:增加一個(gè)功能:通過(guò)串口來(lái)控制LED燈。
#!/usr/bin/python
# -*- coding:utf-8 -*-
import serial
import RPi.GPIO as GPIO
LED = 26
GPIO.setwarnings(False) #禁用警告(可以不用)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED,GPIO.OUT)
#ser = serial.Serial("/dev/ttyAMA0",115200)
ser = serial.Serial("/dev/ttyS0",9600)
print("serial test start ...")
ser.write("Hello Wrold !!!n")
try:
while True:
rx_buf = ser.read()
ser.write(rx_buf)
if rx_buf == 'a':
GPIO.output(LED,GPIO.HIGH)
print("led on")
if rx_buf == 'b':
GPIO.output(LED,GPIO.LOW)
print("led off")
except KeyboardInterrupt:
if ser != None:
ser.close()
進(jìn)階代碼運(yùn)行結(jié)果:
和預(yù)期的一樣,波特率9600,串口通信依然正常,PC端發(fā)送打開LED燈,發(fā)送b關(guān)閉LED燈。
五、結(jié)束語(yǔ)
總結(jié)一下串口的配置,樹莓派的串口有兩個(gè),但是只有一個(gè)是有用排針引出來(lái),所以先要把調(diào)試串口或硬件串口映射到引出來(lái)的那對(duì)引腳,然后再編寫串口收發(fā)的程序即可。
好了,這一講的內(nèi)容就這么多了,如果對(duì)你有幫助,可以點(diǎn)個(gè)贊或者給個(gè)收藏,如果想了解更多樹莓派的知識(shí)可以關(guān)注我,后續(xù)我會(huì)繼續(xù)更新更多的教程,謝謝!