同步最新代码
This commit is contained in:
326
底盘独立控制器/code/CarBody/Mecanum.c
Normal file
326
底盘独立控制器/code/CarBody/Mecanum.c
Normal file
@@ -0,0 +1,326 @@
|
||||
#include "stm32f4xx.h" // Device header
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include <math.h>
|
||||
#include "M3508.h"
|
||||
#include "GM6020.h"
|
||||
#include "Remote.h"
|
||||
#include "PID.h"
|
||||
#include "Parameter.h"
|
||||
#include "RefereeSystem.h"
|
||||
#include "Ultra_CAP.h"
|
||||
#include "Mecanum.h"
|
||||
|
||||
#define Mecanum_PowerControlSpeedNormalizationValue 3.0f//功率控制归一化速度标准值,范围[0,3]
|
||||
#define Mecanum_PowerControlGainCoefficientInitialValue 0.5f//功率控制增益系数初始值
|
||||
#define Mecanum_PowerControl_T 5.0f//功率控制周期(T=Mecanum_PowerControl_T*2ms)
|
||||
#define Mecanum_PowerControl_UseBuffer 30.0f//功率控制消耗的缓冲能量
|
||||
#define Mecanum_PowerControl_PowerMax 4.0f//功率控制功率上限与裁判系统功率上限比值上限
|
||||
#define Mecanum_PowerControl_UltraCAPPower 100.0f//使用超电增加功率
|
||||
|
||||
PID_PositionInitTypedef Mecanum_SpeedPID[4];//底盘四个电机的转速PID
|
||||
PID_PositionInitTypedef Mecanum_TrackPID;//底盘跟随PID
|
||||
float Mecanum_YawTheta;//底盘云台相对偏航角度
|
||||
uint8_t Mecanum_GyroScopeFlag;//底盘小陀螺标志位
|
||||
float Mecanum_Power;//底盘功率(软件计算值)
|
||||
float Mecanum_Current,Mecanum_PowerLimit,Mecanum_CurrentLimit=16384*4.0f;//底盘电流总和,功率控制功率上限,底盘电流限幅
|
||||
|
||||
/*
|
||||
*函数简介:麦轮初始化
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:即四个转速PID的初始化
|
||||
*备注:四个电机的ID参照上方的宏定义,最好使用M3508电机的ID1~4,否则下方电机控制的代码需要修改
|
||||
*/
|
||||
void Mecanum_Init(void)
|
||||
{
|
||||
PID_PositionStructureInit(&Mecanum_SpeedPID[0],0);//左前轮
|
||||
PID_PositionSetParameter(&Mecanum_SpeedPID[0],0.8,0,0);
|
||||
PID_PositionSetEkRange(&Mecanum_SpeedPID[0],-5,5);
|
||||
PID_PositionSetOUTRange(&Mecanum_SpeedPID[0],-15000,15000);
|
||||
|
||||
PID_PositionStructureInit(&Mecanum_SpeedPID[1],0);//右前轮
|
||||
PID_PositionSetParameter(&Mecanum_SpeedPID[1],0.8,0,0);
|
||||
PID_PositionSetEkRange(&Mecanum_SpeedPID[1],-5,5);
|
||||
PID_PositionSetOUTRange(&Mecanum_SpeedPID[1],-15000,15000);
|
||||
|
||||
PID_PositionStructureInit(&Mecanum_SpeedPID[2],0);//左后轮
|
||||
PID_PositionSetParameter(&Mecanum_SpeedPID[2],0.8,0,0);
|
||||
PID_PositionSetEkRange(&Mecanum_SpeedPID[2],-5,5);
|
||||
PID_PositionSetOUTRange(&Mecanum_SpeedPID[2],-15000,15000);
|
||||
|
||||
PID_PositionStructureInit(&Mecanum_SpeedPID[3],0);//右后轮
|
||||
PID_PositionSetParameter(&Mecanum_SpeedPID[3],0.8,0,0);
|
||||
PID_PositionSetEkRange(&Mecanum_SpeedPID[3],-5,5);
|
||||
PID_PositionSetOUTRange(&Mecanum_SpeedPID[3],-15000,15000);
|
||||
|
||||
PID_PositionStructureInit(&Mecanum_TrackPID,Yaw_GM6020PositionValue);//底盘跟随
|
||||
PID_PositionSetParameter(&Mecanum_TrackPID,0.007,0,0.8);
|
||||
PID_PositionSetEkRange(&Mecanum_TrackPID,-1,1);
|
||||
PID_PositionSetOUTRange(&Mecanum_TrackPID,-4,4);
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:麦轮PID清理
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:清理四个转速位置式PID
|
||||
*/
|
||||
void Mecanum_CleanPID(void)
|
||||
{
|
||||
PID_PositionClean(&Mecanum_SpeedPID[0]);//左前轮
|
||||
PID_PositionClean(&Mecanum_SpeedPID[1]);//右前轮
|
||||
PID_PositionClean(&Mecanum_SpeedPID[2]);//左后轮
|
||||
PID_PositionClean(&Mecanum_SpeedPID[3]);//右后轮
|
||||
PID_PositionClean(&Mecanum_TrackPID);//底盘跟随
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:麦轮速度控制
|
||||
*参数说明:左前轮速度
|
||||
*参数说明:右前轮速度
|
||||
*参数说明:左后轮速度
|
||||
*参数说明:右后轮速度
|
||||
*返回类型:无
|
||||
*备注:单独控制四个轮子的速度
|
||||
*/
|
||||
void Mecanum_ControlSpeed(int16_t LeftFrontSpeed,int16_t RightFrontSpeed,int16_t LeftRearSpeed,int16_t RightRearSpeed)
|
||||
{
|
||||
//更改期望
|
||||
Mecanum_SpeedPID[0].Need_Value=LeftFrontSpeed;//左前轮
|
||||
Mecanum_SpeedPID[1].Need_Value=RightFrontSpeed;//右前轮;
|
||||
Mecanum_SpeedPID[2].Need_Value=LeftRearSpeed;//左后轮
|
||||
Mecanum_SpeedPID[3].Need_Value=RightRearSpeed;//右后轮
|
||||
|
||||
//PID计算
|
||||
PID_PositionCalc(&Mecanum_SpeedPID[0],M3508_MotorStatus[Mecanum_LeftFrontWheel-0x201].RotorSpeed);//左前轮
|
||||
PID_PositionCalc(&Mecanum_SpeedPID[1],M3508_MotorStatus[Mecanum_RightFrontWheel-0x201].RotorSpeed);//右前轮
|
||||
PID_PositionCalc(&Mecanum_SpeedPID[2],M3508_MotorStatus[Mecanum_LeftRearWheel-0x201].RotorSpeed);//左后轮
|
||||
PID_PositionCalc(&Mecanum_SpeedPID[3],M3508_MotorStatus[Mecanum_RightRearWheel-0x201].RotorSpeed);//右后轮
|
||||
|
||||
Mecanum_Current=0;
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
Mecanum_Current+=fabs(Mecanum_SpeedPID[i].OUT);
|
||||
if(Mecanum_Current>Mecanum_CurrentLimit)
|
||||
{
|
||||
Mecanum_SpeedPID[0].OUT*=(Mecanum_CurrentLimit/Mecanum_Current);
|
||||
Mecanum_SpeedPID[1].OUT*=(Mecanum_CurrentLimit/Mecanum_Current);
|
||||
Mecanum_SpeedPID[2].OUT*=(Mecanum_CurrentLimit/Mecanum_Current);
|
||||
Mecanum_SpeedPID[3].OUT*=(Mecanum_CurrentLimit/Mecanum_Current);
|
||||
}
|
||||
|
||||
M3508_CANSetLIDCurrent(Mecanum_SpeedPID[1].OUT,Mecanum_SpeedPID[0].OUT,Mecanum_SpeedPID[2].OUT,Mecanum_SpeedPID[3].OUT);//M3508控制
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:麦轮逆运动解算
|
||||
*参数说明:x轴速度,单位m/s(以前为正)
|
||||
*参数说明:y轴速度,单位m/s(以左为正)
|
||||
*参数说明:z轴转速,单位rad/s(以逆时针为正)
|
||||
*返回类型:无
|
||||
*备注:速度转速转换系数:
|
||||
* w'=v/R (rad/s)=v/(2Π×R) (r/s)=60×v/(2Π×R) (r/min)=1/19 w
|
||||
* ⇒ w=19×60×v/(2Π×R/100)=19×60×100×v/(2Π×R)=18143.663512×v/R,R单位cm
|
||||
*备注:麦轮半径参数在上方宏定义Mecanum_WheelRadius修改,默认7cm,转换参数2591.95
|
||||
*备注:底盘中心到轮子中心的距离由上方宏定义x轴分量Mecanum_rx和y轴分量Mecanum_ry决定
|
||||
*/
|
||||
void Mecanum_InverseMotionControl(float v_x,float v_y,float w)
|
||||
{
|
||||
//逆运动解算
|
||||
int16_t LeftFrontSpeed=(int16_t)((-v_x-v_y-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//左前轮
|
||||
int16_t RightFrontSpeed=(int16_t)((v_x-v_y-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//右前轮
|
||||
int16_t LeftRearSpeed=(int16_t)((-v_x+v_y-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//左后轮
|
||||
int16_t RightRearSpeed=(int16_t)((v_x+v_y-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//右后轮
|
||||
|
||||
Mecanum_ControlSpeed(LeftFrontSpeed,RightFrontSpeed,LeftRearSpeed,RightRearSpeed);//M3508速度控制
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:麦轮功率控制
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:麦轮是否开启可功率控制模式决定于上方宏定义Mecanum_PowerControl
|
||||
*备注:以Mecanum_PowerControl_T*2ms为控制周期,取底盘平均功率(通过M3508反馈数据计算),通过速度增益系数和速度归一化控制速度大小,速度增益系数在[0,2]范围内
|
||||
*备注:速度归一化的标准值在上方宏定义Mecanum_PowerControlSpeedNormalizationValue修改,范围[0,3]
|
||||
*备注:增益系数的初始值在上方宏定义Mecanum_PowerControlGainCoefficientInitialValue修改
|
||||
*备注:设定功率上限最高为150W限幅
|
||||
*备注:速度转速转换系数:
|
||||
* w'=v/R (rad/s)=v/(2Π×R) (r/s)=60×v/(2Π×R) (r/min)=1/19 w
|
||||
* ⇒ w=19×60×v/(2Π×R/100)=19×60×100×v/(2Π×R)=18143.663512×v/R,R单位cm
|
||||
*备注:麦轮半径参数在上方宏定义Mecanum_WheelRadius修改,默认7cm,转换参数2591.95
|
||||
*备注:底盘中心到轮子中心的距离由上方宏定义x轴分量Mecanum_rx和y轴分量Mecanum_ry决定
|
||||
*/
|
||||
void Mecanum_PowerMoveControl(void)
|
||||
{
|
||||
static uint8_t Mecanum_GyroScopeCloseFlag=0;//小陀螺待关闭标志位
|
||||
static float GainCoefficient=1.0f;//速度增益系数
|
||||
static uint8_t Count=0;//计数器,以Mecanum_PowerControl_T*2ms为控制周期
|
||||
|
||||
/*==========三轴速度获取==========*/
|
||||
float vx=1024-Remote_RxData.Remote_R_UD;
|
||||
float vy=1024-Remote_RxData.Remote_R_RL;
|
||||
float w=1024-Remote_RxData.Remote_L_RL;//获取三个轴的速度参量
|
||||
float sigma=sqrtf(vx*vx+vy*vy);//获取xy轴速度归一化系数
|
||||
if(sigma!=0)//x,y轴速度归一化(正交合成速度不变为标准值)
|
||||
{
|
||||
vx=vx/sigma*Mecanum_PowerControlSpeedNormalizationValue;
|
||||
vy=vy/sigma*Mecanum_PowerControlSpeedNormalizationValue;
|
||||
}
|
||||
|
||||
int16_t Raw_Theta=Yaw_GM6020PositionValue-GM6020_MotorStatus[0].Angle;//获取底盘云台相对角度原始数据
|
||||
if(Raw_Theta<0)Raw_Theta+=8192;
|
||||
//Mecanum_YawTheta=Raw_Theta/8192.0f*2.0f*3.141592653589793238462643383279f;
|
||||
Mecanum_YawTheta=Raw_Theta*0.000766990393942820614859043794746f;//获取底盘云台相对角度
|
||||
|
||||
float vx_=vx,vy_=vy;
|
||||
vx=vx_*cosf(Mecanum_YawTheta)-vy_*sinf(Mecanum_YawTheta);
|
||||
vy=vx_*sinf(Mecanum_YawTheta)+vy_*cosf(Mecanum_YawTheta);//根据底盘云台相对角度修正xy轴速度
|
||||
|
||||
/*==========小陀螺处理==========*/
|
||||
if(Yaw_GM6020PositionValue<4096)//正向小陀螺为逆时针
|
||||
{
|
||||
if((Remote_RxData.Remote_RS==2 || Remote_RxData.Remote_KeyPush_Ctrl==1) || (Mecanum_GyroScopeFlag==1 && Mecanum_GyroScopeCloseFlag==1 && GM6020_MotorStatus[0].Position<Yaw_GM6020PositionValue+500))//小陀螺模式
|
||||
{
|
||||
w=Mecanum_GyroScopeAngularVelocity;
|
||||
Mecanum_GyroScopeFlag=1;//处于小陀螺状态
|
||||
Mecanum_GyroScopeCloseFlag=1;//小陀螺处于待关闭状态
|
||||
}
|
||||
else if(Mecanum_GyroScopeFlag==1 && ((GM6020_MotorStatus[0].Angle>Yaw_GM6020PositionValue+100 || GM6020_MotorStatus[0].Angle<Yaw_GM6020PositionValue-100) || (GM6020_MotorStatus[0].Speed>2||GM6020_MotorStatus[0].Speed<-2)))//小陀螺关闭状态
|
||||
{
|
||||
PID_PositionSetOUTRange(&Mecanum_TrackPID,-2,2);
|
||||
PID_PositionCalc(&Mecanum_TrackPID,GM6020_MotorStatus[0].Position);//底盘跟云台
|
||||
w=-Mecanum_TrackPID.OUT;
|
||||
Mecanum_GyroScopeCloseFlag=0;//小陀螺未处于待关闭状态
|
||||
}
|
||||
else if(Remote_RxData.Remote_RS==1)//反向小陀螺模式(仅检录使用)
|
||||
w=-Mecanum_GyroScopeAngularVelocity;
|
||||
else
|
||||
{
|
||||
PID_PositionSetOUTRange(&Mecanum_TrackPID,-5,5);
|
||||
Mecanum_GyroScopeFlag=0;
|
||||
PID_PositionCalc(&Mecanum_TrackPID,GM6020_MotorStatus[0].Position);//底盘跟云台
|
||||
w=-Mecanum_TrackPID.OUT;
|
||||
}
|
||||
}
|
||||
else//正向小陀螺为顺时针
|
||||
{
|
||||
if((Remote_RxData.Remote_RS==2 || Remote_RxData.Remote_KeyPush_Ctrl==1) || (Mecanum_GyroScopeFlag==1 && Mecanum_GyroScopeCloseFlag==1 && GM6020_MotorStatus[0].Position>Yaw_GM6020PositionValue-500))//小陀螺模式
|
||||
{
|
||||
w=-Mecanum_GyroScopeAngularVelocity;
|
||||
Mecanum_GyroScopeFlag=1;//处于小陀螺状态
|
||||
Mecanum_GyroScopeCloseFlag=1;//小陀螺处于待关闭状态
|
||||
}
|
||||
else if(Mecanum_GyroScopeFlag==1 && ((GM6020_MotorStatus[0].Angle>Yaw_GM6020PositionValue+5 || GM6020_MotorStatus[0].Angle<Yaw_GM6020PositionValue-5) || (GM6020_MotorStatus[0].Speed>1||GM6020_MotorStatus[0].Speed<-1)))//小陀螺关闭状态
|
||||
{
|
||||
PID_PositionSetOUTRange(&Mecanum_TrackPID,-2,2);
|
||||
PID_PositionCalc(&Mecanum_TrackPID,GM6020_MotorStatus[0].Position);//底盘跟云台
|
||||
w=-Mecanum_TrackPID.OUT;
|
||||
Mecanum_GyroScopeCloseFlag=0;//小陀螺未处于待关闭状态
|
||||
}
|
||||
else if(Remote_RxData.Remote_RS==1)//反向小陀螺模式(仅检录使用)
|
||||
w=Mecanum_GyroScopeAngularVelocity;
|
||||
else
|
||||
{
|
||||
PID_PositionSetOUTRange(&Mecanum_TrackPID,-5,5);
|
||||
Mecanum_GyroScopeFlag=0;
|
||||
PID_PositionCalc(&Mecanum_TrackPID,GM6020_MotorStatus[0].Position);//底盘跟云台
|
||||
w=-Mecanum_TrackPID.OUT;
|
||||
}
|
||||
}
|
||||
|
||||
/*==========功率上限处理==========*/
|
||||
/*由缓冲能量得到功率控制功率上限*/
|
||||
float Mecanum_PowerRef=1.0f/(60.0f-Mecanum_PowerControl_UseBuffer)*RefereeSystem_Buffer;//功率增益
|
||||
if(Mecanum_PowerRef>Mecanum_PowerControl_PowerMax)Mecanum_PowerRef=Mecanum_PowerControl_PowerMax;
|
||||
Mecanum_PowerLimit=Mecanum_PowerRef*RefereeSystem_Ref;
|
||||
|
||||
/*由运动状态约束功率控制功率上限*/
|
||||
float Scale=sigma/660.0f;
|
||||
if(Scale<1 && Scale>0)Mecanum_PowerLimit*=Scale;//平移约束
|
||||
if(Mecanum_GyroScopeFlag==1)Mecanum_PowerLimit=Mecanum_PowerRef*RefereeSystem_Ref;//小陀螺约束
|
||||
if(Mecanum_PowerLimit>150.0f)Mecanum_PowerLimit=150.0f;//限幅约束
|
||||
|
||||
/*由超电约束功率控制功率上限*/
|
||||
if(Remote_RxData.Remote_KeyPush_Shift==1)//开启超电
|
||||
{
|
||||
if(Mecanum_PowerLimit>0.0f)
|
||||
{
|
||||
if(Mecanum_PowerLimit<RefereeSystem_Ref)Mecanum_PowerLimit+=Mecanum_PowerControl_UltraCAPPower;
|
||||
else Mecanum_PowerLimit=RefereeSystem_Ref+Mecanum_PowerControl_UltraCAPPower;
|
||||
}
|
||||
Ultra_CAP_SetPower(RefereeSystem_Ref);
|
||||
}
|
||||
else
|
||||
Ultra_CAP_SetPower(Mecanum_PowerLimit);
|
||||
|
||||
/*==========功率控制==========*/
|
||||
static float PowerSum=0;//控制周期内的功率积分
|
||||
Mecanum_Power=1.732050807568877f*(M3508_MotorStatus[Mecanum_LeftFrontWheel-0x201].Power \
|
||||
+M3508_MotorStatus[Mecanum_RightFrontWheel-0x201].Power \
|
||||
+M3508_MotorStatus[Mecanum_LeftRearWheel-0x201].Power \
|
||||
+M3508_MotorStatus[Mecanum_RightRearWheel-0x201].Power);//获取底盘功率
|
||||
PowerSum+=Mecanum_Power;
|
||||
|
||||
/*速度增益*/
|
||||
if(Count==Mecanum_PowerControl_T)//一个控制周期
|
||||
{
|
||||
Count=0;//计数器清零
|
||||
float Power_avg=PowerSum/Mecanum_PowerControl_T;
|
||||
PowerSum=0;
|
||||
|
||||
if(Power_avg<Mecanum_PowerLimit/2.0f)
|
||||
{
|
||||
GainCoefficient+=0.05f;//增益系数递减
|
||||
if(GainCoefficient>2)GainCoefficient=2;//增益系数限上幅2
|
||||
}
|
||||
else if(Power_avg<Mecanum_PowerLimit-5)
|
||||
{
|
||||
GainCoefficient+=0.02f;//增益系数递减
|
||||
if(GainCoefficient>2)GainCoefficient=2;//增益系数限上幅2
|
||||
}
|
||||
else if(Power_avg>Mecanum_PowerLimit+5)
|
||||
{
|
||||
if(RefereeSystem_Buffer<60.0f-Mecanum_PowerControl_UseBuffer)GainCoefficient-=0.05f;//增益系数递增
|
||||
else GainCoefficient-=0.02f;//增益系数递增
|
||||
if(GainCoefficient<Mecanum_PowerControlGainCoefficientInitialValue/2.0f)GainCoefficient=Mecanum_PowerControlGainCoefficientInitialValue/2.0f;//增益系数限下幅
|
||||
}
|
||||
}
|
||||
else if(vx!=0 || vy!=0 || Mecanum_GyroScopeFlag==1)//正常运动
|
||||
Count++;
|
||||
else//停止运动
|
||||
GainCoefficient=Mecanum_PowerControlGainCoefficientInitialValue;//增益系数回归初始值
|
||||
if(Mecanum_GyroScopeFlag==1 && (vx!=0 || vy!=0)){w*=0.6f;vx*=0.5f;vy*=0.5f;}//小陀螺移动直接降速,保证移动瞬间为缓冲能量增加
|
||||
|
||||
/*电流限幅*/
|
||||
float Mecanum_BufferCurrent=Mecanum_PowerLimit*512.0f/15.0f;
|
||||
float Mecanum_PowerCurrent=Mecanum_PowerLimit*512.0f/15.0f*5.0f;
|
||||
float B,C=0.9f;
|
||||
if(60.0f-Mecanum_PowerControl_UseBuffer-10.0f>10.0f)B=60.0f-Mecanum_PowerControl_UseBuffer-10.0f;
|
||||
else B=10.0f;
|
||||
if(RefereeSystem_Buffer>B)
|
||||
{
|
||||
float PowerScale=0;
|
||||
if(Mecanum_Power>C*Mecanum_PowerLimit)
|
||||
{
|
||||
if(Mecanum_Power>Mecanum_PowerLimit)PowerScale=0;
|
||||
else PowerScale=(Mecanum_PowerLimit-Mecanum_Power)/(Mecanum_PowerLimit-C*Mecanum_PowerLimit);
|
||||
}
|
||||
else PowerScale=1;
|
||||
Mecanum_CurrentLimit=Mecanum_BufferCurrent+Mecanum_PowerCurrent*PowerScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RefereeSystem_Buffer<5.0f)Mecanum_CurrentLimit=Mecanum_BufferCurrent*0.5f;
|
||||
else Mecanum_CurrentLimit=Mecanum_BufferCurrent*(RefereeSystem_Buffer+B-10.0f)/(2*B-10.0f);
|
||||
}
|
||||
if(Mecanum_CurrentLimit>16384*4)Mecanum_CurrentLimit=16384*4;
|
||||
|
||||
/*==========运动控制==========*/
|
||||
vx*=GainCoefficient;vy*=GainCoefficient;
|
||||
if(Mecanum_GyroScopeFlag==1)w*=GainCoefficient;
|
||||
int16_t LeftFrontSpeed=(int16_t)((-vx-vy-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//左前
|
||||
int16_t RightFrontSpeed=(int16_t)((vx-vy-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//右前
|
||||
int16_t LeftRearSpeed=(int16_t)((-vx+vy-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//左后
|
||||
int16_t RightRearSpeed=(int16_t)((vx+vy-w*(Mecanum_rx+Mecanum_ry)/100.0f)/Mecanum_WheelRadius*18143.663512f);//右后
|
||||
|
||||
Mecanum_ControlSpeed(LeftFrontSpeed,RightFrontSpeed,LeftRearSpeed,RightRearSpeed);
|
||||
}
|
||||
18
底盘独立控制器/code/CarBody/Mecanum.h
Normal file
18
底盘独立控制器/code/CarBody/Mecanum.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef __MECANUM_H
|
||||
#define __MECANUM_H
|
||||
|
||||
#define Mecanum_LeftFrontWheel M3508_2//左前轮
|
||||
#define Mecanum_RightFrontWheel M3508_1//右前轮
|
||||
#define Mecanum_LeftRearWheel M3508_3//左后轮
|
||||
#define Mecanum_RightRearWheel M3508_4//右后轮
|
||||
|
||||
extern float Mecanum_Power;//底盘功率(软件计算值)
|
||||
extern float Mecanum_YawTheta;//底盘云台相对偏航角度
|
||||
|
||||
void Mecanum_Init(void);//麦轮初始化
|
||||
void Mecanum_CleanPID(void);//麦轮PID清理
|
||||
void Mecanum_ControlSpeed(int16_t LeftFrontSpeed,int16_t RightFrontSpeed,int16_t LeftRearSpeed,int16_t RightRearSpeed);//麦轮速度控制
|
||||
void Mecanum_InverseMotionControl(float v_x,float v_y,float w);//麦轮逆运动解算
|
||||
void Mecanum_PowerMoveControl(void);//麦轮功率控制
|
||||
|
||||
#endif
|
||||
210
底盘独立控制器/code/CarBody/RefereeSystem.c
Normal file
210
底盘独立控制器/code/CarBody/RefereeSystem.c
Normal file
@@ -0,0 +1,210 @@
|
||||
#include "stm32f4xx.h" // Device header
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "RefereeSystem_CRCTable.h"
|
||||
#include "UART.h"
|
||||
|
||||
/****************************************************************************************************
|
||||
|
||||
此处裁判系统只接收0x0201命令,获取机器人性能体系数据,主要获取发射机构是否上电
|
||||
帧格式:
|
||||
0xA5 0x0D 0x00 包序号 帧头CRC8校验 0x01 0x02 13ByteData 整包CRC16校验
|
||||
|___________________________________| |_______| |
|
||||
帧头 命令码 数据
|
||||
|
||||
****************************************************************************************************/
|
||||
|
||||
/*接收数据缓冲区数组元素数=命令码对应数据段长度+9*/
|
||||
uint8_t RefereeSystem_RxHEXPacket1[22]={0xA5,0x0D,0x00,0x00,0x00,0x01,0x02,0};//裁判系统0x0201命令码接收数据缓冲区
|
||||
uint8_t RefereeSystem_RxHEXPacket2[25]={0xA5,0x10,0x00,0x00,0x00,0x02,0x02,0};//裁判系统0x0202命令码接收数据缓冲区
|
||||
|
||||
uint8_t RefereeSystem_ShooterStatus=1;//发射机构状态,0-发射机构未上电,1-发射机构上电
|
||||
uint16_t RefereeSystem_Ref=120,RefereeSystem_Buffer=30.0f;//底盘功率上限,底盘功率缓冲能量(若无裁判系统,默认功率上限80W,缓冲能量30J)
|
||||
float RefereeSystem_Power;//底盘实时功率
|
||||
uint8_t RefereeSystem_RobotID=0;//机器人ID(无裁判系统时一直为0,4号步兵ID为4/104)
|
||||
|
||||
/*
|
||||
*函数简介:裁判系统CRC8查表计算
|
||||
*参数说明:校验数据
|
||||
*参数说明:数据长度
|
||||
*参数说明:CRC初始值(默认给参数0xFF)
|
||||
*返回类型:无
|
||||
*备注:表格位于Referee System_CRCTable.h文件中CRC8_Table数组
|
||||
*/
|
||||
uint8_t RefereeSystem_GetCRC8CheckSum(uint8_t *Data,uint16_t Length,uint8_t Initial)
|
||||
{
|
||||
uint8_t Minuend;
|
||||
while(Length--)
|
||||
{
|
||||
Minuend=Initial^(*Data);
|
||||
Data++;
|
||||
Initial=CRC8_Table[Minuend];
|
||||
}
|
||||
return Initial;
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:裁判系统CRC8校验
|
||||
*参数说明:校验数据(含尾端CRC校验码)
|
||||
*参数说明:数据长度
|
||||
*返回类型:校验正确返回1,否则返回0
|
||||
*备注:无
|
||||
*/
|
||||
uint8_t RefereeSystem_VerifyCRC8CheckSum(uint8_t *Data,uint16_t Length)
|
||||
{
|
||||
uint8_t CRC8CheckSum=0;
|
||||
if((Data==0) || (Length<=2))return 0;//特殊情况处理
|
||||
CRC8CheckSum=RefereeSystem_GetCRC8CheckSum(Data,Length-1,CRC8_Initial);//获取CRC8计算值
|
||||
return CRC8CheckSum==Data[Length-1];//测量值与计算值相比较
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:裁判系统CRC16查表计算
|
||||
*参数说明:校验数据
|
||||
*参数说明:数据长度
|
||||
*参数说明:CRC初始值(默认给参数0xFFFF)
|
||||
*返回类型:无
|
||||
*备注:表格位于Referee System_CRCTable.h文件中CRC16_Table数组
|
||||
*/
|
||||
uint16_t RefereeSystem_GetCRC16CheckSum(uint8_t *Data,uint32_t Length,uint16_t Initial)
|
||||
{
|
||||
uint8_t Minuend;
|
||||
while(Length--)
|
||||
{
|
||||
Minuend=*Data;
|
||||
Data++;
|
||||
Initial=((uint16_t)(Initial)>>8)^CRC16_Table[((uint16_t)(Initial)^(uint16_t)(Minuend))&0x00FF];
|
||||
}
|
||||
return Initial;
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:裁判系统CRC16校验
|
||||
*参数说明:校验数据(含尾端CRC校验码)
|
||||
*参数说明:数据长度
|
||||
*返回类型:校验正确返回1,否则返回0
|
||||
*备注:无
|
||||
*/
|
||||
uint32_t RefereeSystem_VerifyCRC16CheckSum(uint8_t *Data, uint32_t Length)
|
||||
{
|
||||
uint16_t CRC16CheckSum=0;
|
||||
if((Data==0)||(Length<=2))return 0;//特殊情况处理
|
||||
CRC16CheckSum=RefereeSystem_GetCRC16CheckSum(Data,Length-2,CRC16_Initial);//获取CRC16计算值
|
||||
return ((CRC16CheckSum&0xFF)==Data[Length-2]&&((CRC16CheckSum>>8)&0xff)==Data[Length-1]);//测量值与计算值相比较
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:裁判系统接收初始化
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:默认使用UART1(USART6),默认Rx引脚PG9
|
||||
*/
|
||||
void RefereeSystem_Init(void)
|
||||
{
|
||||
UART1_Init();
|
||||
//while(RefereeSystem_RobotID==0);
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:UART1串口中断接收裁判系统数据
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:数据帧格式在最上方注释
|
||||
*/
|
||||
void USART6_IRQHandler(void)
|
||||
{
|
||||
/*有效数据位数=命令码对应数据段长度+2*/
|
||||
#define DataLength1 15//裁判系统0x0201命令码有效数据位数
|
||||
#define DataLength2 18//裁判系统0x0202命令码有效数据位数
|
||||
|
||||
static int RxHEXState=0;//定义静态变量用于接收模式的选择
|
||||
static int pRxHEXState=0;//定义静态变量用于充当计数器
|
||||
|
||||
uint8_t RefereeSystem_RxData;//裁判系统接收数据
|
||||
int RefereeSystem_PowerRow;//底盘实时功率原始数据
|
||||
|
||||
if(USART_GetITStatus(USART6,USART_IT_RXNE)==SET)//查询接收中断标志位
|
||||
{
|
||||
USART_ClearITPendingBit(USART6,USART_IT_RXNE);//清除接收中断标志位
|
||||
|
||||
RefereeSystem_RxData=USART_ReceiveData(USART6);//将数据存入缓存区
|
||||
|
||||
/*=====检查帧头=====*/
|
||||
if(RxHEXState==0){if(RefereeSystem_RxData==0xA5)RxHEXState=1;}
|
||||
|
||||
/*=====检查数据段长度,区分命令码=====*/
|
||||
else if(RxHEXState==1)
|
||||
{
|
||||
if(RefereeSystem_RxData==0x0D)RxHEXState=2;//0x0201命令码
|
||||
else if(RefereeSystem_RxData==0x10)RxHEXState=8;//0x0202命令码
|
||||
else RxHEXState=0;//其他命令码直接跳过
|
||||
}
|
||||
|
||||
/*=====0x0201命令码=====*/
|
||||
/*=====检查帧头其他部分=====*/
|
||||
else if(RxHEXState==2){if(RefereeSystem_RxData==0x00)RxHEXState=3;else RxHEXState=0;}
|
||||
else if(RxHEXState==3){RefereeSystem_RxHEXPacket1[3]=RefereeSystem_RxData;RxHEXState=4;}
|
||||
else if(RxHEXState==4)
|
||||
{
|
||||
RefereeSystem_RxHEXPacket1[4]=RefereeSystem_RxData;
|
||||
|
||||
if(RefereeSystem_VerifyCRC8CheckSum(RefereeSystem_RxHEXPacket1,5)==1)RxHEXState=5;//检查CRC8
|
||||
else RxHEXState=0;
|
||||
}
|
||||
|
||||
/*=====检查命令码=====*/
|
||||
else if(RxHEXState==5){if(RefereeSystem_RxData==0x01)RxHEXState=6;else RxHEXState=0;}
|
||||
else if(RxHEXState==6){if(RefereeSystem_RxData==0x02){RxHEXState=7;pRxHEXState=0;}else RxHEXState=0;}
|
||||
|
||||
/*=====接收有效数据=====*/
|
||||
else if(RxHEXState==7)
|
||||
{
|
||||
RefereeSystem_RxHEXPacket1[pRxHEXState+7]=RefereeSystem_RxData;//接收数据
|
||||
pRxHEXState++;
|
||||
|
||||
if(pRxHEXState>=DataLength1)
|
||||
{
|
||||
if(RefereeSystem_VerifyCRC16CheckSum(RefereeSystem_RxHEXPacket1,22)==1)//CRC校验
|
||||
{
|
||||
RefereeSystem_RobotID=RefereeSystem_RxHEXPacket1[7];//获取机器人ID
|
||||
RefereeSystem_ShooterStatus=(RefereeSystem_RxHEXPacket1[19]&0x04)>>2;//获取发射机构状态
|
||||
RefereeSystem_Ref=RefereeSystem_RxHEXPacket1[17]|((uint16_t)RefereeSystem_RxHEXPacket1[18]<<8);//获取功率上限
|
||||
}
|
||||
RxHEXState=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=====0x0202命令码=====*/
|
||||
/*=====检查帧头其他部分=====*/
|
||||
else if(RxHEXState==8){if(RefereeSystem_RxData==0x00)RxHEXState=9;else RxHEXState=0;}
|
||||
else if(RxHEXState==9){RefereeSystem_RxHEXPacket2[3]=RefereeSystem_RxData;RxHEXState=10;}
|
||||
else if(RxHEXState==10)
|
||||
{
|
||||
RefereeSystem_RxHEXPacket2[4]=RefereeSystem_RxData;
|
||||
if(RefereeSystem_VerifyCRC8CheckSum(RefereeSystem_RxHEXPacket2,5)==1)RxHEXState=11;
|
||||
else RxHEXState=0;
|
||||
}
|
||||
|
||||
/*=====检查命令码=====*/
|
||||
else if(RxHEXState==11){if(RefereeSystem_RxData==0x02)RxHEXState=12;else RxHEXState=0;}
|
||||
else if(RxHEXState==12){if(RefereeSystem_RxData==0x02){RxHEXState=13;pRxHEXState=0;}else RxHEXState=0;}
|
||||
|
||||
/*=====接收有效数据=====*/
|
||||
else if(RxHEXState==13)
|
||||
{
|
||||
RefereeSystem_RxHEXPacket2[pRxHEXState+7]=RefereeSystem_RxData;//接收数据
|
||||
pRxHEXState++;
|
||||
|
||||
if(pRxHEXState>=DataLength2)
|
||||
{
|
||||
if(RefereeSystem_VerifyCRC16CheckSum(RefereeSystem_RxHEXPacket2,25)==1)//CRC校验
|
||||
{
|
||||
RefereeSystem_Buffer=RefereeSystem_RxHEXPacket2[15]|((uint16_t)RefereeSystem_RxHEXPacket2[16]<<8);//获取缓冲能量
|
||||
RefereeSystem_PowerRow=(int32_t)((uint32_t)RefereeSystem_RxHEXPacket2[11]|((uint32_t)RefereeSystem_RxHEXPacket2[12]<<8)|((uint32_t)RefereeSystem_RxHEXPacket2[13]<<16)|((uint32_t)RefereeSystem_RxHEXPacket2[14]<<24));
|
||||
RefereeSystem_Power=*((float *)(&RefereeSystem_PowerRow));//获取底盘实时功率
|
||||
}
|
||||
RxHEXState=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
底盘独立控制器/code/CarBody/RefereeSystem.h
Normal file
13
底盘独立控制器/code/CarBody/RefereeSystem.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __REFEREESYSTEM_H
|
||||
#define __REFEREESYSTEM_H
|
||||
|
||||
extern uint8_t RefereeSystem_ShooterStatus;//发射机构状态,0-发射机构未上电,1-发射机构上电
|
||||
extern uint16_t RefereeSystem_Ref,RefereeSystem_Buffer;//底盘功率上限,底盘功率缓冲能量
|
||||
extern float RefereeSystem_Power;//底盘实时功率
|
||||
extern uint8_t RefereeSystem_RobotID;//机器人ID
|
||||
|
||||
uint8_t RefereeSystem_GetCRC8CheckSum(uint8_t *Data,uint16_t Length,uint8_t Initial);//裁判系统CRC8查表计算
|
||||
uint16_t RefereeSystem_GetCRC16CheckSum(uint8_t *Data,uint32_t Length,uint16_t Initial);//裁判系统CRC16查表计算
|
||||
void RefereeSystem_Init(void);//裁判系统接收初始化
|
||||
|
||||
#endif
|
||||
46
底盘独立控制器/code/CarBody/RefereeSystem_CRCTable.c
Normal file
46
底盘独立控制器/code/CarBody/RefereeSystem_CRCTable.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "stm32f4xx.h" // Device header
|
||||
#include "stm32f4xx_conf.h"
|
||||
|
||||
//crc8 generator polynomial:G(x)=x8+x5+x4+1//CRC8-MAXIM
|
||||
uint8_t CRC8_Initial=0xFF;//CRC8初始值
|
||||
const uint8_t CRC8_Table[256]=
|
||||
{
|
||||
0x00,0x5E,0xBC,0xE2,0x61,0x3F,0xDD,0x83,0xC2,0x9C,0x7E,0x20,0xA3,0xFD,0x1F,0x41,
|
||||
0x9D,0xC3,0x21,0x7F,0xFC,0xA2,0x40,0x1E,0x5F,0x01,0xE3,0xBD,0x3E,0x60,0x82,0xDC,
|
||||
0x23,0x7D,0x9F,0xC1,0x42,0x1C,0xFE,0xA0,0xE1,0xBF,0x5D,0x03,0x80,0xDE,0x3C,0x62,
|
||||
0xBE,0xE0,0x02,0x5C,0xDF,0x81,0x63,0x3D,0x7C,0x22,0xC0,0x9E,0x1D,0x43,0xA1,0xFF,
|
||||
0x46,0x18,0xFA,0xA4,0x27,0x79,0x9B,0xC5,0x84,0xDA,0x38,0x66,0xE5,0xBB,0x59,0x07,
|
||||
0xDB,0x85,0x67,0x39,0xBA,0xE4,0x06,0x58,0x19,0x47,0xA5,0xFB,0x78,0x26,0xC4,0x9A,
|
||||
0x65,0x3B,0xD9,0x87,0x04,0x5A,0xB8,0xE6,0xA7,0xF9,0x1B,0x45,0xC6,0x98,0x7A,0x24,
|
||||
0xF8,0xA6,0x44,0x1A,0x99,0xC7,0x25,0x7B,0x3A,0x64,0x86,0xD8,0x5B,0x05,0xE7,0xB9,
|
||||
0x8C,0xD2,0x30,0x6E,0xED,0xB3,0x51,0x0F,0x4E,0x10,0xF2,0xAC,0x2F,0x71,0x93,0xCD,
|
||||
0x11,0x4F,0xAD,0xF3,0x70,0x2E,0xCC,0x92,0xD3,0x8D,0x6F,0x31,0xB2,0xEC,0x0E,0x50,
|
||||
0xAF,0xF1,0x13,0x4D,0xCE,0x90,0x72,0x2C,0x6D,0x33,0xD1,0x8F,0x0C,0x52,0xB0,0xEE,
|
||||
0x32,0x6C,0x8E,0xD0,0x53,0x0D,0xEF,0xB1,0xF0,0xAE,0x4C,0x12,0x91,0xCF,0x2D,0x73,
|
||||
0xCA,0x94,0x76,0x28,0xAB,0xF5,0x17,0x49,0x08,0x56,0xB4,0xEA,0x69,0x37,0xD5,0x8B,
|
||||
0x57,0x09,0xEB,0xB5,0x36,0x68,0x8A,0xD4,0x95,0xCB,0x29,0x77,0xF4,0xAA,0x48,0x16,
|
||||
0xE9,0xB7,0x55,0x0B,0x88,0xD6,0x34,0x6A,0x2B,0x75,0x97,0xC9,0x4A,0x14,0xF6,0xA8,
|
||||
0x74,0x2A,0xC8,0x96,0x15,0x4B,0xA9,0xF7,0xB6,0xE8,0x0A,0x54,0xD7,0x89,0x6B,0x35
|
||||
};
|
||||
|
||||
//crc16 generator polynomial:G(x)=x16+x12+x5+1//CRC16-CCITT
|
||||
uint16_t CRC16_Initial=0xFFFF;//CRC16初始值
|
||||
const uint16_t CRC16_Table[256]=
|
||||
{
|
||||
0x0000,0x1189,0x2312,0x329B,0x4624,0x57AD,0x6536,0x74BF,0x8C48,0x9DC1,0xAF5A,0xBED3,0xCA6C,0xDBE5,0xE97E,0xF8F7,
|
||||
0x1081,0x0108,0x3393,0x221A,0x56A5,0x472C,0x75B7,0x643E,0x9CC9,0x8D40,0xBFDB,0xAE52,0xDAED,0xCB64,0xF9FF,0xE876,
|
||||
0x2102,0x308B,0x0210,0x1399,0x6726,0x76AF,0x4434,0x55BD,0xAD4A,0xBCC3,0x8E58,0x9FD1,0xEB6E,0xFAE7,0xC87C,0xD9F5,
|
||||
0x3183,0x200A,0x1291,0x0318,0x77A7,0x662E,0x54B5,0x453C,0xBDCB,0xAC42,0x9ED9,0x8F50,0xFBEF,0xEA66,0xD8FD,0xC974,
|
||||
0x4204,0x538D,0x6116,0x709F,0x0420,0x15A9,0x2732,0x36BB,0xCE4C,0xDFC5,0xED5E,0xFCD7,0x8868,0x99E1,0xAB7A,0xBAF3,
|
||||
0x5285,0x430C,0x7197,0x601E,0x14A1,0x0528,0x37B3,0x263A,0xDECD,0xCF44,0xFDDF,0xEC56,0x98E9,0x8960,0xBBFB,0xAA72,
|
||||
0x6306,0x728F,0x4014,0x519D,0x2522,0x34AB,0x0630,0x17B9,0xEF4E,0xFEC7,0xCC5C,0xDDD5,0xA96A,0xB8E3,0x8A78,0x9BF1,
|
||||
0x7387,0x620E,0x5095,0x411C,0x35A3,0x242A,0x16B1,0x0738,0xFFCF,0xEE46,0xDCDD,0xCD54,0xB9EB,0xA862,0x9AF9,0x8B70,
|
||||
0x8408,0x9581,0xA71A,0xB693,0xC22C,0xD3A5,0xE13E,0xF0B7,0x0840,0x19C9,0x2B52,0x3ADB,0x4E64,0x5FED,0x6D76,0x7CFF,
|
||||
0x9489,0x8500,0xB79B,0xA612,0xD2AD,0xC324,0xF1BF,0xE036,0x18C1,0x0948,0x3BD3,0x2A5A,0x5EE5,0x4F6C,0x7DF7,0x6C7E,
|
||||
0xA50A,0xB483,0x8618,0x9791,0xE32E,0xF2A7,0xC03C,0xD1B5,0x2942,0x38CB,0x0A50,0x1BD9,0x6F66,0x7EEF,0x4C74,0x5DFD,
|
||||
0xB58B,0xA402,0x9699,0x8710,0xF3AF,0xE226,0xD0BD,0xC134,0x39C3,0x284A,0x1AD1,0x0B58,0x7FE7,0x6E6E,0x5CF5,0x4D7C,
|
||||
0xC60C,0xD785,0xE51E,0xF497,0x8028,0x91A1,0xA33A,0xB2B3,0x4A44,0x5BCD,0x6956,0x78DF,0x0C60,0x1DE9,0x2F72,0x3EFB,
|
||||
0xD68D,0xC704,0xF59F,0xE416,0x90A9,0x8120,0xB3BB,0xA232,0x5AC5,0x4B4C,0x79D7,0x685E,0x1CE1,0x0D68,0x3FF3,0x2E7A,
|
||||
0xE70E,0xF687,0xC41C,0xD595,0xA12A,0xB0A3,0x8238,0x93B1,0x6B46,0x7ACF,0x4854,0x59DD,0x2D62,0x3CEB,0x0E70,0x1FF9,
|
||||
0xF78F,0xE606,0xD49D,0xC514,0xB1AB,0xA022,0x92B9,0x8330,0x7BC7,0x6A4E,0x58D5,0x495C,0x3DE3,0x2C6A,0x1EF1,0x0F78
|
||||
};
|
||||
12
底盘独立控制器/code/CarBody/RefereeSystem_CRCTable.h
Normal file
12
底盘独立控制器/code/CarBody/RefereeSystem_CRCTable.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __REFEREESYSTEM_CRCTABLE_H
|
||||
#define __REFEREESYSTEM_CRCTABLE_H
|
||||
|
||||
//crc8 generator polynomial:G(x)=x8+x5+x4+1//CRC8-MAXIM
|
||||
extern uint8_t CRC8_Initial;//CRC8初始值
|
||||
extern const uint8_t CRC8_Table[256];
|
||||
|
||||
//crc16 generator polynomial:G(x)=x16+x12+x5+1//CRC16-CCITT
|
||||
extern uint16_t CRC16_Initial;//CRC16初始值
|
||||
extern const uint16_t CRC16_Table[256];
|
||||
|
||||
#endif
|
||||
68
底盘独立控制器/code/CarBody/UI.c
Normal file
68
底盘独立控制器/code/CarBody/UI.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "stm32f4xx.h" // Device header
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "UI_Library.h"
|
||||
#include "Remote.h"
|
||||
#include "CloseLoopControl.h"
|
||||
#include "Delay.h"
|
||||
#include "RefereeSystem.h"
|
||||
|
||||
/*
|
||||
*函数简介:UI初始化
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:无
|
||||
*/
|
||||
void UI_Init(void)
|
||||
{
|
||||
_ui_init_default_Ungroup_1();
|
||||
Delay_ms(100);
|
||||
_ui_init_default_Ungroup_0();
|
||||
Delay_ms(100);
|
||||
_ui_init_default_Ungroup_2();
|
||||
Delay_ms(100);
|
||||
_ui_init_default_Ungroup_1();
|
||||
Delay_ms(100);
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:UI更新
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:无
|
||||
*/
|
||||
void UI_Updata(void)
|
||||
{
|
||||
static uint8_t Count=0;
|
||||
Count=(Count+1)%2;//每次更新一个,循环更新提高效率
|
||||
|
||||
if(CloseLoopControl_ErrorFlag==1)//遥控器未连接,所有指示灯变绿
|
||||
{
|
||||
CloseLoopControl_ErrorFlag=0;
|
||||
_ui_update_default_Ungroup_2_NOCheck();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Count==0)//更新Shift
|
||||
{
|
||||
if(Remote_RxData.Remote_KeyPush_Shift==1)_ui_update_default_Ungroup_2_Shift_Open();
|
||||
else _ui_update_default_Ungroup_2_Shift_Close();
|
||||
}
|
||||
else//更新Ctrl
|
||||
{
|
||||
if(Remote_RxData.Remote_KeyPush_Ctrl==1)_ui_update_default_Ungroup_2_Ctrl_Open();
|
||||
else _ui_update_default_Ungroup_2_Ctrl_Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:UI显示遥控器未连接
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:所有指示灯变绿
|
||||
*/
|
||||
void UI_RemoteNoCheck(void)
|
||||
{
|
||||
if(CloseLoopControl_ErrorFlag==1)CloseLoopControl_ErrorFlag=0;
|
||||
_ui_update_default_Ungroup_2_NOCheck();
|
||||
}
|
||||
8
底盘独立控制器/code/CarBody/UI.h
Normal file
8
底盘独立控制器/code/CarBody/UI.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __UI_H
|
||||
#define __UI_H
|
||||
|
||||
void UI_Init(void);//UI初始化
|
||||
void UI_Updata(void);//UI更新
|
||||
void UI_RemoteNoCheck(void);//UI显示遥控器未连接
|
||||
|
||||
#endif
|
||||
41
底盘独立控制器/code/CarBody/UI_Base.c
Normal file
41
底盘独立控制器/code/CarBody/UI_Base.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "stm32f4xx.h" // Device header
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "UI_Base.h"
|
||||
#include <string.h>
|
||||
#include "RefereeSystem.h"
|
||||
#include "RefereeSystem_CRCTable.h"
|
||||
|
||||
uint8_t UI_seq=0;
|
||||
|
||||
#define DEFINE_FRAME_PROC(num,id) \
|
||||
void ui_proc_##num##_frame(ui_##num##_frame_t *msg) \
|
||||
{ \
|
||||
msg->header.SOF=0xA5; \
|
||||
msg->header.data_length=6+15*num; \
|
||||
msg->header.seq=UI_seq++; \
|
||||
msg->header.CRC8=RefereeSystem_GetCRC8CheckSum((uint8_t*)msg,4,CRC8_Initial); \
|
||||
msg->header.cmd_id=0x0301; \
|
||||
msg->header.dada_cmd_id=id; \
|
||||
msg->header.sender_id=RefereeSystem_RobotID; \
|
||||
msg->header.receiver_id=RefereeSystem_RobotID+256; \
|
||||
msg->CRC16=RefereeSystem_GetCRC16CheckSum((uint8_t*)msg,13+15*num,CRC16_Initial); \
|
||||
}
|
||||
|
||||
DEFINE_FRAME_PROC(1,0x0101)
|
||||
DEFINE_FRAME_PROC(2,0x0102)
|
||||
DEFINE_FRAME_PROC(5,0x0103)
|
||||
DEFINE_FRAME_PROC(7,0x0104)
|
||||
|
||||
void ui_proc_string_frame(ui_string_frame_t *msg)
|
||||
{
|
||||
msg->header.SOF=0xA5;
|
||||
msg->header.data_length=51;
|
||||
msg->header.seq=UI_seq++;
|
||||
msg->header.CRC8=RefereeSystem_GetCRC8CheckSum((uint8_t*)msg,4,CRC8_Initial);
|
||||
msg->header.cmd_id=0x0301;
|
||||
msg->header.dada_cmd_id=0x0110;
|
||||
msg->header.sender_id=RefereeSystem_RobotID;
|
||||
msg->header.receiver_id=RefereeSystem_RobotID+256;
|
||||
msg->option.str_length=strlen(msg->option.string);
|
||||
msg->CRC16=RefereeSystem_GetCRC16CheckSum((uint8_t *)msg,58,CRC16_Initial);
|
||||
}
|
||||
103
底盘独立控制器/code/CarBody/UI_Base.h
Normal file
103
底盘独立控制器/code/CarBody/UI_Base.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#ifndef __UI_BASE_H
|
||||
#define __UI_BASE_H
|
||||
|
||||
#define PRIMITIVE_CAT(x, y) x##y
|
||||
#define MESSAGE_PACKED __attribute__((packed))
|
||||
|
||||
#define DEFINE_MESSAGE(name,p_a,p_b,p_c,p_d,p_e) \
|
||||
typedef struct \
|
||||
{ \
|
||||
uint8_t figure_name[3]; \
|
||||
uint32_t operate_tpye:3; \
|
||||
uint32_t figure_tpye:3; \
|
||||
uint32_t layer:4; \
|
||||
uint32_t color:4; \
|
||||
uint32_t PRIMITIVE_CAT(details_,p_a):9; \
|
||||
uint32_t PRIMITIVE_CAT(details_,p_b):9; \
|
||||
uint32_t width:10; \
|
||||
uint32_t start_x:11; \
|
||||
uint32_t start_y:11; \
|
||||
uint32_t PRIMITIVE_CAT(details_,p_c):10; \
|
||||
uint32_t PRIMITIVE_CAT(details_,p_d):11; \
|
||||
uint32_t PRIMITIVE_CAT(details_,p_e):11; \
|
||||
}MESSAGE_PACKED ui_interface_##name##_t
|
||||
|
||||
DEFINE_MESSAGE(figure,_a,_b,_c,_d,_e);
|
||||
DEFINE_MESSAGE(line,_a,_b,_c,end_x,end_y);
|
||||
DEFINE_MESSAGE(rect,_a,_b,_c,end_x,end_y);
|
||||
DEFINE_MESSAGE(round,_a,_b,r,_d,_e);
|
||||
DEFINE_MESSAGE(ellipse,_a,_b,_c,rx,ry);
|
||||
DEFINE_MESSAGE(arc,start_angle,end_angle,_c,rx,ry);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t figure_name[3];
|
||||
uint32_t operate_tpye:3;
|
||||
uint32_t figure_tpye:3;
|
||||
uint32_t layer:4;
|
||||
uint32_t color:4;
|
||||
uint32_t font_size:9;
|
||||
uint32_t _b:9;
|
||||
uint32_t width:10;
|
||||
uint32_t start_x:11;
|
||||
uint32_t start_y:11;
|
||||
int32_t number;
|
||||
}MESSAGE_PACKED ui_interface_number_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t figure_name[3];
|
||||
uint32_t operate_tpye:3;
|
||||
uint32_t figure_tpye:3;
|
||||
uint32_t layer:4;
|
||||
uint32_t color:4;
|
||||
uint32_t font_size:9;
|
||||
uint32_t str_length:9;
|
||||
uint32_t width:10;
|
||||
uint32_t start_x:11;
|
||||
uint32_t start_y:11;
|
||||
uint32_t _c:10;
|
||||
uint32_t _d:11;
|
||||
uint32_t _e:11;
|
||||
char string[30];
|
||||
}MESSAGE_PACKED ui_interface_string_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t SOF;
|
||||
uint16_t data_length;
|
||||
uint8_t seq;
|
||||
uint8_t CRC8;
|
||||
uint16_t cmd_id;
|
||||
uint16_t dada_cmd_id;
|
||||
uint16_t sender_id;
|
||||
uint16_t receiver_id;
|
||||
}MESSAGE_PACKED ui_frame_header_t;
|
||||
|
||||
#define DEFINE_FIGURE_MESSAGE(num) \
|
||||
typedef struct \
|
||||
{ \
|
||||
ui_frame_header_t header; \
|
||||
ui_interface_figure_t data[num]; \
|
||||
uint16_t CRC16; \
|
||||
}MESSAGE_PACKED ui_##num##_frame_t
|
||||
|
||||
DEFINE_FIGURE_MESSAGE(1);
|
||||
DEFINE_FIGURE_MESSAGE(2);
|
||||
DEFINE_FIGURE_MESSAGE(5);
|
||||
DEFINE_FIGURE_MESSAGE(7);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ui_frame_header_t header;
|
||||
ui_interface_string_t option;
|
||||
uint16_t CRC16;
|
||||
}MESSAGE_PACKED ui_string_frame_t;
|
||||
|
||||
void ui_proc_1_frame(ui_1_frame_t *msg);
|
||||
void ui_proc_2_frame(ui_2_frame_t *msg);
|
||||
void ui_proc_5_frame(ui_5_frame_t *msg);
|
||||
void ui_proc_7_frame(ui_7_frame_t *msg);
|
||||
void ui_proc_string_frame(ui_string_frame_t *msg);
|
||||
|
||||
#endif
|
||||
222
底盘独立控制器/code/CarBody/UI_Library.c
Normal file
222
底盘独立控制器/code/CarBody/UI_Library.c
Normal file
@@ -0,0 +1,222 @@
|
||||
#include "stm32f4xx.h" // Device header
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "UI_Base.h"
|
||||
#include <string.h>
|
||||
#include "UART.h"
|
||||
|
||||
/*==========Shift文本==========*/
|
||||
ui_string_frame_t ui_default_Ungroup_0;
|
||||
ui_interface_string_t* ui_default_Ungroup_Text_Shift=&ui_default_Ungroup_0.option;
|
||||
|
||||
void _ui_init_default_Ungroup_0(void)
|
||||
{
|
||||
ui_default_Ungroup_0.option.figure_name[0]=0;
|
||||
ui_default_Ungroup_0.option.figure_name[1]=0;
|
||||
ui_default_Ungroup_0.option.figure_name[2]=0;
|
||||
ui_default_Ungroup_0.option.operate_tpye=1;
|
||||
ui_default_Ungroup_0.option.figure_tpye=7;
|
||||
ui_default_Ungroup_0.option.layer=0;
|
||||
ui_default_Ungroup_0.option.font_size=30;
|
||||
ui_default_Ungroup_0.option.start_x=75;
|
||||
ui_default_Ungroup_0.option.start_y=850;
|
||||
ui_default_Ungroup_0.option.color=2;
|
||||
ui_default_Ungroup_0.option.str_length=5;
|
||||
ui_default_Ungroup_0.option.width=6;
|
||||
strcpy(ui_default_Ungroup_Text_Shift->string, "Shift");
|
||||
|
||||
ui_proc_string_frame(&ui_default_Ungroup_0);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_0,sizeof(ui_default_Ungroup_0));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_0(void)
|
||||
{
|
||||
ui_default_Ungroup_0.option.operate_tpye=2;
|
||||
|
||||
ui_proc_string_frame(&ui_default_Ungroup_0);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_0,sizeof(ui_default_Ungroup_0));
|
||||
}
|
||||
|
||||
void _ui_remove_default_Ungroup_0(void)
|
||||
{
|
||||
ui_default_Ungroup_0.option.operate_tpye=3;
|
||||
|
||||
ui_proc_string_frame(&ui_default_Ungroup_0);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_0,sizeof(ui_default_Ungroup_0));
|
||||
}
|
||||
|
||||
/*==========Ctrl文本==========*/
|
||||
ui_string_frame_t ui_default_Ungroup_1;
|
||||
ui_interface_string_t* ui_default_Ungroup_Text_Ctrl=&ui_default_Ungroup_1.option;
|
||||
|
||||
void _ui_init_default_Ungroup_1(void)
|
||||
{
|
||||
ui_default_Ungroup_1.option.figure_name[0]=0;
|
||||
ui_default_Ungroup_1.option.figure_name[1]=0;
|
||||
ui_default_Ungroup_1.option.figure_name[2]=1;
|
||||
ui_default_Ungroup_1.option.operate_tpye=1;
|
||||
ui_default_Ungroup_1.option.figure_tpye=7;
|
||||
ui_default_Ungroup_1.option.layer=0;
|
||||
ui_default_Ungroup_1.option.font_size=30;
|
||||
ui_default_Ungroup_1.option.start_x=75;
|
||||
ui_default_Ungroup_1.option.start_y=750;
|
||||
ui_default_Ungroup_1.option.color=2;
|
||||
ui_default_Ungroup_1.option.str_length=4;
|
||||
ui_default_Ungroup_1.option.width=6;
|
||||
strcpy(ui_default_Ungroup_Text_Ctrl->string,"Ctrl");
|
||||
|
||||
ui_proc_string_frame(&ui_default_Ungroup_1);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_1,sizeof(ui_default_Ungroup_1));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_1(void)
|
||||
{
|
||||
ui_default_Ungroup_1.option.operate_tpye=2;
|
||||
|
||||
ui_proc_string_frame(&ui_default_Ungroup_1);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_1,sizeof(ui_default_Ungroup_1));
|
||||
}
|
||||
|
||||
void _ui_remove_default_Ungroup_1(void)
|
||||
{
|
||||
ui_default_Ungroup_1.option.operate_tpye=3;
|
||||
|
||||
ui_proc_string_frame(&ui_default_Ungroup_1);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_1,sizeof(ui_default_Ungroup_1));
|
||||
}
|
||||
|
||||
/*==========指示灯==========*/
|
||||
ui_2_frame_t ui_default_Ungroup_2;
|
||||
ui_interface_round_t *ui_default_Ungroup_Round_Shift=(ui_interface_round_t *)&(ui_default_Ungroup_2.data[0]);
|
||||
ui_interface_round_t *ui_default_Ungroup_Round_Ctrl=(ui_interface_round_t *)&(ui_default_Ungroup_2.data[1]);
|
||||
|
||||
void _ui_init_default_Ungroup_2(void)
|
||||
{
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
ui_default_Ungroup_2.data[i].figure_name[0]=0;
|
||||
ui_default_Ungroup_2.data[i].figure_name[1]=0;
|
||||
ui_default_Ungroup_2.data[i].figure_name[2]=i+2;
|
||||
ui_default_Ungroup_2.data[i].operate_tpye=1;
|
||||
}
|
||||
|
||||
ui_default_Ungroup_Round_Shift->figure_tpye=2;
|
||||
ui_default_Ungroup_Round_Shift->layer=0;
|
||||
ui_default_Ungroup_Round_Shift->details_r=20;
|
||||
ui_default_Ungroup_Round_Shift->start_x=250;
|
||||
ui_default_Ungroup_Round_Shift->start_y=835;
|
||||
ui_default_Ungroup_Round_Shift->color=2;
|
||||
ui_default_Ungroup_Round_Shift->width=2;
|
||||
|
||||
ui_default_Ungroup_Round_Ctrl->figure_tpye=2;
|
||||
ui_default_Ungroup_Round_Ctrl->layer=0;
|
||||
ui_default_Ungroup_Round_Ctrl->details_r=20;
|
||||
ui_default_Ungroup_Round_Ctrl->start_x=250;
|
||||
ui_default_Ungroup_Round_Ctrl->start_y=735;
|
||||
ui_default_Ungroup_Round_Ctrl->color=2;
|
||||
ui_default_Ungroup_Round_Ctrl->width=2;
|
||||
|
||||
ui_proc_2_frame(&ui_default_Ungroup_2);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_2,sizeof(ui_default_Ungroup_2));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_2_ERROR(void)
|
||||
{
|
||||
ui_default_Ungroup_2.data[0].operate_tpye=2;
|
||||
ui_default_Ungroup_2.data[1].operate_tpye=2;
|
||||
|
||||
ui_default_Ungroup_Round_Shift->details_r=10;
|
||||
ui_default_Ungroup_Round_Shift->start_x=240;
|
||||
ui_default_Ungroup_Round_Shift->start_y=825;
|
||||
ui_default_Ungroup_Round_Shift->color=0;
|
||||
ui_default_Ungroup_Round_Shift->width=20;
|
||||
|
||||
ui_default_Ungroup_Round_Ctrl->details_r=10;
|
||||
ui_default_Ungroup_Round_Ctrl->start_x=240;
|
||||
ui_default_Ungroup_Round_Ctrl->start_y=725;
|
||||
ui_default_Ungroup_Round_Ctrl->color=0;
|
||||
ui_default_Ungroup_Round_Ctrl->width=20;
|
||||
|
||||
ui_proc_2_frame(&ui_default_Ungroup_2);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_2,sizeof(ui_default_Ungroup_2));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_2_NOCheck(void)
|
||||
{
|
||||
ui_default_Ungroup_2.data[0].operate_tpye=2;
|
||||
ui_default_Ungroup_2.data[1].operate_tpye=2;
|
||||
|
||||
ui_default_Ungroup_Round_Shift->details_r=20;
|
||||
ui_default_Ungroup_Round_Shift->start_x=250;
|
||||
ui_default_Ungroup_Round_Shift->start_y=835;
|
||||
ui_default_Ungroup_Round_Shift->color=2;
|
||||
ui_default_Ungroup_Round_Shift->width=2;
|
||||
|
||||
ui_default_Ungroup_Round_Ctrl->details_r=20;
|
||||
ui_default_Ungroup_Round_Ctrl->start_x=250;
|
||||
ui_default_Ungroup_Round_Ctrl->start_y=735;
|
||||
ui_default_Ungroup_Round_Ctrl->color=2;
|
||||
ui_default_Ungroup_Round_Ctrl->width=2;
|
||||
|
||||
ui_proc_2_frame(&ui_default_Ungroup_2);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_2,sizeof(ui_default_Ungroup_2));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_2_Shift_Open(void)
|
||||
{
|
||||
ui_default_Ungroup_2.data[0].operate_tpye=2;
|
||||
ui_default_Ungroup_2.data[1].operate_tpye=0;
|
||||
|
||||
ui_default_Ungroup_Round_Shift->details_r=10;
|
||||
ui_default_Ungroup_Round_Shift->start_x=250;
|
||||
ui_default_Ungroup_Round_Shift->start_y=835;
|
||||
ui_default_Ungroup_Round_Shift->color=2;
|
||||
ui_default_Ungroup_Round_Shift->width=20;
|
||||
|
||||
ui_proc_2_frame(&ui_default_Ungroup_2);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_2,sizeof(ui_default_Ungroup_2));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_2_Shift_Close(void)
|
||||
{
|
||||
ui_default_Ungroup_2.data[0].operate_tpye=2;
|
||||
ui_default_Ungroup_2.data[1].operate_tpye=0;
|
||||
|
||||
ui_default_Ungroup_Round_Shift->details_r=20;
|
||||
ui_default_Ungroup_Round_Shift->start_x=250;
|
||||
ui_default_Ungroup_Round_Shift->start_y=835;
|
||||
ui_default_Ungroup_Round_Shift->color=2;
|
||||
ui_default_Ungroup_Round_Shift->width=2;
|
||||
|
||||
ui_proc_2_frame(&ui_default_Ungroup_2);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_2,sizeof(ui_default_Ungroup_2));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_2_Ctrl_Open(void)
|
||||
{
|
||||
ui_default_Ungroup_2.data[0].operate_tpye=0;
|
||||
ui_default_Ungroup_2.data[1].operate_tpye=2;
|
||||
|
||||
ui_default_Ungroup_Round_Ctrl->details_r=10;
|
||||
ui_default_Ungroup_Round_Ctrl->start_x=250;
|
||||
ui_default_Ungroup_Round_Ctrl->start_y=735;
|
||||
ui_default_Ungroup_Round_Ctrl->color=2;
|
||||
ui_default_Ungroup_Round_Ctrl->width=20;
|
||||
|
||||
ui_proc_2_frame(&ui_default_Ungroup_2);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_2,sizeof(ui_default_Ungroup_2));
|
||||
}
|
||||
|
||||
void _ui_update_default_Ungroup_2_Ctrl_Close(void)
|
||||
{
|
||||
ui_default_Ungroup_2.data[0].operate_tpye=0;
|
||||
ui_default_Ungroup_2.data[1].operate_tpye=2;
|
||||
|
||||
ui_default_Ungroup_Round_Ctrl->details_r=20;
|
||||
ui_default_Ungroup_Round_Ctrl->start_x=250;
|
||||
ui_default_Ungroup_Round_Ctrl->start_y=735;
|
||||
ui_default_Ungroup_Round_Ctrl->color=2;
|
||||
ui_default_Ungroup_Round_Ctrl->width=2;
|
||||
|
||||
ui_proc_2_frame(&ui_default_Ungroup_2);
|
||||
UART1_SendArray((uint8_t *)&ui_default_Ungroup_2,sizeof(ui_default_Ungroup_2));
|
||||
}
|
||||
23
底盘独立控制器/code/CarBody/UI_Library.h
Normal file
23
底盘独立控制器/code/CarBody/UI_Library.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef __UI_LIBRARY_H
|
||||
#define __UI_LIBRARY_H
|
||||
|
||||
/*==========Shift文本==========*/
|
||||
void _ui_init_default_Ungroup_0(void);
|
||||
void _ui_update_default_Ungroup_0(void);
|
||||
void _ui_remove_default_Ungroup_0(void);
|
||||
|
||||
/*==========Ctrl文本==========*/
|
||||
void _ui_init_default_Ungroup_1(void);
|
||||
void _ui_update_default_Ungroup_1(void);
|
||||
void _ui_remove_default_Ungroup_1(void);
|
||||
|
||||
/*==========指示灯==========*/
|
||||
void _ui_init_default_Ungroup_2(void);
|
||||
void _ui_update_default_Ungroup_2_ERROR(void);
|
||||
void _ui_update_default_Ungroup_2_NOCheck(void);
|
||||
void _ui_update_default_Ungroup_2_Shift_Open(void);
|
||||
void _ui_update_default_Ungroup_2_Shift_Close(void);
|
||||
void _ui_update_default_Ungroup_2_Ctrl_Open(void);
|
||||
void _ui_update_default_Ungroup_2_Ctrl_Close(void);
|
||||
|
||||
#endif
|
||||
122
底盘独立控制器/code/CarBody/Ultra_CAP.c
Normal file
122
底盘独立控制器/code/CarBody/Ultra_CAP.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "stm32f4xx.h" // Device header
|
||||
#include "stm32f4xx_conf.h"
|
||||
|
||||
/*
|
||||
*函数简介:超电使能
|
||||
*参数说明:0-停机,1-运行(负载关),2-运行(负载开)
|
||||
*返回类型:1-发送成功,0-发送失败
|
||||
*备注:标识符0x600,数据长度4字节
|
||||
*/
|
||||
uint8_t Ultra_CAP_Enable(uint8_t EnableFlag)
|
||||
{
|
||||
CanTxMsg TxMessage;
|
||||
TxMessage.StdId=0x600;//ID标准标识符0x600
|
||||
TxMessage.RTR=CAN_RTR_Data;//数据帧
|
||||
TxMessage.IDE=CAN_Id_Standard;//标准格式
|
||||
TxMessage.DLC=0x04;//4字节数据段
|
||||
TxMessage.Data[0]=0;
|
||||
TxMessage.Data[1]=EnableFlag;
|
||||
TxMessage.Data[2]=0;
|
||||
TxMessage.Data[3]=0;
|
||||
|
||||
uint8_t mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据并获取邮箱号
|
||||
uint16_t i=0;
|
||||
while((CAN_TransmitStatus(CAN1,mbox)==CAN_TxStatus_Failed)&&(i<0xFFF))i++;//等待发送结束
|
||||
if(i>=0xFFF)return 0;//发送失败
|
||||
return 1;//发送成功
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:超电设置电压上限
|
||||
*参数说明:电压
|
||||
*返回类型:1-发送成功,0-发送失败
|
||||
*备注:标识符0x602,数据长度4字节,默认存入EEPROM
|
||||
*备注:设定值=电压*100
|
||||
*/
|
||||
uint8_t Ultra_CAP_SetVoltage(float Voltage)
|
||||
{
|
||||
uint16_t SetVoltage=(uint16_t)((int16_t)(Voltage*100.0f));
|
||||
CanTxMsg TxMessage;
|
||||
TxMessage.StdId=0x602;//ID标准标识符0x602
|
||||
TxMessage.RTR=CAN_RTR_Data;//数据帧
|
||||
TxMessage.IDE=CAN_Id_Standard;//标准格式
|
||||
TxMessage.DLC=0x04;//4字节数据段
|
||||
TxMessage.Data[0]=(uint8_t)(SetVoltage>>8);
|
||||
TxMessage.Data[1]=(uint8_t)(SetVoltage & 0x00FF);
|
||||
TxMessage.Data[2]=0;
|
||||
TxMessage.Data[3]=0x01;
|
||||
|
||||
uint8_t mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据并获取邮箱号
|
||||
uint16_t i=0;
|
||||
while((CAN_TransmitStatus(CAN1,mbox)==CAN_TxStatus_Failed)&&(i<0xFFF))i++;//等待发送结束
|
||||
if(i>=0xFFF)return 0;//发送失败
|
||||
return 1;//发送成功
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:超电设置电流上限
|
||||
*参数说明:无
|
||||
*返回类型:1-发送成功,0-发送失败
|
||||
*备注:标识符0x603,数据长度4字节,默认存入EEPROM
|
||||
*备注:设定值=电流*100
|
||||
*/
|
||||
uint8_t Ultra_CAP_SetCurrent(float Current)
|
||||
{
|
||||
uint16_t SetCurrent=(uint16_t)((int16_t)(Current*100.0f));
|
||||
CanTxMsg TxMessage;
|
||||
TxMessage.StdId=0x603;//低位ID标准标识符0x603
|
||||
TxMessage.RTR=CAN_RTR_Data;//数据帧
|
||||
TxMessage.IDE=CAN_Id_Standard;//标准格式
|
||||
TxMessage.DLC=0x04;//4字节数据段
|
||||
TxMessage.Data[0]=(uint8_t)(SetCurrent>>8);
|
||||
TxMessage.Data[1]=(uint8_t)(SetCurrent & 0x00FF);
|
||||
TxMessage.Data[2]=0;
|
||||
TxMessage.Data[3]=0x01;
|
||||
|
||||
uint8_t mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据并获取邮箱号
|
||||
uint16_t i=0;
|
||||
while((CAN_TransmitStatus(CAN1,mbox)==CAN_TxStatus_Failed)&&(i<0xFFF))i++;//等待发送结束
|
||||
if(i>=0xFFF)return 0;//发送失败
|
||||
return 1;//发送成功
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:超电设置功率上限
|
||||
*参数说明:无
|
||||
*返回类型:1-发送成功,0-发送失败
|
||||
*备注:标识符0x601,数据长度4字节
|
||||
*备注:设定值=功率*100
|
||||
*/
|
||||
uint8_t Ultra_CAP_SetPower(float PowerLimit)
|
||||
{
|
||||
uint16_t SetPower=(uint16_t)((int16_t)(PowerLimit*100.0f));
|
||||
CanTxMsg TxMessage;
|
||||
TxMessage.StdId=0x601;//低位ID标准标识符0x601
|
||||
TxMessage.RTR=CAN_RTR_Data;//数据帧
|
||||
TxMessage.IDE=CAN_Id_Standard;//标准格式
|
||||
TxMessage.DLC=0x04;//4字节数据段
|
||||
TxMessage.Data[0]=(uint8_t)(SetPower>>8);
|
||||
TxMessage.Data[1]=(uint8_t)(SetPower & 0x00FF);
|
||||
TxMessage.Data[2]=0;
|
||||
TxMessage.Data[3]=0;
|
||||
|
||||
uint8_t mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据并获取邮箱号
|
||||
uint16_t i=0;
|
||||
while((CAN_TransmitStatus(CAN1,mbox)==CAN_TxStatus_Failed)&&(i<0xFFF))i++;//等待发送结束
|
||||
if(i>=0xFFF)return 0;//发送失败
|
||||
return 1;//发送成功
|
||||
}
|
||||
|
||||
/*
|
||||
*函数简介:超电初始化
|
||||
*参数说明:无
|
||||
*返回类型:无
|
||||
*备注:默认设定电压23V,电流8A,功率150W
|
||||
*/
|
||||
void Ultra_CAP_Init(void)
|
||||
{
|
||||
Ultra_CAP_SetVoltage(23.0f);
|
||||
Ultra_CAP_SetCurrent(8.0f);
|
||||
Ultra_CAP_Enable(2);
|
||||
Ultra_CAP_SetPower(150.0f);
|
||||
}
|
||||
7
底盘独立控制器/code/CarBody/Ultra_CAP.h
Normal file
7
底盘独立控制器/code/CarBody/Ultra_CAP.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __ULTRA_CAP_H
|
||||
#define __ULTRA_CAP_H
|
||||
|
||||
void Ultra_CAP_Init(void);//超电初始化
|
||||
uint8_t Ultra_CAP_SetPower(float PowerLimit);//超电设置功率上限
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user