同步最新代码

This commit is contained in:
2026-01-13 14:52:42 +08:00
commit b1418b080c
1011 changed files with 429902 additions and 0 deletions

View 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);
}

View 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

View 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;
}
}
}
}

View 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

View 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
};

View 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

View 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();
}

View 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

View 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);
}

View 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

View 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));
}

View 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

View 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);
}

View 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