Files
Hero-C-Board-Legacy/云台/云台-old/CarBody/RefereeSystem.c

180 lines
5.9 KiB
C

#include "stm32f4xx.h" // Device header
#include "stm32f4xx_conf.h"
#include "RefereeSystem_CRCTable.h"
#include "Keyboard.h"
#include "Warming.h"
#include "Remote.h"
/****************************************************************************************************
此处裁判系统只接收0x0201命令,获取机器人性能体系数据,主要获取发射机构是否上电
帧格式:
0xA5 0x0D 0x00 包序号 帧头CRC8校验 0x01 0x02 13ByteData 整包CRC16校验
|___________________________________| |_______| |
帧头 命令码 数据
****************************************************************************************************/
/*接收数据缓冲区数组元素数=命令码对应数据段长度+9*/
uint8_t RefereeSystem_RxHEXPacket[21]={0xA5,0x0C,0x00,0x00,0x00,0x04,0x03,0};//裁判系统0x0304命令码接收数据缓冲区
uint8_t RefereeSystem_ShooterStatus;//发射机构状态,0-发射机构未上电,1-发射机构上电
uint8_t RefereeSystem_ShooterOpenFlag;//发射机构上电标志位,1-发射机构正在上电,0-其他
uint16_t RefereeSystem_ShooterOpenCounter;//发射机构上电读秒等待设备启动
uint8_t RefereeSystem_Status=0;//图传链路连接状态,0-图传链路未连接,1-图传链路连接
/*
*函数简介:裁判系统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)
{
Keyboard_Init();
}
/*
*函数简介:UART1串口中断接收裁判系统数据
*参数说明:无
*返回类型:无
*备注:数据帧格式在最上方注释
*/
void USART6_IRQHandler(void)
{
/*有效数据位数=命令码对应数据段长度+2*/
#define DataLength 14//裁判系统0x0304命令码有效数据位数
static int RxHEXState=0;//定义静态变量用于接收模式的选择
static int pRxHEXState=0;//定义静态变量用于充当计数器
uint8_t RefereeSystem_RxData;//裁判系统接收数据
TIM_SetCounter(TIM7,0);
TIM_Cmd(TIM7,DISABLE);//关闭定时器并重置计数值
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==0x0C)RxHEXState=2;else RxHEXState=0;}
/*=====0x0304命令码=====*/
/*=====检查帧头其他部分=====*/
else if(RxHEXState==2){if(RefereeSystem_RxData==0x00)RxHEXState=3;else RxHEXState=0;}
else if(RxHEXState==3){RefereeSystem_RxHEXPacket[3]=RefereeSystem_RxData;RxHEXState=4;}
else if(RxHEXState==4)
{
RefereeSystem_RxHEXPacket[4]=RefereeSystem_RxData;
if(RefereeSystem_VerifyCRC8CheckSum(RefereeSystem_RxHEXPacket,5)==1)RxHEXState=5;
else RxHEXState=0;
}
/*=====检查命令码=====*/
else if(RxHEXState==5){if(RefereeSystem_RxData==0x04)RxHEXState=6;else RxHEXState=0;}//接收命令码
else if(RxHEXState==6){if(RefereeSystem_RxData==0x03){RxHEXState=7;pRxHEXState=0;}else RxHEXState=0;}
/*=====接收有效数据=====*/
else if(RxHEXState==7)
{
RefereeSystem_RxHEXPacket[pRxHEXState+7]=RefereeSystem_RxData;//接收数据
pRxHEXState++;
if(pRxHEXState>=DataLength)
{
if(RefereeSystem_VerifyCRC16CheckSum(RefereeSystem_RxHEXPacket,21)==1)//CRC校验
{
Keyboard_DataProcess(&(RefereeSystem_RxHEXPacket[7]));//获取键盘数据
RefereeSystem_Status=1;
}
RxHEXState=0;
}
}
if(Remote_StartFlag==1)//第一次接收数据
{
Remote_StartFlag=2;
Warming_LEDClean();
}
Remote_Status=1;//遥控器已连接
}
TIM_Cmd(TIM7,ENABLE);//开启定时
}