17 Commits

Author SHA1 Message Date
a6d9bfc2b0 vision init 2026-03-19 01:34:58 +08:00
guoxy06
3ebb57d86b 修改RectifyRCjoystick()改了左摇杆限幅 2026-03-15 16:41:00 +08:00
Zorua
4ac9cba1d7 damiao motor driver init_1.1 2026-03-15 13:15:49 +08:00
Zorua
3afa755680 damiao motor driver init_1 2026-03-15 12:52:05 +08:00
Zorua
fbc83771a8 damiao motor driver init 2026-03-14 18:55:54 +08:00
fcl
52e8018b2c changed pid param for steer motor 2026-03-14 14:20:38 +08:00
guoxy06
fa85ac8e2a 4310能转,但不受遥控控制 2026-03-13 18:37:58 +08:00
fcl
4d20b137da reast 2026-03-11 20:37:35 +08:00
fcl
8a96476007 Revert "supercap can1"
This reverts commit 69e97cbefa.
2026-03-11 20:30:36 +08:00
fcl
91588795c2 待测版本(ID修改完成) 2026-03-11 19:45:12 +08:00
fcl
0e711f1fe8 待测版本(ID修改完成) 2026-03-11 19:44:53 +08:00
fcl
09802b3daa 待测版本(ID修改完成) 2026-03-10 19:10:47 +08:00
69e97cbefa supercap can1 2026-03-10 15:21:42 +08:00
5d32411da6 supercap can1 2026-03-10 03:09:35 +08:00
6d1de50957 supercap can1 2026-03-10 03:07:45 +08:00
93d26b601d Merge remote-tracking branch 'origin/dev' into dev 2026-03-10 03:06:07 +08:00
d6872ad1e8 supercap 2026-03-10 03:05:49 +08:00
14 changed files with 230 additions and 99 deletions

View File

@@ -113,14 +113,14 @@ void ChassisInit()
.can_init_config.can_handle = &hcan1,
.controller_param_init_config = {
.angle_PID = {
.Kp = 12,
.Ki = 0.2,
.Kp = 35,
.Ki = 0.25,
.Kd = 0,
.CoefA = 3,
.CoefB = 0.1,
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement | PID_DerivativeFilter | PID_ChangingIntegrationRate,
.IntegralLimit = 1000,
.MaxOut = 5000,
.IntegralLimit = 1500,
.MaxOut = 6000,
.Derivative_LPF_RC = 0.001,
.DeadBand = 0.5,
},
@@ -151,7 +151,7 @@ void ChassisInit()
motor_steering_lb = DJIMotorInit(&chassis_motor_steering_config);
PID_Init_Config_s chassis_follow_pid_conf = {
.Kp = 1.05, // 6
.Kp = 0.95, // 6
.Ki = 0,
.Kd = 0.1, // 0.495
.DeadBand = 0.5f,// 启用死区,值为0.5度
@@ -170,11 +170,14 @@ void ChassisInit()
SuperCap_Init_Config_s cap_conf = {
.can_config = {
.can_handle = &hcan2,
.tx_id = 0x302, // 超级电容默认接收id
.rx_id = 0x301, // 超级电容默认发送id,注意tx和rx在其他人看来是反的
.can_handle = &hcan1, // 保持你原有的硬件CAN接口不变
.tx_id = 0x001, // C板发给超级电容的ID
.rx_id = 0x100, // 超级电容发给C板的ID
}};
cap = SuperCapInit(&cap_conf); // 超级电容初始化
cap = SuperCapInit(&cap_conf); // 超级电容初始化 todo 控制
// (新增)设置超级电容功率补偿,例如补偿5W,可根据实际需求调整 todo 控制
SuperCapSetPowerOffset(cap, 5);
// 发布订阅初始化,如果为双板,则需要can comm来传递消息
#ifdef CHASSIS_BOARD

View File

@@ -203,14 +203,13 @@ static void RemoteControlSet()
// 左侧开关状态为[下],或视觉未识别到目标,纯遥控器拨杆控制
if (switch_is_down(rc_data[TEMP].rc.switch_left) )
{ // 按照摇杆的输出大小进行角度增量,增益系数需调整
gimbal_cmd_send.yaw += 0.005f * (float)rc_data[TEMP].rc.rocker_l_;
gimbal_cmd_send.pitch += 0.001f * (float)rc_data[TEMP].rc.rocker_l1;
gimbal_cmd_send.yaw += 0.005f * (float)rc_data[TEMP].rc.rocker_r_;
gimbal_cmd_send.pitch += 0.001f * (float)rc_data[TEMP].rc.rocker_r1;
}
// 云台软件限位
// 底盘参数,目前没有加入小陀螺(调试似乎暂时没有必要),系数需要调整
chassis_cmd_send.vx = 0.15f * (float)rc_data[TEMP].rc.rocker_r_; // _水平方向
chassis_cmd_send.vy = 0.15f * (float)rc_data[TEMP].rc.rocker_r1; // 1数值方向
chassis_cmd_send.vx = 0.15f * (float)rc_data[TEMP].rc.rocker_l_; // _水平方向
chassis_cmd_send.vy = 0.15f * (float)rc_data[TEMP].rc.rocker_l1; // 1数值方向
// // 发射参数
// if (switch_is_up(rc_data[TEMP].rc.switch_right)) // 右侧开关状态[上],弹舱打开

View File

@@ -26,12 +26,12 @@ void GimbalInit()
},
.controller_param_init_config = {
.angle_PID = {
//.Kp = 0.685, // 8
.Kp = 0.685, // 8
//.Kp = 0.785, // 8
.Kp = 3, // 8
//.Ki = 0.315,
.Ki = 0.25,
.Kd = 0.022,
//.DeadBand = 0.1,
.Ki = 0.45,
.Kd = 0.03,
//.DeadBand = 0.1
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement | PID_DerivativeFilter | PID_ChangingIntegrationRate,
.IntegralLimit = 1060,
.CoefA = 20,
@@ -40,9 +40,9 @@ void GimbalInit()
.Derivative_LPF_RC = 0.001
},
.speed_PID = {
.Kp = 8000, // 50
.Kp = 500, // 50
//.Kp = 5000, // 50
.Ki = 5000, // 200
.Ki = 2000, // 200
.Kd = 0,
.CoefB = 1,
.CoefA = 10,
@@ -66,7 +66,7 @@ void GimbalInit()
Motor_Init_Config_s pitch_config = {
.can_init_config = {
.can_handle = &hcan2,
.tx_id = 4,
.tx_id = 4,//2
},
.controller_param_init_config = {
.angle_PID = {
@@ -83,7 +83,7 @@ void GimbalInit()
.Kd = 0, // 0
.Improve = PID_Trapezoid_Intergral | PID_Integral_Limit | PID_Derivative_On_Measurement,
.IntegralLimit = 2500,
.MaxOut = 20000,
.MaxOut = 8000,//20000
},
.other_angle_feedback_ptr = &gimba_IMU_data->Pitch,
// 还需要增加角速度额外反馈指针,注意方向,ins_task.md中有c板的bodyframe坐标系说明
@@ -96,7 +96,7 @@ void GimbalInit()
.close_loop_type = SPEED_LOOP | ANGLE_LOOP,
.motor_reverse_flag = MOTOR_DIRECTION_NORMAL,
},
.motor_type = M3508,
.motor_type = DM4310,
};
// 电机对total_angle闭环,上电时为零,会保持静止,收到遥控器数据再动
yaw_motor = DJIMotorInit(&yaw_config);
@@ -132,6 +132,17 @@ void GimbalTask()
DJIMotorChangeFeed(pitch_motor, SPEED_LOOP, OTHER_FEED);
DJIMotorSetRef(yaw_motor, gimbal_cmd_recv.yaw); // yaw和pitch会在robot_cmd中处理好多圈和单圈
DJIMotorSetRef(pitch_motor, gimbal_cmd_recv.pitch);
// // 根据底盘速度进行补偿,保持云台稳定
// // 这里简化处理,实际应用中可能需要更复杂的补偿算法
// float yaw_ref = gimbal_cmd_recv.yaw;
// float pitch_ref = gimbal_cmd_recv.pitch;
//
// // 当底盘移动时,云台需要保持相对稳定
// // 这里可以根据底盘速度调整云台的控制参考值
// // 例如,当底盘向前移动时,云台可能需要稍微向后调整以保持稳定
//
// DJIMotorSetRef(yaw_motor, yaw_ref); // yaw和pitch会在robot_cmd中处理好多圈和单圈
// DJIMotorSetRef(pitch_motor, pitch_ref);
break;
// 云台自由模式,使用编码器反馈,底盘和云台分离,仅云台旋转,一般用于调整云台姿态(英雄吊射等)/能量机关
case GIMBAL_FREE_MODE: // 后续删除,或加入云台追地盘的跟随模式(响应速度更快)
@@ -160,3 +171,12 @@ void GimbalTask()
// 推送消息
PubPushMessage(gimbal_pub, (void *)&gimbal_feedback_data);
}
// /**
// * @brief 获取云台IMU数据指针
// *
// * @return attitude_t* 云台IMU数据指针
// */
// attitude_t *GetGimbalIMUData()
// {
// return gimba_IMU_data;
// }

View File

@@ -1,6 +1,6 @@
#ifndef GIMBAL_H
#define GIMBAL_H
#include "../modules/imu/ins_task.h"
/**
* @brief 初始化云台,会被RobotInit()调用
*
@@ -9,8 +9,8 @@ void GimbalInit();
/**
* @brief 云台任务
*
* @return attitude_t* 云台IMU数据指针
*/
void GimbalTask();
//attitude_t *GetGimbalIMUData();
#endif // GIMBAL_H

View File

@@ -26,7 +26,7 @@
/* 机器人重要参数定义,注意根据不同机器人进行修改,浮点数需要以.0或f结尾,无符号以u结尾 */
// 云台参数
#define YAW_CHASSIS_ALIGN_ECD 3938 // 云台和底盘对齐指向相同方向时的电机编码器值,若对云台有机械改动需要修改
#define YAW_CHASSIS_ALIGN_ECD 1190 // 云台和底盘对齐指向相同方向时的电机编码器值,若对云台有机械改动需要修改
#define YAW_ECD_GREATER_THAN_4096 0 // ALIGN_ECD值是否大于4096,是为1,否为0;用于计算云台偏转角度
#define PITCH_HORIZON_ECD 3412 // 云台处于水平位置时编码器值,若对云台有机械改动需要修改
#define PITCH_MAX_ANGLE 0 // 云台竖直方向最大角度 (注意反馈如果是陀螺仪,则填写陀螺仪的角度)

View File

@@ -96,7 +96,7 @@ void ShootInit()
.close_loop_type = CURRENT_LOOP | SPEED_LOOP,
.motor_reverse_flag = MOTOR_DIRECTION_NORMAL, // 注意方向设置为拨盘的拨出的击发方向
},
.motor_type = M3508 // 英雄使用m3508
.motor_type = M2006 // 英雄使用m3508
};
loader = DJIMotorInit(&loader_config);

View File

@@ -5,7 +5,7 @@
* @version beta
* @date 2022-11-03
* @todo 增加对串口调试助手协议的支持,包括vofa和serial debug
* @copyright Copyright (c) 2022
* @copyright Copyright (c) 2023
*
*/
#include "master_process.h"

View File

@@ -24,7 +24,7 @@ static CANInstance sender_assignment[6] = {
[1] = {.can_handle = &hcan1, .txconf.StdId = 0x200, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[2] = {.can_handle = &hcan1, .txconf.StdId = 0x2ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[3] = {.can_handle = &hcan2, .txconf.StdId = 0x1ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[4] = {.can_handle = &hcan2, .txconf.StdId = 0x200, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[4] = {.can_handle = &hcan2, .txconf.StdId = 0x3FE, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
[5] = {.can_handle = &hcan2, .txconf.StdId = 0x2ff, .txconf.IDE = CAN_ID_STD, .txconf.RTR = CAN_RTR_DATA, .txconf.DLC = 0x08, .tx_buff = {0}},
};
@@ -106,7 +106,36 @@ static void MotorSenderGrouping(DJIMotorInstance *motor, CAN_Init_Config_s *conf
}
}
break;
case DM4310:
if (motor_id < 4) // 根据ID分组
{
motor_send_num = motor_id;
motor_grouping = config->can_handle == &hcan2 ? 1 : 4;
}
else
{
motor_send_num = motor_id - 4;
motor_grouping = config->can_handle == &hcan2 ? 0 : 3;
}
// 计算接收id并设置分组发送id
config->rx_id = 0x300 + motor_id + 1; // 把ID+1,进行分组设置
sender_enable_flag[motor_grouping] = 1; // 设置发送标志位,防止发送空帧
motor->message_num = motor_send_num;
motor->sender_group = motor_grouping;
// 检查是否发生id冲突
for (size_t i = 0; i < idx; ++i)
{
if (dji_motor_instance[i]->motor_can_instance->can_handle == config->can_handle && dji_motor_instance[i]->motor_can_instance->rx_id == config->rx_id)
{
LOGERROR("[dji_motor] ID crash. Check in debug mode, add dji_motor_instance to watch to get more information.");
uint16_t can_bus = config->can_handle == &hcan2 ? 1 : 2;
while (1) // 6020的id 1-4和2006/3508的id 5-8会发生冲突(若有注册,即1!5,2!6,3!7,4!8) (1!5!,LTC! (((不是)
LOGERROR("[dji_motor] id [%d], can_bus [%d]", config->rx_id, can_bus);
}
}
break;
default: // other motors should not be registered here
while (1)
LOGERROR("[dji_motor]You must not register other motors using the API of DJI motor."); // 其他电机不应该在这里注册
@@ -296,8 +325,17 @@ void DJIMotorControl()
// 分组填入发送数据
group = motor->sender_group;
num = motor->message_num;
if (i == 1)
{
sender_assignment[4].tx_buff[6] = (uint8_t)(set & 0x00ff); // 高八位
sender_assignment[4].tx_buff[7] = (uint8_t)(set >> 8); // 低八位
}
else
{
sender_assignment[group].tx_buff[2 * num] = (uint8_t)(set >> 8); // 低八位
sender_assignment[group].tx_buff[2 * num + 1] = (uint8_t)(set & 0x00ff); // 高八位
}
// 若该电机处于停止状态,直接将buff置零
if (motor->stop_flag == MOTOR_STOP)

View File

@@ -105,7 +105,6 @@ void DJIMotorChangeFeed(DJIMotorInstance *motor, Closeloop_Type_e loop, Feedback
* @brief 该函数被motor_task调用运行在rtos上,motor_stask内通过osDelay()确定控制频率
*/
void DJIMotorControl();
/**
* @brief 停止电机,注意不是将设定值设为零,而是直接给电机发送的电流值置零
*

View File

@@ -20,13 +20,32 @@ static DaemonInstance *rc_daemon_instance;
* @brief 矫正遥控器摇杆的值,超过660或者小于-660的值都认为是无效值,置0
*
*/
static void RectifyRCjoystick()
// static void RectifyRCjoystick()
// {
// for (uint8_t i = 0; i < 5; ++i)
// if (abs(*(&rc_ctrl[TEMP].rc.rocker_l_ + i)) > 660)
// *(&rc_ctrl[TEMP].rc.rocker_l_ + i) = 0;
// }
static void RectifyRCjoystick()//左遥杆水平向右限幅不够,因为下面的+3,将+3删除就用上面的
{
int16_t *rocker_ptr = &rc_ctrl[TEMP].rc.rocker_l_;
for (uint8_t i = 0; i < 5; ++i)
if (abs(*(&rc_ctrl[TEMP].rc.rocker_l_ + i)) > 660)
*(&rc_ctrl[TEMP].rc.rocker_l_ + i) = 0;
{
if (i == 0) // 左遥杆水平方向
{
// 增加右向最大值到700,左向保持660不变
if (rocker_ptr[i] > 700)
rocker_ptr[i] = 700;
else if (rocker_ptr[i] < -660)
rocker_ptr[i] = -660;
}
else // 其他通道保持原限制
{
if (abs(rocker_ptr[i]) > 660)
rocker_ptr[i] = 0;
}
}
}
/**
* @brief 遥控器数据解析
*
@@ -40,7 +59,7 @@ static void sbus_to_rc(const uint8_t *sbus_buf)
rc_ctrl[TEMP].rc.rocker_l_ = (((sbus_buf[2] >> 6) | (sbus_buf[3] << 2) | (sbus_buf[4] << 10)) & 0x07ff) - RC_CH_VALUE_OFFSET; //!< Channel 2
rc_ctrl[TEMP].rc.rocker_l1 = (((sbus_buf[4] >> 1) | (sbus_buf[5] << 7)) & 0x07ff) - RC_CH_VALUE_OFFSET; //!< Channel 3
rc_ctrl[TEMP].rc.dial = ((sbus_buf[16] | (sbus_buf[17] << 8)) & 0x07FF) - RC_CH_VALUE_OFFSET;
rc_ctrl[TEMP].rc.rocker_l_= rc_ctrl[TEMP].rc.rocker_l_;
rc_ctrl[TEMP].rc.rocker_l_= rc_ctrl[TEMP].rc.rocker_l_+3;
// 左侧拨轮
RectifyRCjoystick();
// 开关,0左1右

View File

@@ -1,15 +1,12 @@
/*
* @Descripttion:
* @version:
* @Author: Chenfu
* @Date: 2022-12-02 21:32:47
* @LastEditTime: 2022-12-05 15:29:49
* @Descripttion: 适配群星战队协议的超级电容模块
* @version: V2.0
*/
#include "super_cap.h"
#include "memory.h"
#include "stdlib.h"
static SuperCapInstance *super_cap_instance = NULL; // 可以由app保存此指针
static SuperCapInstance *super_cap_instance = NULL;
static void SuperCapRxCallback(CANInstance *_instance)
{
@@ -17,9 +14,14 @@ static void SuperCapRxCallback(CANInstance *_instance)
SuperCap_Msg_s *Msg;
rxbuff = _instance->rx_buff;
Msg = &super_cap_instance->cap_msg;
Msg->vol = (uint16_t)(rxbuff[0] << 8 | rxbuff[1]);
Msg->current = (uint16_t)(rxbuff[2] << 8 | rxbuff[3]);
Msg->power = (uint16_t)(rxbuff[4] << 8 | rxbuff[5]);
// 按照新协议解析接收数据
Msg->ready = (SuperCapReadyEnum)rxbuff[0];
Msg->state = (SuperCapStateEnum)rxbuff[1];
Msg->energy = rxbuff[2];
Msg->chassis_power = (uint16_t)(rxbuff[3] << 1); // 左移一位还原量程
Msg->bat_voltage = rxbuff[4];
Msg->bat_power = rxbuff[5];
}
SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config)
@@ -32,12 +34,26 @@ SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config)
return super_cap_instance;
}
void SuperCapSend(SuperCapInstance *instance, uint8_t *data)
void SuperCapSend(SuperCapInstance *instance, SuperCap_TxMsg_s *tx_data)
{
memcpy(instance->can_ins->tx_buff, data, 8);
uint8_t *txbuff = instance->can_ins->tx_buff;
// 按照新协议装载发送数据
txbuff[0] = tx_data->Enable;
txbuff[1] = tx_data->Charge;
txbuff[2] = tx_data->Powerlimit - instance->power_offset; // 计算功率补偿
txbuff[3] = tx_data->ChargePower;
CANTransmit(instance->can_ins, 1);
}
void SuperCapSetPowerOffset(SuperCapInstance *instance, uint8_t offset)
{
if (instance != NULL) {
instance->power_offset = offset;
}
}
SuperCap_Msg_s SuperCapGet(SuperCapInstance *instance)
{
return instance->cap_msg;

View File

@@ -1,29 +1,61 @@
/*
* @Descripttion:
* @version:
* @Author: Chenfu
* @Date: 2022-12-02 21:32:47
* @LastEditTime: 2022-12-05 15:25:46
* @Descripttion: 适配群星战队协议的超级电容模块
* @version: V2.0
*/
#ifndef SUPER_CAP_H
#define SUPER_CAP_H
#include "bsp_can.h"
// 超级电容状态枚举(从群星战队协议移植)
typedef enum
{
DISCHARGE = 0, // 放电状态
CHARGE = 1, // 充电状态
WAIT = 2, // 待机状态
SOFTSTART_PROTECTION = 3, // 处于软起动状态
OVER_LOAD_PROTECTION = 4, // 超电过载保护状态
BAT_OVER_VOLTAGE_PROTECTION = 5, // 过压保护状态
BAT_UNDER_VOLTAGE_PROTECTION = 6, // 电池欠压保护
CAP_UNDER_VOLTAGE_PROTECTION = 7, // 超级电容欠压保护
OVER_TEMPERATURE_PROTECTION = 8, // 过温保护
BOOM = 9, // 超电爆炸了
} SuperCapStateEnum;
// 超级电容准备状态
typedef enum
{
UNREADY = 0,
READY = 1,
} SuperCapReadyEnum;
#pragma pack(1)
/* 接收到的超级电容信息结构体 */
typedef struct
{
uint16_t vol; // 电压
uint16_t current; // 电流
uint16_t power; // 功率
SuperCapReadyEnum ready; // 可用标志:1为可用,0为不可用
SuperCapStateEnum state; // 状态标志
uint8_t energy; // 超级电容可用能量:0-100%
uint16_t chassis_power; // 底盘功率
uint8_t bat_voltage; // 电池电压*10
uint8_t bat_power; // 电池功率
} SuperCap_Msg_s;
/* 需要发送给超级电容的控制信息结构体 */
typedef struct {
uint8_t Enable; // 超级电容使能。1使能,0失能
uint8_t Charge; // 超级电容充电。1充电,0放电
uint8_t Powerlimit; // 裁判系统功率限制
uint8_t ChargePower; // 超级电容充电功率
} SuperCap_TxMsg_s;
#pragma pack()
/* 超级电容实例 */
typedef struct
{
CANInstance *can_ins; // CAN实例
SuperCap_Msg_s cap_msg; // 超级电容信息
SuperCap_Msg_s cap_msg; // 超级电容接收信息
uint8_t power_offset; // 功率补偿值
} SuperCapInstance;
/* 超级电容初始化配置 */
@@ -34,18 +66,22 @@ typedef struct
/**
* @brief 初始化超级电容
*
* @param supercap_config 超级电容初始化配置
* @return SuperCapInstance* 超级电容实例指针
*/
SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s *supercap_config);
/**
* @brief 发送超级电容控制信息
*
* @param instance 超级电容实例
* @param data 超级电容控制信息
*/
void SuperCapSend(SuperCapInstance *instance, uint8_t *data);
void SuperCapSend(SuperCapInstance *instance, SuperCap_TxMsg_s *tx_data);
#endif // !SUPER_CAP_Hd
/**
* @brief 设置超级电容功率补偿
*/
void SuperCapSetPowerOffset(SuperCapInstance *instance, uint8_t offset);
/**
* @brief 获取超级电容数据
*/
SuperCap_Msg_s SuperCapGet(SuperCapInstance *instance);
#endif // !SUPER_CAP_H

View File

@@ -1,21 +1,16 @@
<!--
* @Descripttion:
* @version:
* @Author: Chenfu
* @Date: 2022-12-02 21:32:47
* @LastEditTime: 2022-12-05 15:27:57
-->
# super_can
# super_cap (适配版)
## 代码结构
.h中放置的是数据定义和外部接口,以及协议的定义和宏,.c中包含一些私有函数。
.h中放置的是数据和协议枚举定义、控制接口,.c中包含CAN接收中断的回调解析以及发送打包逻辑。当前版本已完全适配群星战队的超级电容协议。
## 外部接口
```c
SuperCapInstance *SuperCapInit(SuperCap_Init_Config_s* supercap_config);
void SuperCapSend(SuperCapInstance *instance, uint8_t *data);
void SuperCapSend(SuperCapInstance *instance, SuperCap_TxMsg_s *tx_data);
void SuperCapSetPowerOffset(SuperCapInstance *instance, uint8_t offset);
SuperCap_Msg_s SuperCapGet(SuperCapInstance *instance);
```
## 私有函数和变量
@@ -25,7 +20,7 @@ static uint8_t *rxbuff;
static void SuperCapRxCallback(can_instance *_instance)
```
`SuperCapRxCallback()`是super cap初始化can实例时的回调函数,用于can接收中断,进行协议解析。
SuperCapRxCallback()是super cap初始化can实例时的回调函数,用于CAN接收中断,进行协议解析(包含底盘功率右移量程的还原等处理)。
## 使用范例
@@ -35,20 +30,26 @@ static void SuperCapRxCallback(can_instance *_instance)
SuperCap_Init_Config_s capconfig = {
.can_config = {
.can_handle = &hcan1,
.rx_id = 0x301,
.tx_id = 0x302
},
.recv_data_len = 4*sizeof(uint16_t),
.send_data_len = sizeof(uint8_t)
.rx_id = 0x100, // 超级电容发给C板的ID
.tx_id = 0x001 // C板发给超级电容的ID
}
};
SuperCapInstance *ins = SuperCapInit(&capconfig);
// 如果需要设置功率补偿
SuperCapSetPowerOffset(ins, 5);
```
发送通过`SuperCapSend()`,建议使用强制类型转换:
发送控制指令时,使用 SuperCap_TxMsg_s 结构体:
```c
uint16_t tx = 0x321;
SuperCapSend(ins, (uint8_t*)&tx);
SuperCap_TxMsg_s tx_cmd = {
.Enable = 1,
.Charge = 1,
.Powerlimit = 60,
.ChargePower = 40
};
SuperCapSend(ins, &tx_cmd);
```