mirror of
https://github.com/goldenfishs/MRobot.git
synced 2025-12-17 13:29:54 +08:00
add-oid编码器
This commit is contained in:
parent
2e68c0d0bc
commit
b9f7e63025
@ -1,4 +1,4 @@
|
||||
bsp,can,dwt,gpio,i2c,mm,spi,uart,pwm,time
|
||||
component,ahrs,capacity,cmd,crc8,crc16,error_detect,filter,FreeRTOS_CLI,limiter,mixer,pid,ui,user_math
|
||||
device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9
|
||||
device,dr16,bmi088,ist8310,motor,motor_rm,motor_dm,motor_vesc,motor_lk,motor_lz,motor_odrive,dm_imu,rc_can,servo,buzzer,led,ws2812,vofa,ops9,oid
|
||||
module,config,
|
||||
|
@ -224,4 +224,14 @@ devices:
|
||||
thread_signals: []
|
||||
files:
|
||||
header: "vofa.h"
|
||||
source: "vofa.c"
|
||||
source: "vofa.c"
|
||||
oid:
|
||||
name: "oid编码器"
|
||||
description: "oid编码器驱动"
|
||||
dependencies:
|
||||
bsp: ["time", "can", "mm"]
|
||||
component: ["user_math"]
|
||||
thread_signals: []
|
||||
files:
|
||||
header: "oid.h"
|
||||
source: "oid.c"
|
||||
467
device/oid.c
Normal file
467
device/oid.c
Normal file
@ -0,0 +1,467 @@
|
||||
/*
|
||||
oid编码器驱动
|
||||
*/
|
||||
|
||||
/*编码器can通信的默认波特率为500kHZ*/
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "device/oid.h"
|
||||
#include "bsp/time.h"
|
||||
#include "mm.h"
|
||||
/* Private function prototypes ---------------------------------------------- */
|
||||
|
||||
static OID_CANManager_t* OID_GetCANManager(BSP_CAN_t can);
|
||||
|
||||
/* Private functions -------------------------------------------------------- */
|
||||
|
||||
static OID_CANManager_t *can_managers[BSP_CAN_NUM] = {NULL};
|
||||
|
||||
/**
|
||||
* @brief 接收数据处理
|
||||
* @param[in] none
|
||||
* @retval none
|
||||
*/
|
||||
static void OID_ParseFeedbackFrame( OID_t *encoder , uint8_t *rx_data )
|
||||
{
|
||||
if(encoder->param.id == rx_data[1])//判断编码器id
|
||||
{
|
||||
switch(rx_data[2])//判断指令
|
||||
{
|
||||
case 0x01:
|
||||
encoder->feedback.angle_fbk = rx_data[3]|rx_data[4]<<8|rx_data[5]<<16|rx_data[6]<<24;
|
||||
encoder->feedback.angle_360 = encoder->feedback.angle_fbk*360.0f/OID_RESOLUTION;
|
||||
encoder->feedback.angle_2PI = encoder->feedback.angle_fbk*M_2PI/OID_RESOLUTION;
|
||||
break;
|
||||
|
||||
case 0x0A:
|
||||
encoder->feedback.speed_fbk=rx_data[3]|rx_data[4]<<8|rx_data[5]<<16|rx_data[6]<<24;
|
||||
encoder->feedback.speed_rpm=encoder->feedback.speed_fbk/OID_RESOLUTION/(0.1f/60.0f);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8_t OID_Update(OID_Param_t *param)
|
||||
{
|
||||
|
||||
if (param == NULL) return DEVICE_ERR_NULL;
|
||||
|
||||
OID_CANManager_t *manager = OID_GetCANManager(param->can);
|
||||
if (manager == NULL) return DEVICE_ERR_NULL;
|
||||
|
||||
OID_t *encoder = NULL;
|
||||
|
||||
for (int i = 0; i < manager->encoder_count; i++) {
|
||||
if (manager->encoders[i] && manager->encoders[i]->param.id == param->id) {
|
||||
encoder = manager->encoders[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (encoder == NULL) return DEVICE_ERR_NO_DEV;
|
||||
|
||||
// 从CAN队列获取数据
|
||||
BSP_CAN_Message_t rx_msg;
|
||||
if (BSP_CAN_GetMessage( param->can , param->id , &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK)
|
||||
{
|
||||
uint64_t now_time = BSP_TIME_Get();
|
||||
if (now_time - encoder->header.last_online_time > 100000) // 100ms超时,单位微秒
|
||||
{
|
||||
encoder->header.online = false;
|
||||
}
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
encoder->header.online = true;
|
||||
encoder->header.last_online_time = BSP_TIME_Get();
|
||||
// 处理接收到的数据
|
||||
OID_ParseFeedbackFrame( encoder , rx_msg.data );
|
||||
return DEVICE_OK; // 没有新数据
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 更新所有编码器数据
|
||||
* @return 更新结果
|
||||
*/
|
||||
int8_t OID_UpdateAll(void) {
|
||||
int8_t ret = DEVICE_OK;
|
||||
for (int can = 0; can < BSP_CAN_NUM; can++) {
|
||||
OID_CANManager_t *manager = OID_GetCANManager((BSP_CAN_t)can);
|
||||
if (manager == NULL) continue;
|
||||
|
||||
for (int i = 0; i < manager->encoder_count; i++) {
|
||||
OID_t *encoder = manager->encoders[i];
|
||||
if (encoder != NULL) {
|
||||
if (OID_Update(&encoder->param) != DEVICE_OK) {
|
||||
ret = DEVICE_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取指定CAN总线的管理器
|
||||
* @param can CAN总线
|
||||
* @return CAN管理器指针
|
||||
*/
|
||||
static OID_CANManager_t* OID_GetCANManager(BSP_CAN_t can) {
|
||||
if (can >= BSP_CAN_NUM) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return can_managers[can];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建CAN管理器
|
||||
* @param can CAN总线
|
||||
* @return 创建结果
|
||||
*/
|
||||
static int8_t OID_CreateCANManager(BSP_CAN_t can) {
|
||||
if (can >= BSP_CAN_NUM) return DEVICE_ERR;
|
||||
if (can_managers[can] != NULL) return DEVICE_OK;
|
||||
|
||||
can_managers[can] = (OID_CANManager_t*)BSP_Malloc(sizeof(OID_CANManager_t));
|
||||
if (can_managers[can] == NULL) return DEVICE_ERR;
|
||||
|
||||
memset(can_managers[can], 0, sizeof(OID_CANManager_t));
|
||||
can_managers[can]->can = can;
|
||||
return DEVICE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 注册一个欧艾迪编码器
|
||||
* @param param 编码器参数
|
||||
* @return 注册结果
|
||||
*/
|
||||
int8_t OID_Register(OID_Param_t *param)
|
||||
{
|
||||
if (param == NULL) {
|
||||
return DEVICE_ERR_NULL;
|
||||
}
|
||||
|
||||
/* 创建CAN管理器 */
|
||||
if (OID_CreateCANManager(param->can) != DEVICE_OK) {
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
/* 获取CAN管理器 */
|
||||
OID_CANManager_t *manager = OID_GetCANManager(param->can);
|
||||
if (manager == NULL) {
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
/* 检查是否已注册 */
|
||||
for (int i = 0; i < manager->encoder_count; i++) {
|
||||
if (manager->encoders[i] && manager->encoders[i]->param.id == param->id) {
|
||||
return DEVICE_ERR_INITED;
|
||||
}
|
||||
}
|
||||
|
||||
/* 检查是否已达到最大数量 */
|
||||
if (manager->encoder_count >= OID_MAX_NUM) {
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
/* 分配内存 */
|
||||
OID_t *encoder = (OID_t *)BSP_Malloc(sizeof(OID_t));
|
||||
if (encoder == NULL) {
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
/* 初始化电机 */
|
||||
memset(encoder, 0, sizeof(OID_t));
|
||||
memcpy(&encoder->param, param, sizeof(OID_Param_t));
|
||||
encoder->header.online = false;
|
||||
// encoder->encoder.reverse = param->reverse;
|
||||
|
||||
/* 注册CAN接收ID - DM电机使用Master ID接收反馈 */
|
||||
uint16_t feedback_id = param->id;
|
||||
if (BSP_CAN_RegisterId(param->can, feedback_id, 3) != BSP_OK) {
|
||||
BSP_Free(encoder);
|
||||
return DEVICE_ERR;
|
||||
}
|
||||
|
||||
/* 添加到管理器 */
|
||||
manager->encoders[manager->encoder_count] = encoder;
|
||||
manager->encoder_count++;
|
||||
|
||||
return DEVICE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 使编码器离线(设置在线状态为false)
|
||||
* @param param 编码器参数
|
||||
* @return 操作结果
|
||||
*/
|
||||
int8_t OID_Offline(OID_Param_t *param) {
|
||||
if (param == NULL) {
|
||||
return DEVICE_ERR_NULL;
|
||||
}
|
||||
|
||||
OID_t *encoder = OID_GetEncoder(param);
|
||||
if (encoder == NULL) {
|
||||
return DEVICE_ERR_NO_DEV;
|
||||
}
|
||||
|
||||
encoder->header.online = false;
|
||||
return DEVICE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取指定编码器的实例指针
|
||||
* @param param 编码器参数
|
||||
* @return 编码器实例指针
|
||||
*/
|
||||
OID_t* OID_GetEncoder(OID_Param_t *param) {
|
||||
if (param == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OID_CANManager_t *manager = OID_GetCANManager(param->can);
|
||||
if (manager == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 查找对应的编码器 */
|
||||
for (int i = 0; i < manager->encoder_count; i++) {
|
||||
OID_t *encoder = manager->encoders[i];
|
||||
if (encoder && encoder->param.can == param->can &&
|
||||
encoder->param.id == param->id) {
|
||||
return encoder;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/**
|
||||
* @brief 读取编码器值
|
||||
* @param[in] 编码器id
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Read_Value(OID_Param_t *param)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x01;
|
||||
frame.data[3] = 0x00;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置编码器id
|
||||
* @param[in] 编码器当前id,编码器设置id
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_ID(OID_Param_t *param,OID_Param_t *param_new)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x02;
|
||||
frame.data[3] = param_new->id;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置can通讯波特率 0x00:500K(默认);0x01:1M;0x02:250K;0x03:125K;0x04:100K;
|
||||
* @param[in] 编码器id,编码器设置波特率
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_Baudrate(OID_Param_t *param,OID_Baudrate_t encoder_vaud_rate)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x03;
|
||||
frame.data[3] = encoder_vaud_rate;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置编码器模式 0x00:查询,0x02:自动返回编码器角速度值,0xAA:自动返回编码器值
|
||||
* @param[in] 编码器id,编码器设置模式
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_Mode(OID_Param_t *param,OID_Mode_t encoder_mode)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x04;
|
||||
frame.data[3] = encoder_mode;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置编码器自动回传时间(掉电记忆,单位:微秒),数值范围:50~65535(16 位无符号整数)
|
||||
注意:设置太短的返回时间后,通过编码器上位机再设置其他参数很容易失败,谨慎使用!
|
||||
* @param[in] 编码器id,编码器自动回传时间
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_AutoFeedbackTime(OID_Param_t *param,uint8_t encoder_time)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x05;
|
||||
frame.data[3] = encoder_time;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置当前位置值为零点
|
||||
* @param[in] 编码器id
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_ZeroPoint(OID_Param_t *param)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x06;
|
||||
frame.data[3] = 0x00;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置编码器值递增方向 0x00:顺时针,0x01:逆时针
|
||||
* @param[in] 编码器id
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_Polarity(OID_Param_t *param,OID_Direction_t encoder_direction)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x07;
|
||||
frame.data[3] = encoder_direction;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 读取编码器角度值
|
||||
* @param[in] 编码器id
|
||||
* @retval none
|
||||
编码器旋转速度=编码器角速度值/单圈
|
||||
精度/转速计算时间(单位:转/分钟)
|
||||
例如:编码器角速度值回传为1000,单圈
|
||||
精度为32768,转速采样时间为
|
||||
100ms(0.1/60min)
|
||||
编码器旋转速度=1000/32768/(0.1/60)
|
||||
=1000*0.0183=18.31转/分钟
|
||||
*/
|
||||
int8_t OID_Read_AngularVelocity(OID_Param_t *param)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x0A;
|
||||
frame.data[3] = 0x00;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置编码器角速度采样时间(掉电记忆,单位:毫秒)
|
||||
* @param[in] 编码器id,采样时间
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_AngularVelocitySamplingTime(OID_Param_t *param,uint8_t encoder_time)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x0B;
|
||||
frame.data[3] = encoder_time;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置编码器中点 设定当前编码器值为 M(M 为单圈分辨率*圈数/2)
|
||||
* @param[in] 编码器id
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_Midpoint(OID_Param_t *param)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x0C;
|
||||
frame.data[3] = 0x01;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 设置编码器当前位置值 数值范围:0~X(X 为单圈分辨率*圈数- 1)
|
||||
* @param[in] 编码器id
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_CurrentPosition(OID_Param_t *param,uint8_t encoder_direction)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x0D;
|
||||
frame.data[3] = encoder_direction;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
/**
|
||||
* @brief 编码器设置当前值为 5 圈值 即当前编码器值为 Z(Z 为单圈分辨率*5)
|
||||
* @param[in] 编码器id
|
||||
* @retval none
|
||||
*/
|
||||
int8_t OID_Set_CurrentValue5Turns(OID_Param_t *param)
|
||||
{
|
||||
BSP_CAN_StdDataFrame_t frame;
|
||||
frame.id = param->id;
|
||||
frame.dlc = 4;
|
||||
frame.data[0] = 0x04;
|
||||
frame.data[1] = param->id;
|
||||
frame.data[2] = 0x0F;
|
||||
frame.data[3] = 0x01;
|
||||
|
||||
|
||||
return BSP_CAN_TransmitStdDataFrame(param->can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
269
device/oid.h
Normal file
269
device/oid.h
Normal file
@ -0,0 +1,269 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "device/device.h"
|
||||
#include "bsp/can.h"
|
||||
#include "component/user_math.h"
|
||||
|
||||
/* Exported constants ------------------------------------------------------- */
|
||||
#define OID_MAX_NUM 32
|
||||
#define OID_RESOLUTION 1024 //编码器分辨率
|
||||
/* Exported macro ----------------------------------------------------------- */
|
||||
/* Exported types ----------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief 编码器工作模式枚举
|
||||
*/
|
||||
typedef enum {
|
||||
OID_MODE_QUERY = 0x00, // 查询模式
|
||||
OID_MODE_AUTO_SPEED = 0x02, // 自动返回编码器角速度值
|
||||
OID_MODE_AUTO_POSITION = 0xAA // 自动返回编码器值
|
||||
} OID_Mode_t;
|
||||
|
||||
/**
|
||||
* @brief 编码器方向枚举
|
||||
*/
|
||||
typedef enum {
|
||||
OID_DIR_CW = 0x00, // 顺时针
|
||||
OID_DIR_CCW = 0x01 // 逆时针
|
||||
} OID_Direction_t;
|
||||
|
||||
/**
|
||||
* @brief 编码器波特率枚举
|
||||
* 当编码器的ID和波特率更改后,闪灯的颜色会相应变化,状态灯颜色参照表及代表的意义如下:
|
||||
*
|
||||
* 颜色及其数值定义关系:
|
||||
* - 蓝色(0) : 500K(默认)
|
||||
* - 青色(1) : 1M
|
||||
* - 橙色(2) : 250K
|
||||
* - 紫色(3) : 125K
|
||||
* - 绿色(4) : 100K
|
||||
* - 红色(5) : 保留
|
||||
*/
|
||||
typedef enum {
|
||||
OID_BAUD_500K = 0x00, // 蓝色 - 500K(默认)
|
||||
OID_BAUD_1M = 0x01, // 青色 - 1M
|
||||
OID_BAUD_250K = 0x02, // 橙色 - 250K
|
||||
OID_BAUD_125K = 0x03, // 紫色 - 125K
|
||||
OID_BAUD_100K = 0x04 // 绿色 - 100K
|
||||
} OID_Baudrate_t;
|
||||
|
||||
typedef struct {
|
||||
BSP_CAN_t can;
|
||||
uint16_t id;
|
||||
|
||||
} OID_Param_t;
|
||||
|
||||
typedef struct {
|
||||
//0x01 编码器值反馈
|
||||
float angle_fbk;
|
||||
float angle_360;
|
||||
float angle_2PI;
|
||||
//0x0A 速度反馈
|
||||
float speed_fbk;
|
||||
float speed_rpm;
|
||||
|
||||
} OID_Feedback_t;
|
||||
|
||||
typedef struct {
|
||||
DEVICE_Header_t header;
|
||||
OID_Param_t param;
|
||||
OID_Feedback_t feedback;
|
||||
} OID_t;
|
||||
|
||||
/*CAN管理器,管理一个CAN总线上所有的编码器*/
|
||||
typedef struct {
|
||||
BSP_CAN_t can;
|
||||
OID_t *encoders[OID_MAX_NUM];
|
||||
uint8_t encoder_count;
|
||||
} OID_CANManager_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief 更新指定编码器数据
|
||||
* @param param 编码器参数指针
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR_NULL: 参数为空
|
||||
* - DEVICE_ERR_NO_DEV: 编码器未找到
|
||||
* - DEVICE_ERR: 其他错误
|
||||
*/
|
||||
int8_t OID_Update(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 更新所有已注册编码器数据
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 全部成功
|
||||
* - DEVICE_ERR: 部分或全部失败
|
||||
*/
|
||||
int8_t OID_UpdateAll(void);
|
||||
|
||||
/**
|
||||
* @brief 注册一个欧艾迪编码器
|
||||
* @param param 编码器参数指针
|
||||
* @return 注册结果
|
||||
* - DEVICE_OK: 注册成功
|
||||
* - DEVICE_ERR_NULL: 参数为空
|
||||
* - DEVICE_ERR_INITED: 已注册
|
||||
* - DEVICE_ERR: 其他错误
|
||||
*/
|
||||
int8_t OID_Register(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器离线状态
|
||||
* @param param 编码器参数指针
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR_NULL: 参数为空
|
||||
* - DEVICE_ERR_NO_DEV: 编码器未找到
|
||||
*/
|
||||
int8_t OID_Offline(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 获取指定编码器实例指针
|
||||
* @param param 编码器参数指针
|
||||
* @return 编码器实例指针,失败返回NULL
|
||||
*/
|
||||
OID_t* OID_GetEncoder(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器ID
|
||||
* @param param 当前编码器参数
|
||||
* @param param_new 新编码器参数(包含新ID)
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_ID(OID_Param_t *param, OID_Param_t *param_new);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器CAN通信波特率
|
||||
* @param param 编码器参数
|
||||
* @param encoder_vaud_rate 波特率设置
|
||||
* - 0x00: 500K(默认)
|
||||
* - 0x01: 1M
|
||||
* - 0x02: 250K
|
||||
* - 0x03: 125K
|
||||
* - 0x04: 100K
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_Baudrate(OID_Param_t *param, OID_Baudrate_t encoder_vaud_rate);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器工作模式
|
||||
* @param param 编码器参数
|
||||
* @param encoder_mode 工作模式
|
||||
* - 0x00: 查询模式
|
||||
* - 0x02: 自动返回编码器角速度值
|
||||
* - 0xAA: 自动返回编码器值
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_Mode(OID_Param_t *param, OID_Mode_t encoder_mode);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器自动回传时间
|
||||
* @param param 编码器参数
|
||||
* @param encoder_time 自动回传时间(单位:微秒)
|
||||
* 数值范围:50~65535(16位无符号整数)
|
||||
* @note 注意:设置太短的返回时间后,通过编码器上位机再设置其他参数很容易失败,谨慎使用!
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_AutoFeedbackTime(OID_Param_t *param, uint8_t encoder_time);
|
||||
|
||||
/**
|
||||
* @brief 设置当前位置为零点
|
||||
* @param param 编码器参数
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_ZeroPoint(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器值递增方向
|
||||
* @param param 编码器参数
|
||||
* @param encoder_direction 方向设置
|
||||
* - 0x00: 顺时针
|
||||
* - 0x01: 逆时针
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_Polarity(OID_Param_t *param, OID_Direction_t encoder_direction);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器角速度采样时间
|
||||
* @param param 编码器参数
|
||||
* @param encoder_time 采样时间(单位:毫秒)
|
||||
* @note 掉电记忆功能
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_AngularVelocitySamplingTime(OID_Param_t *param, uint8_t encoder_time);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器中点位置
|
||||
* @param param 编码器参数
|
||||
* @note 设定当前编码器值为 M(M 为单圈分辨率 × 圈数 / 2)
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_Midpoint(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器当前位置值
|
||||
* @param param 编码器参数
|
||||
* @param encoder_direction 位置值
|
||||
* 数值范围:0~X(X 为单圈分辨率 × 圈数 - 1)
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_CurrentPosition(OID_Param_t *param, uint8_t encoder_direction);
|
||||
|
||||
/**
|
||||
* @brief 设置编码器当前值为5圈值
|
||||
* @param param 编码器参数
|
||||
* @note 即当前编码器值为 Z(Z 为单圈分辨率 × 5)
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Set_CurrentValue5Turns(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 读取编码器角速度值
|
||||
* @param param 编码器参数
|
||||
* @note 编码器旋转速度 = 编码器角速度值 / 单圈精度 / 转速计算时间(单位:转/分钟)
|
||||
* 例如:编码器角速度值回传为1000,单圈精度为32768,转速采样时间为100ms(0.1/60min)
|
||||
* 编码器旋转速度 = 1000 / 32768 / (0.1/60) = 1000 × 0.0183 = 18.31转/分钟
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Read_AngularVelocity(OID_Param_t *param);
|
||||
|
||||
/**
|
||||
* @brief 读取编码器值
|
||||
* @param param 编码器参数
|
||||
* @return 操作结果
|
||||
* - DEVICE_OK: 成功
|
||||
* - DEVICE_ERR: 失败
|
||||
*/
|
||||
int8_t OID_Read_Value(OID_Param_t *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user