前言:本文为手把手教学树莓派4B与 STM32 的 UART 通讯,本次项目采用树莓派4B与 STM32 进行串口通讯,将彼此的数据进行互相传输。本篇博客同时提供了基于 YOLOv5-Lite 的目标检测数据联动,即将树莓派4B检测到的信息发送至 STM32,后续可以通过这些信息进行各种需求上的控制。树莓派4B与 STM32 的联动是很常见的嵌入式架构体系,通常树莓派4B负责计算量大的任务(例如:目标检测,激光雷达等),STM32 则负责进行控制任务,该架构也是目前主流的智能硬件处理框架!(文末有代码开源!)
硬件实物图:
效果图:
一、树莓派4B串口
1.1 树莓派4B的Pin
树莓派4B的引脚图:
树莓派4B作为一款小型电脑,其提供了额外大量的 Pin 引脚适用于嵌入式的日常开发,本次实验我们需要需要实现树莓派4B与STM32F103C8T6之间的UART通讯!
补充说明:
树莓派4B作为上位机负责计算量大的任务(例如:目标检测,激光雷达等),STM32 则负责进行控制为主的任务。该体系框架是目前主流的人工智能嵌入式流派之一,如今多数的智能小车,智能航行器,智能机械臂都有使用该套框架!
该框架的优势:
该框架将控制任务与计算任务隔离,实现了各 CPU 的专门专精,提高了系统的稳定性(方便后期任务的扩展或者检修)。同时,STM32虽然计算能力上是远远弱于树莓派4B的,但是其GPIO的控制能力是强于树莓派的,也就是它天生根据控制优势。所以,该框架是充分发挥了各自的专长!
树莓派4B与STM32之间常用的通讯方式:
(1)、UART,(2)、SPI,(3)、I2C(该项目使用Serial)
1.2 树莓派4B安装Serial与使用
引脚连接:
根据上图树莓派4B的 Pin 引脚图中 GPIO14(TXD) 和 GPIO15(RXD) 的两个引脚分别与 STM32F103C8T6 的 PA10(RXD) 和 PA10(RXD) 的引脚相连(交叉连接)
1.2.1 安装serial
在终端输入:sudo apt-get install serial
1.2.2 打开树莓派4B串口
在终端输入:sudo raspi-config 打开界面设置
Interfacing Options→serial→否→是
在终端输入:ls -al /dev/查看设备
1.2.3 修改串口映射关系
在终端输入:sudo nano /boot/config.txt
末行添加 dtoverlay=pi3-miniuart-bit
重启树莓派4B,之后终端输入:ls -la /dev/查看设备
1.2.4 修改配置文件
在终端输入:sudo nano /boot/cmdline.txt
修改cmdline.txt文件的内容,内容如下:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
二、安装minicom与树莓派4B测试
2.1 minicom安装
minicom 是 Linux/树莓派4B 平台串口调试工具,相当于 Windows 上的串口调试助手,此时需要先安装 minicom;
sudo apt-get install minicom
在终端输入:minicom -D /dev/ttyAMA0
如果要退出这个minicom软件的话,先按CTRL+A再按Z就会弹出菜单,按下0回车就退出了,然后就能直接关闭了。
2.2 树莓派4B通信测试
我们使用 XCOM 串口调试助手来测试树莓派4B能否正常进行 UART 通信!
使用USB-TTL模块交叉连接树莓派4B的 UART 的引脚;
★特殊说明:USB-TTL 模块的 VCC 和 GND 一定都要与树莓派4B的相应 Pin 相连,不然可能因为电流的不平衡导致端口疯狂输出乱码!
我们在下图 minicom 红框区域输入 Hi IKUN!字样之后,可以在 XCOM 的端口处看到字符串成功发送到了 PC 端;
同理,在 XCOM 端口发送 Hi My Brother 字样之后,可以在树莓派4B的 minicom 红框区域成功接收到该信息!
当成功完成上述的操作之后,说明我们已经成功的配置好树莓派4B的UART功能!之后就可以尝试与 STM32 进行通信了(发送数据给XCOM不仅可以通过 minicom,也可以通过python等代码)!
三、树莓派4B与STM32通信
STM32 的代码其实就是简单的UART串口通讯代码,但实质上是有很多坑!!!作者发现大部分博主并没有说明出坑所在,这部分作者将会为读者朋友把可能出现的坑给解决掉!
3.1 树莓派4B代码
我们利用 Python 代码写一个循环发送数字的代码程序,具体代码如下:
import serial import time ser = serial.Serial('/dev/ttyAMA0',115200) # 串口初始化,根据实际情况修改串口号和波特率 # 定义要输出的数字 num = 196 while True: ser.write(str(int(num)).encode()) # 发送数字到串口 num += 1 if num > 205: num = 196 time.sleep(0.2) # 等待1秒钟
可以看出代码是非常简单的,但是这里读者朋友需要注意的是树莓派4B的端口发送至STM32的其实都是字符串流!在STM32端我们对发送过来的字符串流进行解码(很多博主其实都没有说明该点,导致很多朋友解码失败)!
3.2 CubeMX配置
1、RCC配置外部高速晶振(精度更高)——HSE;
2、SYS配置:Debug设置成Serial Wire(否则可能导致芯片自锁);
3、I2C配置:
4、USART1配置:设置UART1串口;波特率:115200;开启UART串口中断;
5、时钟树配置
6、工程配置
3.3 STM32代码
3.3.1 OLED代码
OLED模块主要是方便显示树莓派4B发送给STM32的数据信息!考虑到实际情况,我们一般需要根据树莓派4B发送过来的数字信息,所以,我们这里利用OLED进行数字显示!
小数显示API函数:
//z_len为整数显示位数,f_len为小数显示位数,size2为字体大小 void OLED_Showdecimal(u8 x,u8 y,float num,u8 z_len,u8 f_len,u8 size2) { u8 t,temp; u8 enshow; int z_temp,f_temp; z_temp=(int)num; //整数部分 for(t=0;t