我正在使用 XMC4500 relax kit 对 MIT Cheetah 马达 AK80-9 进行编程和运行。 代码是正确的,当电机显示绿灯时,但当我尝试调试和运行时,电机却没有正确响应。 尝试 20 次后,电机可能会响应一两次并显示绿灯。 我检查了 c/c++ 设置、电机 CAN id。
是我漏掉了什么,还是哪里出了问题?
我使用的是 DAVE 4.4.2
密码
/*
* main.c
*
* 创建于: 2024 年 2 月 26 日 16:44:40
* 作者:拉贾尔-纳格韦卡尔拉杰尔-纳格韦卡尔
*/
#include " dave.h "//来自 DAVE 代码生成的声明(包括 SFR 声明)
#include
#include
char str[200];
bool sys_on = 0;
int start = 0;
#define P_MIN -12.5f
#define P_MAX 12.5f
#define V_MIN -50.0f
#define V_MAX 50.0f
#define KP_MIN 0.0f
#define KP_MAX 500.0f
#define KD_MIN 0.0f
#define KD_MAX 5.0f
#define T_MIN -18.0f
#define T_MAX 18.0f
//初始化电机输入值
浮点数 p_int = 0.0;
浮点 v_int = 0.0;
float kp_int = 0.0;
float kd_int = 0.0;
float t_int = 0.0;
//t_int(+ve)--向下,t_int(-ve)--向上
// 读取电机输出的初始化变量
float p_out = 0.0f;
float v_out = 0.0f;
float t_out = 0.0f;
int id;
float p1,v1,t1,p2,v2,t2,p1o,v1o,t1o,p2o,v2o,t2o,po,vo,to;
uint8_t motor_on[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC };
uint8_t zeroo_posi
tion[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE };
uint8_t motor_off[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD };
uint8_t *update_data;
CAN_NODE_STATUS_t mo_tranmit_status;
unsigned int float_to_uint(float x, float x_min, float x_max, int bits) {
float span = x_max - x_min;
float offset = x_min;
返回 (unsigned int) ((x - offset) * ((float) ((1<< bits) - 1)) / span);
}
float uint_to_float(unsigned int x_int,float x_min,float x_max,int bits) {
/// 根据给定的范围和位数,将无符号 int 转换为 float ///
float span = x_max - x_min;
float offset = x_min;
return ((float) x_int) * span / ((float) ((1<< bits) - 1)) + offset;
}
void motorInitialize(int x) {
update_data = motor_on;
CAN_NODE_MO_UpdateData(( Request_Node)->lmobj_ptr[x],update_data);
mo_tranmit_status = CAN_NODE_MO_Transmit(( Request_Node)->lmobj_ptr[x]);
}
void setZero(int x) {
update_data = zero_position;
CAN_NODE_MO_UpdateData(( Request_Node)->lmobj_ptr[x],update_data);
mo_tranmit_status = CAN_NODE_MO_Transmit(( Request_Node)->lmobj_ptr[x]);
}
//向电机发送信息
void motorStop(int x) {
update_data = motor_off;
CAN_NODE_MO_UpdateData(( Request_Node)->lmobj_ptr[x],update_data);
CAN_NODE_MO_Transmit(( Request_Node)->lmobj_ptr[x]);
}
void transmitMessage(int x, float *p, float *v, float *t) {
*p = p_int;
*v = v_int;
*t = t_int;
//检查输入值是否在限制范围内
float p_des = fminf(fmaxf(P_MIN, p_int), P_MAX);
float v_des = fminf(fmaxf(V_MIN, v_int), V_MAX);
float kp = fminf(fmaxf(KP_MIN, kp_int), KP_MAX);
float kd = fminf(fmaxf(KD_MIN, kd_int), KD_MAX);
float t_ff = fminf(fmaxf(T_MIN, t_int), T_MAX);
//将浮点数转换为无符号整数
unsigned int p_uint = float_too_uint(p_des, P_MIN, P_MAX, 16);
unsigned int v_uint = float_too_uint(v_des, V_MIN, V_MAX, 12);
unsigned int kp_uint = float_too_uint(kp, KP_MIN, KP_MAX, 12);
unsigned int kd_uint = float_too_uint(kd, KD_MIN, KD_MAX, 12);
unsigned int t_uint = float_too_uint(t_ff, T_MIN, T_MAX, 12);
// 为 can 数据分配 uint 值,以便传输
XMC_CAN_MO_t *transmit_objecct = ( Request_Node)->lmobj_ptr[x]->mo_ptr;
transmit_objecct->can_data_byte[0] = p_uint>> 8;
transmit_objecct->can_data_byte[1] = p_uint 0xFF;
transmit_objecct->can_data_byte[2] = v_uint>> 4;
transmit_objecct->can_data_byte[3] = ((v_uint 0xF)<< 4 | (kp_uint>> 8));
transmit_objecct->can_data_byte[4] = kp_uint 0xFF;
transmit_objecct->can_data_byte[5] = kd_uint>> 4;
transmit_objecct->can_data_byte[6] = ((kd_uint 0xF)<< 4 | (t_uint>> 8));
transmit_objecct->can_data_byte[7] = t_uint 0xFF;
CAN_NODE_MO_Init(( Request_Node)->lmobj_ptr[x]);
//{0x7F, 0XFF, 0x7F, 0XF0, 0x00, 0x00, 0x07, 0xFF}
CAN_NODE_MO_Transmit(( Request_Node)->lmobj_ptr[x]);
p_uint = (transmit_objecct->can_data_byte[0]<<
| transmit_objecct->can_data_byte[1];
v_uint = (transmit_objecct->can_data_byte[2]<< 4)
| (transmit_objecct->can_data_byte[3]>> 4);
kp_uint = ((transmit_objecct->can_data_byte[3] 0xF)<<
| transmit_objecct->can_data_byte[4];
kd_uint = (transmit_objecct->can_data_byte[5]<< 4)
| (transmit_objecct->can_data_byte[6]>> 4);
t_uint = ((transmit_objecct->can_data_byte[6] 0xF)<<
| transmit_objecct->can_data_byte[7];
p_des = uint_too_float(p_uint, P_MIN, P_MAX, 16);
v_des = uint_too_float(v_uint, V_MIN, V_MAX, 12);
kp = uint_too_float(kp_uint, KP_MIN, KP_MAX, 12);
kd = uint_too_float(kd_uint, KD_MIN, KD_MAX, 12);
t_ff = uint_too_float(t_uint, T_MIN, T_MAX, 12);
}
void receiveMessage(int x, int *id, float *p, float *v, float *t) {
XMC_CAN_MO_t *receive_objecct = ( Request_Node)->lmobj_ptr[x]->mo_ptr;
CAN_NODE_MO_Receive(( Request_Node)->lmobj_ptr[x]);
// CAN_NODE_MO_ReceiveData(( Request_Node)->lmobj_ptr[1]);
*id = receive_objecct->can_data_byte[0];
unsigned int p_out = (receive_objecct->can_data_byte[1]<<
| receive_objecct->can_data_byte[2];
unsigned int v_out = (receive_objecct->can_data_byte[3]<< 4)
| (receive_objecct->can_data_byte[4]>> 4);
unsigned int i_out = ((receive_objecct->can_data_byte[4] 0xF)<<
| receive_objecct->can_data_byte[5];
*p = uint_too_float(p_out, P_MIN, P_MAX, 16);
*v = uint_too_float(v_out, V_MIN, V_MAX, 12);
*t = uint_to_float(i_out,T_MIN,T_MAX,12);
/* sprintf(str,"%d,%.2f,%.2f,%.2frn",id,);
SEGGER_RTT_WriteString(0, str);*/
}
/**
* @brief main ()-应用程序入口点
*
*
函数的详细信息
* 此例程是应用程序的入口点。 它由设备启动代码调用。 它负责
* 调用 APP 初始化调度器例程-dave_init () 并托管用户应用程序的占位符
* 代码。
*/
int main(空白)
{
dave_status_T 状态;
状态 = dave_init ();/* DAVE 应用程序的初始化*/
如果(状态!= DAVE_STATUS_SUCCESS)
{
/* 错误处理程序代码的占位符。 下面的 while 循环 CAN 替换为用户错误处理程序。 */
XMC_DEBUG("DAVE 应用程序初始化失败 n);"
而 (1U)
{
}
}
motorInitialize(0);
setZero(0);
start = 1;
/* 用户应用程序代码的占位符。 下面的 while 循环 CAN 替换为用户应用程序代码。 */
while(start)
{
p_int = p_int + 0.01;
transmitMessage(0, p1, v1, t1);
receiveMessage(1, id, p1o, v1o, t1o);
sprintf(str,"%d,%.2f,%.2f,%.2f,%.2f,%.2f,%.2frn",id,p1,v1,t1,p1o,v1o,t1o);
SEGGER_RTT_WriteString(0, str);
}
}
smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/XMC/XMC4500/td-p/711673