自己备赛的过程中遇到了一些问题,网上找了很久才总结出来,openmv通过串口发送数据,stm32进行接收并显示在液晶屏上,亲测可用。
使用设备stm32f103zet6,液晶屏为四线
OpenMv主要代码:
import json #加载json
uart = UART(3,115200) #定义串口3变量 P4 TX<-->PA10 P5 RX<-->PA9
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters
data = bytearray([0xb3,0xb3,max_blob.cx(),max_blob.cy(),length,0x5b]) #打包要发送的数据
uart.write(data) #串口发送
openmv打包发送数据,stm32接收端再进行解析
stm32主要代码:这里设置接收了三个变量,在代码中有注释,先接收然后再进行解析,第一个是解析的函数,第二个是接收函数
void Openmv_Data(void)//处理Openmv接收的数据
{
OpenMV_X=openmv[2];
OpenMV_Y=openmv[3];
length =openmv[4];
}
void Openmv_Receive_Data(int16_t data)//接收Openmv传过来的数据
{
static u8 state = 0;
if(state==0&&data==0xb3)//第一个帧头
{
state=1;
openmv[0]=data;
}
else if(state==1&&data==0xb3)//第二个帧头
{
state=2;
openmv[1]=data;
}
else if(state==2)//第一个有效数据
{
state=3;
openmv[2]=data;
}
else if(state==3)//第二个有效数据
{
state = 4;
openmv[3]=data;
}
else if(state==4)//第三个有效数据
{
state = 5;
openmv[4]=data;
}
else if(state==5) //检测是否接受到结束标志,检测接收帧尾
{
if(data == 0x5B)
{
state = 0;
openmv[5]=data;
Openmv_Data();
}
else if(data != 0x5B)
{
state = 0;
for(i=0;i<6;i++)
{
openmv[i]=0x00;
}
}
}
else
{
state = 0;
for(i=0;i<6;i++)
{
openmv[i]=0x00;
}
}
}
定义的三个变量,注意定义的位置,在使用之前要定义:
int openmv[6];//stm32接收数据数组
int16_t OpenMV_X; /*OPENMV X 轴反馈坐标*/
int16_t OpenMV_Y; /*OPENMV X 轴反馈坐标*/
int16_t length;
int i;
那么什么时候开始接收呢,这里我使用了中断,所以中断函数修改成了这样
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 com_data;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
USART_ClearFlag(USART1,USART_FLAG_RXNE);
com_data = USART1->DR;
Openmv_Receive_Data(com_data); //openmv数据处理函数
Openmv_Data(); //openmv数据处理函数
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}
这样接收就配置好了,为了更直观的显示,我加入了oled屏进行显示,主要的配置如下:
//由于不在同一个文件下,需要引用一下之前定义的变量
extern int16_t OpenMV_X; /*OPENMV X 轴反馈坐标*/
extern int16_t OpenMV_Y; /*OPENMV X 轴反馈坐标*/
extern int16_t length;
//主函数的相关配置
int main(void)
{
OLED_Init();
OLED_Clear();
OLED_ShowString(2,0,"Openmv Test",16);
uart_init(115200);
while(1)
{
//sprintf((char *)string,"X_coords:%d",OpenMV_X);
//OLED_ShowString(2,2,string,16);
OLED_ShowString(0,2,"X_c:",16);
OLED_ShowNum(32,2,OpenMV_X,8,16);
//sprintf((char *)string,"Y_coords:%d",OpenMV_Y);
//OLED_ShowString(2,4,string,16);
OLED_ShowString(0,4,"Y_c:",16);
OLED_ShowNum(32,4,OpenMV_Y,8,16);
//sprintf((char *)string,"L_coords:%d",length);
//OLED_ShowString(2,6,string,16);
OLED_ShowString(0,6,"L_c:",16);
OLED_ShowNum(32,6,length,8,16);
}
}
最终效果:
最终效果还是很完美的
就是有一个疑问,在显示的时候使用sprintf数据会显示不正常,不知道是什么原因,感觉是格式化转换太占用时间了,希望知道的大佬可以指导一下。