树莓派与stm32通信超详细解答过程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

笔者之前发过关于stm32与openmv通信的教程,在学习了几天opencv后,想实现树莓派4B与stm32进行通信。于是上网查询资料,最后实现了两者之间的通信,相信这对大多数电赛人都很有帮助,opencv的识别效果是远高于openmv以及K210的。在此我参考了以下资料辅助我学习,大家可以参考。

基于树莓派4B与STM32的UART串口通信实验(代码开源)_树莓派4b串口波特率-CSDN博客

这位大佬的接发方式我觉得可能对于新手朋友来说比较难懂,于是我换了一种收发方式,与我之前openmv与opencv通信的方式极为类似,如果那个可以搞懂,相信这个也不是问题,甚至超容易上手。

在此默认树莓派已经配置好环境烧录好系统。如果不会烧录系统以及配置opencv的可以私聊我获取镜像。

先上效果图以及视频

一、两者如何进行通信?

与我们之前openmv与stm32的通信方式类似,打开双方的串口然后互相连接,就可以进行通信,具体笔者不多描述,参考我给的链接就可以实现通信,笔者主要讲解我的数据传输方法。

具有以下两个特点:

1.以数据包格式打包发送,32端的代码不用过多改变,接收方式基本相同

data = bytearray([0x2C, 0x12, temp_xh, temp_xl, temp_yh, temp_yl, temp_wh, temp_wl,temp_hh,temp_hl ,0x5B])
    ser.write(data)

2.可以发送16位数据,笔者起初一直发送8位数据,但是bytearray数据包只能发送8位的数据即最高只能发送小于256的数字。这对我们刚入手openmv和32通信的人极不友好。但是根据2023年e题有的坐标点大于256,我们将如何发送?我的解决方法我将数据拆分为高8位和低8位,发送到32后再让32进行解析。为此也是思考了一段时间,我认为还是很有帮助的也能很好的帮助大家。也自认为这个方法很不赖。在此我直接附上树莓派的代码。

import serial
import time
import struct
cx=300
cy=400
cw=500
ch=600
# 初始化串口,修改串口号和波特率
ser = serial.Serial('/dev/ttyAMA0', 115200)

def sending_data(cx, cy, cw, ch):
    # 取 cx 的高 8 位
    temp_xh = (cx & 0xff00) >> 8
    # 取 cx 的低 8 位
    temp_xl = cx & 0x00ff
    # 取 cy 的高 8 位
    temp_yh = (cy & 0xff00) >> 8
    # 取 cy 的低 8 位
    temp_yl = cy & 0x00ff
    # 取 cw 的高 8 位
    temp_wh = (cw & 0xff00) >> 8
    # 取 cw 的低 8 位
    temp_wl = cw & 0x00ff
    # 取 ch 的高 8 位
    temp_hh = (ch & 0xff00) >> 8
    # 取 ch 的低 8 位
    temp_hl = ch & 0x00ff
    data = bytearray([0x2C, 0x12, temp_xh, temp_xl, temp_yh, temp_yl, temp_wh, temp_wl,temp_hh,temp_hl ,0x5B])
    ser.write(data)
    print(data)

while True:
    # 模拟获取数据
    cx += 100
    cy += 100
    cw += 100
    ch += 100
    sending_data(cx, cy, cw, ch)

    time.sleep(0.2)

可以发现这种数据传输方式与openmv与stm32通信的方式极为类似,如果理解了这种传输方式,那么我写的这个树莓派传输数据的方式就超容易上手以及理解。只不过openmv没有加16位数据发送的格式而已。

二、stm32如何解析树莓派发送的数据

1.解析8位数据(0-256)

代码如下(示例):

8位数据比较简单直接从python发送的数据解析低8位就可以

bytearray([0x2C, 0x12, temp_xh, temp_xl, temp_yh, temp_yl, temp_wh, temp_wl,temp_hh,temp_hl ,0x5B])

这里temp_xh为高8位数据,temp_xl为低8位数据,stm32对应数组的位置C1为高8位,Cx为低8位,我们只用处理Cx就可以了。

 Cx=RxBuffer1[RxCounter1-8];
					  C1=RxBuffer1[RxCounter1-9];

2.16位数据(0-65536)

与8位数据类似,我们只需将Cx和C1都读出来,让C1*256加上Cx就是大于256即16位的数据。

我直接附上总处理代码。(stm32端)

uint16_t Cx,Cy,Cw,Ch;
uint16_t C1,C2,C3,C4;
uint16_t X,Y,W,H; 
uint8_t display_buf[20];
uint8_t Flag=0;
void Receive_Data(int16_t Com_Data)
{

  uint8_t i;
	
	static uint8_t RxCounter1=0;//
	
	static uint16_t RxBuffer1[20]={0};
	
	static uint8_t RxState = 0;	
	static uint8_t RxFlag1 = 0;
	
  if(RxState==0&&Com_Data==0x2C)  //0x2c
		{
          
			RxState=1;
			RxBuffer1[RxCounter1++]=Com_Data;
      HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
			
		}

	else if(RxState==1&&Com_Data==0x12)  //0x12
		{
			RxState=2;
			RxBuffer1[RxCounter1++]=Com_Data;
			
		}
	else if(RxState==2)
		{
           
			RxBuffer1[RxCounter1++]=Com_Data;
			if(RxCounter1>=20||Com_Data == 0x5B)      
				{
					RxState=3;
				
					  Cx=RxBuffer1[RxCounter1-8];
					  C1=RxBuffer1[RxCounter1-9];
					  Cy=RxBuffer1[RxCounter1-6];
					  C2=RxBuffer1[RxCounter1-7];
					  Cw=RxBuffer1[RxCounter1-4];
					  C3=RxBuffer1[RxCounter1-5];
					  Ch=RxBuffer1[RxCounter1-2];
					  C4=RxBuffer1[RxCounter1-3];
                      X=C1*256+Cx;
					  Y=C2*256+Cy;
					  W=C3*256+Cw;
					  H=C4*256+Ch;
					}
			}
		
				else if(RxState==3)//
				{
						if(RxBuffer1[RxCounter1-1] == 0x5B)
						{
									
							    if(RxFlag1==0)
									{
							    OLED_Clear();
									}
									HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
									RxFlag1++;
									RxCounter1 = 0;
									RxState = 0;
									OLED_ShowNum(0,0,X,6,16);
									OLED_ShowNum(0,2,Y,6,16);
							        OLED_ShowNum(0,4,W,6,16);
									OLED_ShowNum(0,6,H,6,16);
									
									
									

						}
						else   
						{
									RxState = 0;
									RxCounter1=0;
									for(i=0;i<10;i++)
									{
											RxBuffer1[i]=0x00;      //
									}
						}
				} 
	
				else   
				{
						RxState = 0;
						RxCounter1=0;
						for(i=0;i<10;i++)
						{
								RxBuffer1[i]=0x00;      //
						}
				}
      }

XYWH分别对应处理过的cx,cy,cw,ch。我们直接用oled就可以显示我们从树莓派接收到的数据了。

3.stm32端开启中断

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  uint16_t tempt  /*定义临时变量存放接受的数据*/;
  if(huart->Instance==USART1)
  {
    tempt=USART1_RXbuff;
    Receive_Data(tempt);
		HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);

  }	
HAL_UART_Receive_IT(&huart1,(void *)&USART1_RXbuff,1);/*再次开启接收中断*/
}


总结

具体的可以参考我openmv与stm32通信的文章,有详细的stm32端接收讲解。

https://blog.csdn.net/Halcyon0804/article/details/139890266?spm=1001.2014.3001.5502

到这里基本就实现两者的数据互传了。并且数据范围特别大,我相信已经很够用了,希望这篇文章可以帮到大家。

如果树莓派不会配置的可以私聊我获取树莓派配置好的镜像,已经配置好opencv以及2023年运动目标跟踪控制系统的图像处理代码。

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 树莓派STM32通信可以通过多种方式实现,以下是一种常见的方式: 1. 首先,确保树莓派STM32之间的物理连接。可以使用串口、SPI、I2C等通信接口。 2. 在树莓派上安装相关的开发环境或库文件,例如Python的RPi.GPIO库或C语言的WiringPi库。这些库文件可以方便地操作树莓派的GPIO引脚。 3. 在树莓派上编写代码,通过GPIO引脚与STM32进行通信。可以使用GPIO库提供的函数来设置引脚的输入输出状态,读取或写入数据。 4. 在STM32上编写代码,通过相应的通信接口与树莓派进行通信。例如,如果使用串口通信,可以使用STM32的串口库函数来配置串口参数、发送和接收数据。 5. 在树莓派上使用相应的通信协议和命令,发送需要的数据给STM32。例如,可以使用GPIO库的函数来设置GPIO引脚的状态,并通过串口将命令发送给STM32。 6. 在STM32上接收树莓派发送的数据,并根据需要进行处理。 需要注意的是,树莓派STM32本身的特性和接口选择会对通信的实现方式产生影响。因此,在编写通信代码之前,需要了解树莓派STM32的硬件规格和接口定义,确保代码的正确性和稳定性。此外,通信的协议选择也需要根据具体应用的需求来确定,例如串口通信时可以选择使用ASCII码或二进制码进行数据传输。 ### 回答2: 树莓派STM32通信的代码主要有两种方式,一种是使用串口通信,另一种是使用I2C总线通信。 如果使用串口通信,首先需要在树莓派上配置一个串口,并连接到STM32的串口。在树莓派上可以使用Python编程语言,通过编写串口通信相关的代码来实现与STM32通信。以下是一个简单的串口通信代码示例: '''python import serial ser = serial.Serial('/dev/ttyS0', 115200) # 配置串口,波特率为115200 while True: data = input("请输入要发送的数据:") # 从终端获取要发送的数据 ser.write(data.encode()) # 发送数据 received_data = ser.readline().decode().strip() # 接收数据 print("接收到的数据:", received_data) ser.close() # 关闭串口 ''' 如果使用I2C总线通信,首先需要在树莓派上启用I2C功能,并通过对应的引脚连接到STM32的I2C口。同样,可以使用Python编程语言,在树莓派上编写相应的I2C通信代码实现与STM32通信。以下是一个简单的I2C通信代码示例: '''python import smbus bus = smbus.SMBus(1) # 创建一个I2C对象,参数为I2C总线号,树莓派3B/3B+为1,树莓派4B为0 address = 0x12 # STM32的I2C地址 while True: data = input("请输入要发送的数据:") # 从终端获取要发送的数据 bus.write_byte(address, ord(data)) # 发送数据 received_data = bus.read_byte(address) # 接收数据 print("接收到的数据:", chr(received_data)) bus.close() # 关闭I2C ''' 需要注意的是,以上代码仅是简单的示例,实际使用时还需要根据具体的通信需求进行修改和扩展。同时,树莓派STM32之间的通信需要保证硬件连接的正确性和信号电平的兼容性。 ### 回答3: 树莓派是一款小型的单板计算机,而STM32是一款32位微控制器。要实现树莓派STM32通信,可以通过串口进行数据传输。 首先,在树莓派上连接一个USB转串口模块,并将其与STM32的串口进行连接。然后,在树莓派上安装相应的串口通信库,例如pySerial。 接下来,编写树莓派Python代码,示例如下: ```python import serial # 打开串口,设置波特率为9600 ser = serial.Serial('/dev/ttyUSB0', 9600) # 发送数据到STM32 ser.write('Hello STM32!') # 接收STM32返回的数据 response = ser.readline() print(response) # 关闭串口 ser.close() ``` 上面的代码中,通过指定串口的路径(例如`/dev/ttyUSB0`)和波特率(例如9600)来打开串口,并向STM32发送数据。然后通过`readline()`函数接收STM32返回的数据,并打印出来。最后,关闭串口。 需要注意的是,树莓派STM32之间的通信协议需要一致。在STM32的代码中,需要确保串口的波特率和树莓派设置的波特率一致,并正确处理接收和发送的数据。 以上为一种基本的树莓派STM32通信的代码实现方式,具体的应用场景和需求可能会有所不同,编写代码的细节也会有所差异。这只是一个简单的示例,供参考。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值