Raspberry 4B 串口通信

Posted ʚVVcatɞ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Raspberry 4B 串口通信相关的知识,希望对你有一定的参考价值。

组件

  • Raspberry Pi 4 B+主板*1
  • 树莓派电源*1
  • USB TO TTL模块*1
  • 树莓派管脚图

第1步: 连接电路,使用USB TO TTL模块连接好树莓派的串口和PC电脑的USB接口。

树莓派USB TO TTL模块
TXDRXD
RXDTXD
GNDGND

注意:

  • 树莓派TXD引脚接 USB TO TTL模块 RXD 引脚
  • 树莓派RXD 引脚接 USB TO TTL模块 TXD 引脚
  • 树莓派GND引脚一定要和USB TO TTL模块GND引脚接好,否则在发送数据的过程中会出现乱码。

树莓派默认的映射关系:

pi@raspberrypi:~ $ ls -l /dev
lrwxrwxrwx 1 root root 7 8月 13 07:34 serial0 -> ttyS0
lrwxrwxrwx 1 root root 5 8月 13 07:34 serial1 -> ttyAMA0

由以上映射关系可以看到

  • serial0是GPIO引脚对应的串口,默认使用的是ttyS0 (mini串口)
  • serial1是蓝牙对应的串口,默认使用的是ttyAMA0(硬件串口)

操作步骤

Raspberry 4B 串口通信 实现流程大致如下:

  • 查看Raspberry 4B 的硬件串口与mini串口默认映射关系
  • 修改串口映射关系
  • 禁用串口的控制台功能
  • 测试串口通信

查看树莓派4B的硬件串口与mini串口默认映射关系

在/boot/overlays文件内有两个文件,READMEminiuart-bt.dtbo,首先查看有没有相关文件。

cd /boot/overlays/
ls REA* mini*


README文件中说明了此文件的功能是将树莓派3B,3B+, 3A+, 4B, Zero的蓝牙切换到mini串口(ttyS0),并且恢复硬件串口(ttyAMA0)到GPIO14&15引脚中。

修改串口映射关系

执行命令

sudo gedit /boot/config.txt

在文件的末尾加上一行代码

dtoverlay=miniuart-bt


然后"ctrl+s"保存文件, 执行sudo reboot重启树莓派,使修改生效。

再查看映射关系已经改变:

pi@raspberrypi:~ $ ls -l /dev
lrwxrwxrwx 1 root root 7 8月 13 07:34 serial0 -> ttyAMA0
lrwxrwxrwx 1 root root 5 8月 13 07:34 serial1 -> ttyS0

对比修改前的关系,可以看出 serial0serial1ttyAMA0ttyS0 的映射关系对换完成了,也就是ttyAMA0映射到了引出的GPIO Tx(14) Rx(15) 引脚上。

禁用串口的控制台功能

在树莓派命令窗口中分别通过如下两个命令停止和禁用串口的控制台功能。
由于我们前面已经交换了串口的映射关系,因此这里注意是ttyAMA0。

sudo systemctl stop serial-getty@ttyAMA0.service
sudo systemctl disable serial-getty@ttyAMA0.service

再执行命令:

sudo gedit /boot/cmdline.txt

在文档中删除语句 console=serial0,115200

然后保存文件,重新启动树莓派,使修改生效。

测试串口通信

完成以上操作,树莓派 4B的串口配置就可以直接用了,下面用python-serial模块做一个树莓派串口与电脑USB TO TTL串口通信的测试。

1、首先将树莓派的串口和 USB TO TTL 串口连接好,并将 USB TO TTL 串口插到电脑端上。
2、安装python-serial模块,一般都是树莓派系统默认已经安装好,可以直接跳过该步骤。

 sudo apt-get install python-serial  

3、输入phthon3启动python IDE。
4、创建serial实例ser,端口为 ‘/dev/ttyAMA0’,波特率设置为115200bps,第三个为校验位,可以不写。

>>> import serial
>>> ser = serial.Serial(’/dev/ttyAMA0’,115200)

5、检验串口是否打开,若未打开则输入 ser.open() 打开

>>> ser.isOpen()
True

7、电脑上打开串口调试助手,选择 USB TO TTL插入电脑上显示的串口号,波特率选择115200
测试用的串口助手是STC-ISP里面的串口助手

8、然后我们在树莓派的python里向电脑的串口助手发消息,检测发送是否正常:

>>> ser.write(b’hello’)
5

可以看到在接收缓冲区接收到了树莓派通过串口发送的 hello 消息。

使用python实现串口的发送和接收
# -*- coding: utf-8 -*
#! /usr/bin/env python
import serial
import time

ser = serial.Serial('/dev/ttyAMA0', 115200)  # 设置端口和波特率
if ser.isOpen == False:  # 检查串口是否打开
    ser.open()                # 打开串口
ser.write(b"Raspberry pi is ready")
try:
    while True:
        size = ser.inWaiting()               # 获得缓冲区字符
        if size != 0:
            response = ser.read(size)        # 读取内容并显示
            print(response)        
            ser.flushInput()                 # 清空接收缓存区
            time.sleep(0.5)                  # 软件延时
except KeyboardInterrupt:
    ser.close()

将以上代码保存为“uart_communication.py”,然后执行Python文件

python uart_communication.py

运行树莓派端的python程序,通信过程如下:


使用C++实现串口的发送和接收

以下为C++实现数据的发送

#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
 
int main(){
	int fd;
	if(wiringPiSetup()<0)
		return 1;
	if((fd=serialOpen("/dev/ttyAMA0", 115200))<0)
		return 1;
	printf("Raspberry pi is ready ...\\n");
	serialPrintf(fd,"hello C++!!\\n");
	serialClose(fd);
	return 0;
}

将以上代码保存为“uart_communication.cpp”,然后执行C++文件

g++ uart_communication.cpp -o uart_communication -lwiringPi

sudo ./uart_communication



打开并初始串口:
int serialOpen (char *device, int baud)

  • device:串口的地址,在Linux中就是设备所在的目录。
    • 默认一般是"/dev/ttyAMA0"
  • baud:波特率
  • 返回:正常返回文件描述符,否则返回-1失败。

像使用C语言中的printf一样发送数据到串口:
void serialPrintf (int fd, char *message, …)

  • fd:文件描述符

  • message:格式化的字符串


当使用这个函数初始化树莓派引脚时,程序使用的是wiringPi 引脚编号表。引脚的编号为 0~16

需要root权限
int wiringPiSetup (void)

  • 返回:执行状态,-1表示失败

发送一个字符串到串口
void serialPuts (int fd, char *s)

  • fd:文件描述符
  • s:发送的字符串,字符串要以’\\0’结尾

获取串口缓存中可用的字节数。
int serialDataAvail (int fd)

  • fd:文件描述符
  • 返回:串口缓存中已经接收的,可读取的字节数,-1代表错误

从串口读取一个字节数据返回。

如果串口缓存中没有可用的数据,则会等待10秒,如果10后还有没,返回-1

int serialGetchar (int fd)

  • fd:文件描述符

  • 返回:读取到的字符


以下为C++实现数据的接收

#include<stdio.h>
#include<wiringPi.h>
#include<wiringSerial.h>
#include<string.h>
int main(){
	int fd;
	int message;
	wiringPiSetup();	
	fd = serialOpen("/dev/ttyAMA0", 115200);
	serialPuts(fd, "Raspberry pi is ready\\r\\n");
	while(1){
		while(serialDataAvail(fd) != -1){
			message = serialGetchar(fd); 
			if(message == '1' ){
				serialPuts(fd,"hello\\r\\n"); 
			} else if (message == '2') {
				serialPuts(fd,"C++\\r\\n");
			} else if (message == '3'){
				serialPuts(fd,"!!!\\r\\n");
			}
		}	       
	}	     
	return 0;
}	

参考博客:https://www.cnblogs.com/lulipro/p/5992172.html

以上是关于Raspberry 4B 串口通信的主要内容,如果未能解决你的问题,请参考以下文章

树莓派(Raspberry Pi)4B无界面安装 Raspberry Pi 系统篇

树莓派(Raspberry Pi)4B无界面安装 Raspberry Pi 系统篇

树莓派串口通信

树莓派串口通信

Raspberry Pi 4B 循迹模块

Raspberry Pi 4B C和Python开发环境安装