赞
踩
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
笔者之前发过关于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位数据发送的格式而已。
代码如下(示例):
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];
与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就可以显示我们从树莓派接收到的数据了。
- 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年运动目标跟踪控制系统的图像处理代码。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。