1.1 拓空者接收Openmv数据的函数解析
拓空者2PRO使用串口3接收openmv的数据
//全局变量
u16 offline_check_time;
u8 openmv_buf[20];
_openmv_data_st opmv;
/**********************************************************************************************************
*函 数 名: OpenMV_Byte_Get
*功能说明: OpenMV字节数据获取
*参 数: 字节数据
*返 回 值: 无
**********************************************************************************************************/
void OpenMV_Byte_Get(u8 bytedata)
{
static u8 len = 0,rec_sta;
u8 check_val=0;
//
openmv_buf[rec_sta] = bytedata;
//
if(rec_sta==0)
{
if(bytedata==0xaa)
{
rec_sta++;
}
else
{
rec_sta=0;
}
}
else if(rec_sta==1)
{
if(1)//(bytedata==0x29)未确定
{
rec_sta++;
}
else
{
rec_sta=0;
}
}
else if(rec_sta==2)
{
if(bytedata==0x05)
{
rec_sta++;
}
else
{
rec_sta=0;
}
}
else if(rec_sta==3)
{
if(bytedata==0x41 || bytedata==0x42)
{
rec_sta++;
}
else
{
rec_sta=0;
}
}
else if(rec_sta==4)
{
//
len = bytedata;
// len = sizeof(openmv_buf);
if(len<20)
{
rec_sta++;
}
else
{
rec_sta=0;
}
}
else if(rec_sta==(len+5))
{
//
for(u8 i=0;i<len+5;i++)
{
check_val += openmv_buf[i];
}
//
if(check_val == bytedata)
{
//解析成功
OpenMV_Data_Analysis(openmv_buf,len+6);
//
rec_sta=0;
}
else
{
rec_sta=0;
}
}
else
{
//
rec_sta++;
}
}
这段函数的其实都挺好理解的,这里讲解一下我自己的理解。rec_sta的作用是判断当前数据进行到哪一步,比如当rec_sta=0的时候,如果这时候接受的数据为0xaa时进行下一步的判断,也就是进行标志位的判断。在星瞳科技的官方例程中也有使用比如0x2C,0x12...0x5B。
当rec_sta=3的时候这个时候接收的数据是一个标志位(划重点后面要考)。rec_sta=4的时候bytedata的数据为有效数据长度长度,这个长度和rec_sta=3接收的数据是绑定的这一点下面会讲到。解析成功之后会进行openmv数据的解析函数OpenMV_Data_Analysis(openmv_buf,len+6)
/**********************************************************************************************************
*函 数 名: OpenMV_Data_Analysis
*功能说明: OpenMV数据解析
*参 数: 缓存数据(形参),长度
*返 回 值: 无
**********************************************************************************************************/
#include "Ano_DT.h"
static void OpenMV_Data_Analysis(u8 *buf_data,u8 len)
{
//判断第4位的数据确定数据格式
if(*(buf_data+3)==0x41)
{
//识别的颜色
opmv.cb.color_flag = *(buf_data+5);
//是否正确识别颜色
opmv.cb.sta = *(buf_data+6);
//识别到的颜色坐标和延时时间
opmv.cb.pos_x = (s16)((*(buf_data+7)<<8)|*(buf_data+8));
opmv.cb.pos_y = (s16)((*(buf_data+9)<<8)|*(buf_data+10));
opmv.cb.dT_ms = *(buf_data+11);
//
opmv.mode_sta = 1;
}
else if(*(buf_data+3)==0x42)
{
//巡线检测标志位
opmv.lt.sta = *(buf_data+5);
//偏航角度
opmv.lt.angle = (s16)((*(buf_data+6)<<8)|*(buf_data+7));
//偏移距离
opmv.lt.deviation = (s16)((*(buf_data+8)<<8)|*(buf_data+9));
//判断是否到停止位置
opmv.lt.p_flag = *(buf_data+10);
//中心点的x,y坐标和延时时间
opmv.lt.pos_x = (s16)((*(buf_data+11)<<8)|*(buf_data+12));
opmv.lt.pos_y = (s16)((*(buf_data+13)<<8)|*(buf_data+14));
opmv.lt.dT_ms = *(buf_data+15);
//
opmv.mode_sta = 2;
}
//
OpenMV_Check_Reset();
}
这里是上面用到的数据结构体定义
//==定义
typedef struct
{
//
u8 color_flag;
u8 sta;
s16 pos_x;
s16 pos_y;
u8 dT_ms;
}_openmv_color_block_st;
typedef struct
{
//
u8 sta;
s16 angle;
s16 deviation;
u8 p_flag;
s16 pos_x;
s16 pos_y;
u8 dT_ms;
}_openmv_line_tracking_st;
typedef struct
{
u8 offline;
u8 mode_cmd;
u8 mode_sta;
//
_openmv_color_block_st cb;
_openmv_line_tracking_st lt;
}_openmv_data_st;
//==数据声明
extern _openmv_data_st opmv;
这部分的代码理解起来就比较简单了,就是进行一个数据更新就不多做赘述了。
剩下的代码明天再分析。