(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<z_len;t++) { temp=(z_temp/oled_pow(10,z_len-t-1))%10; if(enshow==0 && t<(z_len-1)) { if(temp==0) { OLED_ShowChar(x+(size2/2)*t,y,' ',size2); continue; } else enshow=1; } OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); } //小数点 OLED_ShowChar(x+(size2/2)*(z_len),y,'.',size2); f_temp=(int)((num-z_temp)*(oled_pow(10,f_len))); //小数部分 for(t=0;t<f_len;t++) { temp=(f_temp/oled_pow(10,f_len-t-1))%10; OLED_ShowChar(x+(size2/2)*(t+z_len)+5,y,temp+'0',size2); } }
篇幅有限,OLED参考博客:http://t.csdn.cn/kydg4
3.3.2 UART代码
这部分代码是比较核心的,上述博客作者已经说明了,其实树莓派4B发送给STM32的数据都是以字符串流的格式发送来得。所以,即使发送过来的是数字数据也会变成字符,这就需要我们进行解码!
uart.h:
#ifndef __UART_H #define __UART_H #include "stm32f1xx_hal.h" extern UART_HandleTypeDef huart1; #define USART1_REC_LEN 600 extern int USART1_RX_BUF[USART1_REC_LEN]; extern uint16_t USART1_RX_STA; extern int USART1_NewData; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); #endif
uart.c:
#include "uart.h" #include "oled.h" int USART1_RX_BUF[USART1_REC_LEN]; //目标数据 uint16_t USART1_RX_STA=2; int USART1_NewData; extern int num; //百位 extern int num2; //十位 extern int num3; //个位 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart ==&huart1) { USART1_RX_BUF[USART1_RX_STA&0X7FFF]=USART1_NewData; USART1_RX_STA++; if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0; //num = USART1_RX_BUF[USART1_RX_STA]; HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1); num = USART1_RX_BUF[USART1_RX_STA-1]; num2 = USART1_RX_BUF[USART1_RX_STA-2]; num3 = USART1_RX_BUF[USART1_RX_STA-3]; } }
上述UART代码,利用 UART 中断函数进行读取 USART1_NewData 的数值,因为我们最大传输的数字为3位数,所以我们分别读取缓存数组中最近的 3 个字节数据(树莓派4B发送过来的是字符串,也就是被转换成了对应数字的ASCII数值,例如:发送过来100,则STM32端接收到的为49 49 48 这3个字节)。
3.3.3 数据解码代码
control.c:
#include "control.h" #include "uart.h" #include "tim.h" #include "oled.h" int num; int num2; int num3; int value; int flag; int last; void TargetTracking() { flag = USART1_RX_STA - last; last = USART1_RX_STA; value = (num3-48) * 100 + (num2-48) * 10 + (num-48) * 1; OLED_ShowStr(10,2,"Object Center",2); OLED_Showdecimal(45,4,value,3,1,16); if(flag == 2) { value = (num2-48) * 10 + (num-48) * 1; OLED_Showdecimal(40,4,value,3,1,16); } }
这里默认都是 3 位数,所以之间按照 UART 数据传输高低位的数据将数据-48变为实际的数字,在×对应的比例即可得到实际值!flag 则是通过 USART1_RX_STA 变量的变化值判断一次传输过来几个字节的数据,可以判断是几位数!
读者朋友可以根据自己实际情况更改上述代码为己所用!
代码运行之后:
四、高级应用
智能小车的目标追踪
树莓派4B通常会出现在基于视觉技术进行规定目标的追踪,这个时候往往需要树莓派4B读取到目标框数据,然后发送给STM32下位机,之后STM32根据这些目标框信息来进行逻辑上的控制。
作者这里以上一篇博客的网络模型检测结果为例,代码如下:
import cv2 import numpy as np import onnxruntime as ort import serial import time ## 最后 **自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。** **深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。** **因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。** ![img](https://img-blog.csdnimg.cn/img_convert/0186901149a2abf61aa33c8453e64b16.png) ![img](https://img-blog.csdnimg.cn/img_convert/f46519ad296e0b4b72029a5100a5877d.jpeg) ![img](https://img-blog.csdnimg.cn/img_convert/19e5244c5e4235b143ed77b0317a8f5a.png) ![img](https://img-blog.csdnimg.cn/img_convert/b6647dd2ea32a7e52239d150cac4610d.png) ![img](https://img-blog.csdnimg.cn/img_convert/4da28c27bbd275bf9b2911d2ccbfeb07.png) ![img](https://img-blog.csdnimg.cn/img_convert/7a3dd28f9bbad4113d7d0413801dc773.png) ![](https://img-blog.csdnimg.cn/img_convert/813ecf14eb30f9189f5dd9a26f4320ce.png) **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!** [**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289) **由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!! 7Kifn-1715710950517)] [外链图片转存中...(img-db6x3o9v-1715710950519)] [外链图片转存中...(img-2mIFnw8q-1715710950519)] [外链图片转存中...(img-unSgX7yr-1715710950520)] [外链图片转存中...(img-VIN91DyE-1715710950520)] [外链图片转存中...(img-g0ed0vBj-1715710950521)] [外链图片转存中...(img-vdPAVZ8y-1715710950521)] **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!** [**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289) **由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!