如何生成构架图(结构图生成)
1228
2022-05-28
【任务介绍】
我们这篇文章来编写前进函数
【代码解释】
void Car_Go(uint8_t speed,uint16_t temp)// 主车前进函数 参数:速度/码盘 { Roadway_mp_syn(); //码盘同步函数 Stop_Flag = 0; //运行状态标志位 Go_Flag = 1; //前进标志位 wheel_L_Flag = 0; //左转标志位 wheel_R_Flag = 0; //右转标志位 wheel_Nav_Flag = 0; //码盘旋转标志位 Back_Flag = 0; //后退标志位 Track_Flag = 0; //循迹标志位 temp_MP = temp; //码盘值赋值 Car_Spend = speed; //速度值赋值 Control(Car_Spend ,Car_Spend); //调用电机驱动函数 while(Stop_Flag != 0x03);//等待前进完成 }
函数类型:void ,无需返回值
参数:速度、码盘值(通过协议:0X02代表前进,对应的副指令有速度和码盘两项参数;或者通过概念:前进就是小车以一定的速度行驶一定的码盘(路程)值)
函数名:Car_Go ,采用大驼峰命名法(每个单词首字母大写,其余小写)
函数体:前进函数体共有12条语句,下面对其依次进行解释。
Roadway_mp_syn(); //码盘同步函数
作用:获取小车当前的码盘值(指当前小车走了多少路程,在小车显示屏上可以看到该数值)。
Q:不写该函数可不可以?
A:不可以,小车的码盘值只在电机驱动板上记录,核心板是不知道的,要通过此函数,把该数据传给核心板,以便进行数据处理,执行后续任务。
Stop_Flag = 0; //运行状态标志位
作用:判断小车是否完成行驶任务。
Go_Flag = 1; //前进标志位
作用:Go_Flag = 1,代表小车前进;Go_Flag = 0,代表小车不前进
Q:如何判断小车当前处于什么状态呢呢?
A:打开通讯协议→四、竞赛平台运行状态表 (如下),运行状态就是通过给Stop_Flag的值判断的,如果Stop_Flag == 0x03 ,说明小车前进任务完成了。
wheel_L_Flag = 0; //左转标志位 wheel_R_Flag = 0; //右转标志位 wheel_Nav_Flag = 0; //码盘旋转标志位 Back_Flag = 0; //后退标志位 Track_Flag = 0; //循迹标志位
同前进标志位。
temp_MP = temp; //码盘值赋值
将我们自定义的码盘值变量“temp” 传递给小车默认(即设备厂商定义的)的码盘值变量“temp_MP”
Car_Spend = speed; //速度值赋值
将我们自定义的速度值变量“speed” 传递给小车默认的(即设备厂商定义的)码盘值变量“Car_Spend”
Control(Car_Spend ,Car_Spend); //调用电机驱动函数
电机驱动函数:一个控制小车左、右两轮子方向及速度的函数,
我们将鼠标移动到函数名上右击,选择Go To Definition Of 'Control' ,跳转到了“my_lib”文件夹下的“roadway_check.c”文件里,来查看该函数的代码。
该函数代码如下:
/*************************************************************** ** 名字: 电机控制函数 ** 功能: 控制左、右两轮子转动的方向和速度 ** 参数: L_Spend:电机左轮速度 ** R_Spend:电机右轮速度 ** 返回值: 无 ****************************************************************/ void Control(int L_Spend,int R_Spend) //函数名→Control:控制 参数1→L_Spend:左轮速度 参数2→R_Spend:右轮速度 { if(L_Spend>=0) //如果左轮速度是正值(代表左轮向前转) { if(L_Spend>100)L_Spend=100;if(L_Spend<5)L_Spend=5; //作用:限制左轮速度在[5,100]内 } else //要不然左轮速度就是负值(代表左轮向后转) { if(L_Spend<-100)L_Spend= -100;if(L_Spend>-5)L_Spend= -5; //作用:限制左轮速度在[-100,5]内 } if(R_Spend>=0) //如果右轮速度是正值(代表右轮向前转) { if(R_Spend>100)R_Spend=100;if(R_Spend<5)R_Spend=5; //作用:限制右轮速度在[5,100]内 } else //要不然右轮速度就是负值(代表右轮向后转) { if(R_Spend<-100)R_Spend= -100;if(R_Spend>-5)R_Spend= -5; //作用:限制右轮速度在[-100,5]内 } Send_UpMotor(L_Spend ,R_Spend); //调用真正的电机驱动函数(底层的电机驱动函数),右击可查看 }
我们将鼠标移动到上述代码第27行的函数名上右击,选择Go To Definition Of 'Send_UpMotor',跳转到了“CAN”文件夹下的“roadway_check.c”文件里,来查看该函数的代码。
该函数代码如下(知道这些语句是控制轮子转速的底层代码就行,无需深入了解):
/** 函数功能:发送电机转速。知道这些语句是控制轮子转速的底层代码就行,无需深入了解 参 数:x1 左侧电机速度 x2 右侧电机转速 返 回 值:无 */ void Send_UpMotor( int x1, int x2) { u8 txbuf[4]; txbuf[0] = x1; txbuf[1] = x1; txbuf[2] = x2; txbuf[3] = x2; //CanDrv_WhaitTxEmpty(); if(CanDrv_TxEmptyCheck()) { CanDrv_TxData(txbuf,4,CAN_SID_HL(ID_MOTOR,0),0,_NULL); CanP_Cmd_Write(CANP_CMD_ID_MOTO,txbuf,0,CAN_SID_HL(ID_MOTOR,0),0); } else CanP_Cmd_Write(CANP_CMD_ID_MOTO,txbuf,4,CAN_SID_HL(ID_MOTOR,0),0); }
while(Stop_Flag != 0x03);//等待前进完成
Q:如何判断小车前进完成了呢?
A:我们通过代码来了解其原理
首先,通过Ctrl+F查询Go_Flag,跳转到my_lib目录下roadway_check.c文件的“前进、后退监测函数”(第96行左右),如下:
/** 函数名:前进完成、后退完成监测函数 函数功能:当小车完成前进或后退指令后,使小车轮子速度降为0,停止运行 */ void Go_and_Back_Check(void) { if(Go_Flag == 1) //如果前进标志位等于1 { if(temp_MP <= Roadway_mp_Get()) //如果我们给定的码盘值 <= 小车当前码盘值(通过调用Roadway_mp_Get()函数获取)(代表前进完成) {//前进完成之后执行下列操作: Go_Flag = 0; //给前进标志位赋值为0 Stop_Flag = 3; //给运行状态标志位赋值为3;赋值为多少要与通讯协议的四、竞赛平台运行状态表对应 Send_UpMotor(0,0); //调用底层驱动代码,让小车左右轮子转速都为0,从而停止前进 } } else if(Back_Flag == 1) { if(temp_MP <= Roadway_mp_Get()) { Back_Flag = 0; Stop_Flag=3; Send_UpMotor(0,0); } } }
右击第9行的Roadway_mp_Get(),进入该被调函数(同文件下第39行左右),代码如下:
/* 函数名字:码盘值获取函数 函数功能:获取码盘值,并返回码盘值。无需深入了解 **/ uint16_t Roadway_mp_Get(void) { uint32_t ct; if(CanHost_Mp > Roadway_cmp) ct = CanHost_Mp - Roadway_cmp; else ct = Roadway_cmp - CanHost_Mp; if(ct > 0x8000) ct = 0xffff - ct; return ct; }
Q:如何让小车左转90°,右转90°?
A:左转90°的原理是让小车以一定速度向左旋转,同时寻找地图的黑线,由于地图的交叉黑线是90°夹角,所以当小车识别到黑线时,小车停止,此时正好转了90°。所以小车左转90°的函数需要一个参数:速度
右转90°函数同理。
嵌入式
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。