爱思控无刷电机驱动器的软件驱动

发布时间:2026/7/11 5:52:23

爱思控无刷电机驱动器的软件驱动
以前调过好几款CAN驱动的无刷电机驱动器把驱动软件分享下使用的是32位嵌入式单片机平台。话不多说以下是爱思控的驱动代码。.c文件内部还有一键配置的函数drdr_hw_initAqmdWalkConfig()这个是我写的自动学习电机统一配置参数当时还和他们客服说过这样量产的时候就不用每台都用电脑操作上位机去配置每项了那样还容易漏#include hw_brushless_aqmd.h /** * 无刷行走电机控制初始化 */ static DR_GPIO_InitTypeDef brushless_power_gpio; AQMD_INFO aqmd_info; static int16 aqmd_now_freq 0; static AQMD_WalkDir _brushless_aqmd_dir AQMD_BRUSHLESS_DIR_HALT; // 行走电机处理任务运行标志 static boolean _brushless_task_flag TRUE; static boolean _wait_learning_flag FALSE; static OS_STK CLSX_BRUSHLESS_TASK_STK[CLSX_BRUSHLESS_TASK_STK_SIZE]; /** * 初始化 行走电机处理任务 */ static void drdr_brushless_aqmd_task_init( void ); /** * 离心式喷头处理任务 */ static void drdr_brushless_aqmd_task( void* p_arg ); /** * 读电机驱动器寄存器信息tc */ static void drdr_hw_aqmd_read(uint16 reg); /** * 写电机驱动器寄存器信息 */ static void drdr_hw_aqmd_write(uint16 reg, int32 data, uint8 length); /** * 设置电机换相频率转速当前电机区间1~1450 */ static void drdr_hw_brushless_aqmdFreq(int16 freq); /** * 设置电机换相频率转速当前电机区间1~1450 */ void drdr_hw_brushless_aqmdRun(int16 freq); /** * 转换数据 */ int16 aqmd_convert_data(uint8 * data){ int16 convert_data; convert_data (data[5] 8) | data[4]; return convert_data; } /** * 读取数据处理 */ void CLSX_BRUSHLESS_AQMD_CAN_ISR(DR_CAN_CH dr_can_ch, uint32 can_id, uint8 * _data) { uint16 cmd (_data[2] 8) | _data[1]; if(DATA_LENGTH_2_BYTES _data[0]) { switch(cmd) { case AQMD_LOCKED_STATE: aqmd_info.aqmd_locked_status (SRWalkMotorDriverLockedStatus)DRDR_Read_INT16(_data, 4); DRDR_Sr_Context_seWalkMotorDriverLockedStatus(aqmd_info.aqmd_locked_status); break; case AQMD_ERROR_STATUS: aqmd_info.aqmd_error_status (SRWalkMotorDriverErrorStatus)DRDR_Read_INT16(_data, 4); DRDR_Sr_Context_seWalkMotorDriverErrorStatus(aqmd_info.aqmd_error_status); break; case AQMD_SUPPLY_VOLTAGE: aqmd_info.aqmd_out_voltage DRDR_Read_INT16(_data, 4); DRDR_Sr_Context_setWalkMotorVoltage(aqmd_info.aqmd_out_voltage); break; case AQMD_REAL_TIME_CURRENT: aqmd_info.aqmd_out_current DRDR_Read_INT16(_data, 4); DRDR_Sr_Context_setWalkMotorCurrent(aqmd_info.aqmd_out_current); break; case AQMD_MOTOR_SPEED_TEN_FLAG: aqmd_info.aqmd_rpm_ten_flag DRDR_Read_INT16(_data, 4); break; case AQMD_MOTOR_SPEED: aqmd_info.aqmd_actual_rpm aqmd_info.aqmd_rpm_ten_flag ? DRDR_Read_INT16(_data, 4) * 10 : DRDR_Read_INT16(_data, 4); DRDR_Sr_Context_setWalkMotorRPM(aqmd_info.aqmd_actual_rpm); break; // case AQMD_REAL_TIME_FREQ: // aqmd_info.aqmd_actual_freq aqmd_info.aqmd_rpm_ten_flag ? DRDR_Read_INT16(_data, 4) : 0.1 * DRDR_Read_INT16(_data, 4); // break; // case AQMD_BUS_CURRENT: // aqmd_info.aqmd_bus_current DRDR_Read_INT16(_data, 4); // break; case AQMD_INTERNAL_TEMPERATURE: aqmd_info.aqmd_temperature DRDR_Read_INT16(_data, 4); DRDR_Sr_Context_setWalkMotorDriverTemperature(aqmd_info.aqmd_temperature); break; case AQMD_LEARN_MOTOR_STATUS: aqmd_info.aqmd_learn_status aqmd_convert_data(_data); break; default: break; } } } /** * 读取电机的相关信息 */ static void drdr_hw_aqmd_get_info(){ drdr_hw_aqmd_read(AQMD_LOCKED_STATE); DRDR_dlyHMSM(0, 0, 0, 20); drdr_hw_aqmd_read(AQMD_ERROR_STATUS); DRDR_dlyHMSM(0, 0, 0, 20); drdr_hw_aqmd_read(AQMD_SUPPLY_VOLTAGE); DRDR_dlyHMSM(0, 0, 0, 20); drdr_hw_aqmd_read(AQMD_REAL_TIME_CURRENT); DRDR_dlyHMSM(0, 0, 0, 20); drdr_hw_aqmd_read(AQMD_MOTOR_SPEED_TEN_FLAG); DRDR_dlyHMSM(0, 0, 0, 20); drdr_hw_aqmd_read(AQMD_MOTOR_SPEED); DRDR_dlyHMSM(0, 0, 0, 20); // drdr_hw_aqmd_read(AQMD_REAL_TIME_FREQ); // DRDR_dlyHMSM(0, 0, 0, 20); // drdr_hw_aqmd_read(AQMD_BUS_CURRENT); // DRDR_dlyHMSM(0, 0, 0, 20); drdr_hw_aqmd_read(AQMD_INTERNAL_TEMPERATURE); DRDR_dlyHMSM(0, 0, 0, 20); drdr_hw_brushless_aqmdReadLearnMotor();//读取电机学习结果 DRDR_dlyHMSM(0, 0, 0, 20); } /** * 写电机驱动器寄存器信息 */ static void drdr_hw_aqmd_write(uint16 reg, int32 data, uint8 length) { uint8 message[8] {0}; switch (length){ case 1: message[0] WRITE_A_SINGLE_BYTE; DRDR_Write_INT8(message, 4, data); break; case 2: message[0] WRITE_DOUBLE_BYTES; DRDR_Write_INT16(message, 4, data); break; case 3: message[0] WRITE_THREE_BYTES; DRDR_Uint8_codr(message, (uint8 *)data, 3); break; case 4: message[0] WRITE_FOUR_BYTES; DRDR_Write_INT32(message, 4, data); break; default : message[0] WRITE_DOUBLE_BYTES; break; } message[1] reg 0xFF; message[2] (reg 8) 0xFF; message[3] 0x00; dr_can_sendStdFrame(DR_CAN_CH_2, AQMD_BRUSHLESS_CAN_ID_NOTIFY, message, 8); } /** * 读电机驱动器寄存器信息 */ static void drdr_hw_aqmd_read(uint16 reg) { uint8 message[8] {0}; message[0] READ_BYTES; message[1] reg 0xFF; message[2] (reg 8) 0xFF; message[3] 0x00; dr_can_sendStdFrame(DR_CAN_CH_2, AQMD_BRUSHLESS_CAN_ID_NOTIFY, message, 8); } /** * 设置电机换相频率转速当前电机区间1~1150 */ static void drdr_hw_brushless_aqmdFreq(int16 freq){ if(AQMD_BRUSHLESS_DIR_FORWARD _brushless_aqmd_dir) { if(freq 0) { aqmd_now_freq -freq; }else { aqmd_now_freq freq; } }else if(AQMD_BRUSHLESS_DIR_BACKWARD _brushless_aqmd_dir) { if(freq 0) { aqmd_now_freq -freq; }else { aqmd_now_freq freq; } }else if(AQMD_BRUSHLESS_DIR_HALT _brushless_aqmd_dir){ aqmd_now_freq 0; } } /** * 设置电机换相频率转速当前电机区间1~1450 */ void drdr_hw_brushless_aqmdRun(int16 freq){ if(AQMD_BRUSHLESS_DIR_FORWARD _brushless_aqmd_dir || AQMD_BRUSHLESS_DIR_BACKWARD _brushless_aqmd_dir){ if(0 aqmd_info.aqmd_rpm_ten_flag) { drdr_hw_aqmd_write(AQMD_SET_TARGET_FREQ, aqmd_now_freq*10, 2); }else { drdr_hw_aqmd_write(AQMD_SET_TARGET_FREQ, aqmd_now_freq, 2); } DRDR_dlyHMSM(0, 0, 0, 10); } } /** * 设置电机停止 */ void drdr_hw_brushless_aqmdStop(){ drdr_hw_aqmd_write(AQMD_BRUSHLESS_STOP, 1, 2); DRDR_dlyHMSM(0, 0, 0, 10); } /** * 设置波特率 */ void drdr_hw_brushless_aqmdBaudrate(AQMD_CanBaudrate can_baudrate) { drdr_hw_aqmd_write(AQMD_SET_CANBAUDRATE, can_baudrate, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 开始电机学习 */ void drdr_hw_brushless_aqmdLearnMotor(){ drdr_hw_aqmd_write(AQMD_LEARN_MOTOR, 1, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 读取电机学习结果 */ void drdr_hw_brushless_aqmdReadLearnMotor(){ drdr_hw_aqmd_read(AQMD_LEARN_MOTOR_STATUS); DRDR_dlyHMSM(0, 0, 0, 10); } /** * 设置最大换向频率数值乘以0.1为最大换向频率 */ void drdr_hw_brushless_aqmdSetMaxTimeFreq(int16 max_freq10){ drdr_hw_aqmd_write(AQMD_MAX_TIME_FREQ, max_freq10, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置默认换向频率数值乘以0.1为默认换向频率 */ void drdr_hw_brushless_aqmdSetDefaultTimeFreq(int16 default_freq10){ drdr_hw_aqmd_write(AQMD_DEFAULT_TIME_FREQ, default_freq10, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置电机极个数极对数*2与电机有关影响驱动器转速反馈当前为8 */ void drdr_hw_brushless_aqmdPolesNum(int16 poles_num){ drdr_hw_aqmd_write(AQMD_SET_MOTOR_POLES_NUM, poles_num, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置通讯中断制动时间(数值乘以 0.1 为通讯中断停止时间单位为s) */ void drdr_hw_brushless_aqmdCommunicationInterruptionBrakingTime(uint8 second10) { drdr_hw_aqmd_write(AQMD_COMMUNICATION_INT_BRAKING, second10, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置禁用蜂鸣器报警 */ void drdr_hw_brushless_aqmdDisable_buzzer_alarm(uint8 off){ drdr_hw_aqmd_write(AQMD_DISABLE_BUZZER_ALARM, off, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置位置闭环控制允许误差 */ void drdr_hw_brushless_aqmdPositionAllowsError(uint16 num){ drdr_hw_aqmd_write(AQMD_POSITION_CLOSED_LOOP_ALLOWS_ERROR, num, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置速度闭环控制算法 */ void drdr_hw_brushless_aqmdSpeedControlAlgorithm(uint8 num){ drdr_hw_aqmd_write(AQMD_SPEED_CLOSED_LOOP_CONTROL_ALGORITHM, num, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置最大加速加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s */ void drdr_hw_brushless_aqmdSetMaxAcc(uint16 num){ drdr_hw_aqmd_write(AQMD_MAXIMUM_ACCELERATION, num, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置默认加速加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s */ void drdr_hw_brushless_aqmdSetDefaultAcc(uint16 num){ drdr_hw_aqmd_write(AQMD_DEFAULT_ACCELERATION, num, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置最大减速加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s */ void drdr_hw_brushless_aqmdSetMaxDecelerationAcc(uint16 num){ drdr_hw_aqmd_write(AQMD_MAXIMUM_DECELERATION_ACCELERATION, num, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置默认减速加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s */ void drdr_hw_brushless_aqmdSetDefaultDecelerationAcc(uint16 num){ drdr_hw_aqmd_write(AQMD_DEFAULT_DECELERATION_ACCELERATION, num, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置额定电流 数值乘以0.01为电流值单位为A */ void drdr_hw_brushless_aqmdSetRatedCurrent(uint16 num100){ drdr_hw_aqmd_write(AQMD_RATED_CURRENT_OF_MOTOR, num100, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 设置最大负载电流 数值乘以0.01为电流值单位为A */ void drdr_hw_brushless_aqmdSetMaxLoadCurrent(uint16 num100){ drdr_hw_aqmd_write(AQMD_MAXIMUM_LOAD_CURRENT_OF_MOTOR, num100, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 存储电机配置参数 */ void drdr_hw_brushless_aqmdSaveMotorConfigParameter(uint8 save){ drdr_hw_aqmd_write(AQMD_SAVE_MOTOR_CONFIG_PARAMETER, save, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 存储系统配置参数 */ void drdr_hw_brushless_aqmdSaveSystemConfigParameter(uint8 save){ drdr_hw_aqmd_write(AQMD_SAVE_SYSTEM_CONFIG_PARAMETER, save, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 存储闭环调速PID参数 */ void drdr_hw_brushless_aqmdSavePidConfigParameter(uint8 save){ drdr_hw_aqmd_write(AQMD_SAVE_PID_CONFIG_PARAMETER, save, 2); DRDR_dlyHMSM(0, 0, 0, 20); } /** * 无刷行走电机配置 */ void drdr_hw_initAqmdWalkConfig(void) { uint32 os_ticks; // drdr_hw_brushless_aqmdBaudrate(AQMD_CAN_BAUDRATE_500); _wait_learning_flag FALSE; os_ticks OSTimeGet(); while (1 ! aqmd_info.aqmd_learn_status) { DRDR_dlyHMSM(0, 0, 0, 500); if(OSTimeGet() os_ticks 10000){//十秒超时 break; } } if(1 ! aqmd_info.aqmd_learn_status) { _wait_learning_flag TRUE; DRDR_dlyHMSM(0, 0, 0, 100); drdr_hw_brushless_aqmdLearnMotor();//进行电机学习 DRDR_dlyHMSM(0, 0, 10, 0); _wait_learning_flag FALSE; } os_ticks OSTimeGet(); while (1 ! aqmd_info.aqmd_learn_status) { DRDR_dlyHMSM(0, 0, 0, 100); if(OSTimeGet() os_ticks 2000){//两秒超时 break; } } if(1 aqmd_info.aqmd_learn_status) { _wait_learning_flag TRUE; DRDR_dlyHMSM(0, 0, 0, 100); drdr_hw_brushless_aqmdFreq(0); drdr_hw_brushless_aqmdStop(); drdr_hw_brushless_aqmdPolesNum(8);//极个数8 √ drdr_hw_brushless_aqmdCommunicationInterruptionBrakingTime(10);//通讯中断制动时间1.0秒 ×√ drdr_hw_brushless_aqmdSetMaxTimeFreq(17000);//最大换向频率(17000/10)Hz √ drdr_hw_brushless_aqmdSetDefaultTimeFreq(10000);//默认换向频率(10000/10)Hz √ drdr_hw_brushless_aqmdDisable_buzzer_alarm(1);//禁用蜂鸣器报警 1 ×√ drdr_hw_brushless_aqmdPositionAllowsError(10);//位置闭环控制允许误差10个脉冲 √ drdr_hw_brushless_aqmdSpeedControlAlgorithm(1);//时间-位置闭环控制 1 √ drdr_hw_brushless_aqmdSetMaxAcc(8000);//最大加速加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s 8000 √ drdr_hw_brushless_aqmdSetDefaultAcc(8000);//加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s 8000 √ drdr_hw_brushless_aqmdSetMaxDecelerationAcc(8000);//加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s 8000 √ drdr_hw_brushless_aqmdSetDefaultDecelerationAcc(8000);//加速度 数值乘以0.1为换向频率最大增大速度单位为 Hz/s 8000 √ drdr_hw_brushless_aqmdSetRatedCurrent(2380);//电机额定电流 数值乘以0.01为电流值单位为A 2380 √ drdr_hw_brushless_aqmdSetMaxLoadCurrent(2380);//最大负载电流 数值乘以0.01为电流值单位为A 2380 √ drdr_hw_brushless_aqmdSaveMotorConfigParameter(1);//保存电机配置参数 电机参数一页全部保存 drdr_hw_brushless_aqmdSaveSystemConfigParameter(1);//保存系统配置参数额外包括了中断制动时间 _wait_learning_flag FALSE; //显示配置完成 dwin_show_fault_flag | 0x40;//表示已检查 dwin_show_fault_flag ~0x04; uint8 data[8] {0}; data[0] 0xAA; data[1] 0x55; data[2] 0xBB; data[3] dwin_show_fault_flag; dr_can_sendExtFrame(DR_CAN_CH_1, 0x111, data, 8);//发送迪文屏正确显示 for(int i 0; i 5; i) { delay_ms(500); dr_buzzer_beep(200); } }else { //显示电机未学习 dwin_show_fault_flag ~0x40;//表示检查未通过未检查 dwin_show_fault_flag | 0x04; uint8 data[8] {0}; data[0] 0xAA; data[1] 0x55; data[2] 0xBB; data[3] dwin_show_fault_flag; dr_can_sendExtFrame(DR_CAN_CH_1, 0x111, data, 8);//发送迪文屏错误显示 } } /** * 无刷行走电机报警及CAN初始化 */ void drdr_hw_initWalkAqmd(DR_GPIO_InitTypeDef _brushless_power_gpio) { DR_GPIO_InitTypeDef can1_tx_gpio, can1_rx_gpio; DR_GPIO_InitTypeDef can2_tx_gpio, can2_rx_gpio; rcu_periph_clock_enable(_brushless_power_gpio.GPIO_CLK); brushless_power_gpio.GPIO_Pin _brushless_power_gpio.GPIO_Pin; brushless_power_gpio.GPIO_Port _brushless_power_gpio.GPIO_Port; can1_tx_gpio.GPIO_CLK RCU_GPIOA; can1_tx_gpio.GPIO_Port GPIOA; can1_tx_gpio.GPIO_Pin GPIO_PIN_12; can1_rx_gpio.GPIO_CLK RCU_GPIOA; can1_rx_gpio.GPIO_Port GPIOA; can1_rx_gpio.GPIO_Pin GPIO_PIN_11; can2_tx_gpio.GPIO_CLK RCU_GPIOB; can2_tx_gpio.GPIO_Port GPIOB; can2_tx_gpio.GPIO_Pin GPIO_PIN_13; can2_rx_gpio.GPIO_CLK RCU_GPIOB; can2_rx_gpio.GPIO_Port GPIOB; can2_rx_gpio.GPIO_Pin GPIO_PIN_12; gpio_mode_set(brushless_power_gpio.GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, brushless_power_gpio.GPIO_Pin); gpio_output_options_set(brushless_power_gpio.GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, brushless_power_gpio.GPIO_Pin); dr_gpio_bit_set(brushless_power_gpio.GPIO_Port, brushless_power_gpio.GPIO_Pin);//set 上电行走电机驱动器 //无刷电机控制 CAN初始化 drdr_can_init(DR_CAN_CH_2); dr_can_init(DR_CAN_CH_2, can2_tx_gpio, GPIO_AF_9, can2_rx_gpio, GPIO_AF_9, DR_CAN_BAUDRATE_500); dr_can_addRXStdCallback(DR_CAN_CH_2, AQMD_BRUSHLESS_CAN_ID_RESP, CLSX_BRUSHLESS_AQMD_CAN_ISR); drdr_hw_stopWalk(); drdr_brushless_aqmd_task_init(); } /** * 开启行走电机驱动器 */ void drdr_hw_openWalkAqmd(void){ dr_gpio_bit_set(brushless_power_gpio.GPIO_Port, brushless_power_gpio.GPIO_Pin); DRDR_dlyHMSM(0, 0, 0, 50); } /** * 关闭行走电机驱动器 */ void drdr_hw_closeWalkAqmd(void){ drdr_hw_stopWalkAqmd(); dr_gpio_bit_reset(brushless_power_gpio.GPIO_Port, brushless_power_gpio.GPIO_Pin); DRDR_dlyHMSM(0, 0, 0, 50); } /** * 前进 */ void drdr_hw_brushlessForwardAqmd(){ _brushless_aqmd_dir AQMD_BRUSHLESS_DIR_FORWARD; } /** * 后退 */ void drdr_hw_brushlessBackwardAqmd(){ _brushless_aqmd_dir AQMD_BRUSHLESS_DIR_BACKWARD; } /** * duty_cycle 驱动行走电机的占空比万分之。。线性转化也可以直接输入速度控制这里是为了兼容其他电机 */ void drdr_hw_setWalkSpeedAqmd(uint16 duty_cycle) { int16 brushless_motor_freq 0; if(2 OSPrioCur || 9 OSPrioCur) { brushless_motor_freq duty_cycle * 1150 / 10000; drdr_hw_brushless_aqmdFreq(brushless_motor_freq); } } /** * 停止行走无刷电机 */ void drdr_hw_stopWalkAqmd(void) { _brushless_aqmd_dir AQMD_BRUSHLESS_DIR_HALT; drdr_hw_brushless_aqmdStop(); drdr_hw_brushless_aqmdFreq(0); DRDR_dlyHMSM(0, 0, 0, 100); } /** * 初始化 行走电机处理任务 */ void drdr_brushless_aqmd_task_init( void ) { uint8 err; OSTaskCreateExt( drdr_brushless_aqmd_task, NULL, CLSX_BRUSHLESS_TASK_STK[ CLSX_BRUSHLESS_TASK_STK_SIZE-1 ], CLSX_BRUSHLESS_TASK_PRIO, CLSX_BRUSHLESS_TASK_PRIO, CLSX_BRUSHLESS_TASK_STK[ 0 ], CLSX_BRUSHLESS_TASK_STK_SIZE, NULL, OS_TASK_OPT_STK_CHK| OS_TASK_OPT_STK_CLR ); #if (OS_TASK_NAME_EN 0) OSTaskNameSet(CLSX_BRUSHLESS_TASK_PRIO, brushless_aqmd, err); #endif // OS_TASK_NAME_EN } /** * 艾思控行走电机驱动器处理任务 */ void drdr_brushless_aqmd_task( void* p_arg ) { while( _brushless_task_flag ) { DRDR_dlyHMSM(0, 0, 0, 100); while(_wait_learning_flag) { DRDR_dlyHMSM(0, 0, 0, 100); } if(isDebugTask()) { drdr_taskinfo_printf(start drdr_brushless_aqmd_task\r\n); } drdr_hw_brushless_aqmdRun(aqmd_now_freq); drdr_hw_aqmd_get_info(); if(isDebugTask()) { drdr_taskinfo_printf(finish drdr_brushless_aqmd_task\r\n); } } while(TRUE) { if(isDebugTask()) { DRDR_printf( drdr_brushless_aqmd_task stoped\r\n ); } DRDR_dlyHMSM( 0, 0, 2, 0); } }.h文件#ifndef _HW_AQMD_H_ #define _HW_AQMD_H_ #include clsk_lib_function.h //从机地址1~127在这设置. #define AQMD_BRUSHLESS_CAN_ID_NOTIFY 0x601 #define AQMD_BRUSHLESS_CAN_ID_RESP 0x581 /*/主站/客户端发送消息格式 _____________________________________________________________________________________________ | | | | | | | CAN标识符 | 数据字节0 | 数据字节1-2 | 数据字节3 | 数据字节4-7 | |---------------|---------------|---------------|---------------|---------------------------| | | | | | | | 0x600节点ID | 命令 | 索引号 | 子索引号 | 数据 | |_______________|_______________|_______________|_______________|__________________________*/ // 命令 #define WRITE_A_SINGLE_BYTE 0x2F //写单字节 数据前 1 字节 #define WRITE_DOUBLE_BYTES 0x2B //写双字节 数据前 2 字节 #define WRITE_THREE_BYTES 0x27 //写三字节 数据前 3 字节 #define WRITE_FOUR_BYTES 0x23 //写四字节 数据全有效 #define READ_BYTES 0x40 //读取数据 数据均无效 /*/从站/服务器应答消息格式 //相应 CAN 节点接收到消息后的应答格式如下 _____________________________________________________________________________________________ | | | | | | | CAN标识符 | 数据字节0 | 数据字节1-2 | 数据字节3 | 数据字节4-7 | |---------------|---------------|---------------|---------------|---------------------------| | | | | | | | 0x580节点ID | 状态 | 索引号 | 子索引号 | 数据/中止代码 | |_______________|_______________|_______________|_______________|__________________________*/ //状态码 #define DATA_LENGTH_1_BYTE 0x4F //数据长度为 1 字节 前 1 字节 #define DATA_LENGTH_2_BYTES 0x4B //数据长度为 2 字节 前 2 字节 #define DATA_LENGTH_3_BYTES 0x47 //数据长度为 3 字节 前 3 字节 #define DATA_LENGTH_4_BYTES 0x43 //数据长度为 4 字节 全有效 #define TRANSFER_SUCCESSFUL 0x60 //传送成功 均无效 #define TRANSFER_ABORTED 0x80 //传送中止 4 个字节为中止代码 //MODBUS寄存器地址REG_ADDR 对象字典索引号INDEX 对象字典子索引号SUB-INDEX //0x0000~0x0FFF 0x4000 REG_ADDR 0 //0x7000~0x7FFF REG_ADDR - 0x2000 0 //索引号 #define AQMD_REAL_TIME_CURRENT 0x4021 //实时电流数值乘以 0.01 为电流值单位为A。 #define AQMD_REAL_TIME_FREQ 0x4022 //实时换向频率转速-3276832767当0x0035寄存器为1时数值即为换向频率当0x0035寄存器为0时数值乘以0.1为换向频率单位为Hz换向频率除以电机极个数再乘以 20 为电机转速单位RPM。 #define AQMD_POSITION_CONTROL_COMPLETION_STATUS 0x4023 //位置控制完成状态 0, 1 0x03 0未完成 1完成 #define AQMD_REAL_TIME_POSITION_H 0x4024 //电机实时位置高半字 #define AQMD_REAL_TIME_POSITION_L 0x4025 //电机实时位置低半字-21474836482147483647 电机换向脉冲数 #define AQMD_REMAINING_COMPLETION_TIME_H 0x4026 //剩余完成时间高半字 #define AQMD_REMAINING_COMPLETION_TIME_L 0x4027 //剩余完成时间低半字04294967295 单位为 ms #define AQMD_INPUT_DUTY_CYCLE 0x402e //IN1 输入占空比 01000 0x03 数值乘以 0.1%为占空比 #define AQMD_INPUT_FREQUENCY 0x402f //IN1 输入频率 0100000 0x03 单位为 Hz #define AQMD_LOCKED_STATE 0x4032 //堵转状态 0未堵转 1正转堵转停止 2反转堵转停止 #define AQMD_ERROR_STATUS 0x4033 //错误状态 0~9 #define AQMD_MOTOR_SPEED 0x4034 //电机转速0~65535当0x0035寄存器为 1 时数值乘以10为转速当0x0035寄存器为0时数值即为转速单位为RPM。注需先通过0x0073和0x0074寄存器配置正确的电机极个数和减速比读取的转速才正确。 #define AQMD_MOTOR_SPEED_TEN_FLAG 0x4035 //转速是否需要乘以10 0数值即转速1数值乘以10为转速 #define AQMD_INTERNAL_TEMPERATURE 0x4037 //内部驱动电路温度 -400~1250 0x03 数值乘以 0.1℃为温度 #define AQMD_SUPPLY_VOLTAGE 0x4038 //电源电压 0~700 0x03 数值乘以 0.1V 为电压 #define AQMD_BUS_CURRENT 0x403a //母线电流 0~2000 0x03 数值乘以 0.01A 为母线电流 #define AQMD_BRUSHLESS_STOP 0x4040 //停止 0, 1, 2 0x06 0正常停止 1紧急制动 2自由停止 #define AQMD_SET_CURRENT 0x4041 //设定力矩控制电流 -800~800 0x06 数值乘以0.01 为电流单位A #define AQMD_SET_DUTY_CYCLE 0x4042 //设定占空比 -1000~1000 0x06 数值乘以 0.1%为目标占空比 #define AQMD_SET_TARGET_FREQ 0x4043 //设定速度闭环控制目标速度换向频率 -32768~32767 0x06 数值乘以0.1 为目标换向频率单位为Hz #define AQMD_SET_MOTOR_POLES_NUM 0X4073 //设定电机极个数电机极个数通常为2的倍数 #define AQMD_SET_CANBAUDRATE 0x4122 //设定CAN波特率 010kbps 120kbps 250kbps 3125kbps 4250kbps 5500kbps 6800kbps 71Mbps #define AQMD_LEARN_MOTOR 0x40e1 //电机学习 0未学习 1开始电机学习/学习中 #define AQMD_LEARN_MOTOR_STATUS 0x4075 //电机学习状态 0未学习 1已学习 #define AQMD_MAXIMUM_ACCELERATION 0x4062 //速度闭环控制、位置闭环控制最大加速加速度 数值乘以 0.1为换向频率最大增大速度单位为 Hz/s #define AQMD_DEFAULT_ACCELERATION 0x4063 //上电时默认速度闭环/位置闭环控制加速加速度 数值乘以 0.1为换向频率最大增大速度单位为 Hz/s #define AQMD_MAXIMUM_DECELERATION_ACCELERATION 0x4064 //速度闭环控制、位置闭环控制最大减速加速度 数值乘以 0.1为换向频率最大增大速度单位为 Hz/s #define AQMD_DEFAULT_DECELERATION_ACCELERATION 0x4065 //上电时默认速度闭环/位置闭环控制减速加速度 数值乘以 0.1为换向频率最大增大速度单位为 Hz/s #define AQMD_MAX_TIME_FREQ 0x4066 //速度闭环控制、位置闭环控制最大速度(换向频率) 数值乘以 0.1 为换向频率单位为 Hz #define AQMD_DEFAULT_TIME_FREQ 0x4067 //上电时速度闭环控制/位置闭环控制默认速度(换向频率) 数值乘以 0.1 为换向频率单位为 Hz #define AQMD_RATED_CURRENT_OF_MOTOR 0x406a //电机额定电流 数值乘以 0.01 为电流值单位为 A #define AQMD_MAXIMUM_LOAD_CURRENT_OF_MOTOR 0x406b //电机最大负载电流 数值乘以 0.01 为电流值单位为 A #define AQMD_SPEED_CLOSED_LOOP_CONTROL_ALGORITHM 0x4070 //速度闭环控制算法 0:速度闭环控制 1:时间-位置闭环控制 2:时间-位置速率控制 #define AQMD_POSITION_CLOSED_LOOP_ALLOWS_ERROR 0x4071 //位置闭环控制允许误差 #define AQMD_COMMUNICATION_INT_BRAKING 0x4095 //通讯中断停止时间 数值乘以 0.1 为通讯中断停止时间单位为s Communication interruption braking time #define AQMD_DISABLE_BUZZER_ALARM 0x4099 //禁用报警 0:不禁用 1:禁用 #define AQMD_SAVE_MOTOR_CONFIG_PARAMETER 0x4160 //存储电机配置参数 #define AQMD_SAVE_SYSTEM_CONFIG_PARAMETER 0x4180 //存储系统配置参数 #define AQMD_SAVE_PID_CONFIG_PARAMETER 0x41c0 //存储闭环调速PID参数 /////////读取相关信息的地址定义/////////// /* * 无刷行走电机读取信息结构体 */ typedef struct{ BrushlessMotorDriverLockedStatus aqmd_locked_status; //堵转状态 0x32 BrushlessMotorDriverErrorStatus aqmd_error_status; //驱动器错误状态字 0x33 uint16 aqmd_out_voltage; //电源电压0~7000.1V //0x38 uint16 aqmd_out_current; //实时电流040000.01A//0x21 uint16 aqmd_rpm_ten_flag; //转速是否需要乘以10 //0x35 uint16 aqmd_actual_rpm; //电机转速RPM //0x34 // float aqmd_actual_freq; //实时换向频率转速//0x22 // uint16 aqmd_bus_current; //母线电流0~20000.01A //0x3a int16 aqmd_temperature; //温度-400~12500.1℃ //0x37 uint16 aqmd_learn_status; //电机学习状态 //0x75 } AQMD_INFO; /* * 无刷行走电机CAN波特率参数枚举 */ typedef enum { AQMD_CAN_BAUDRATE_10 0, //10kbps AQMD_CAN_BAUDRATE_20 1, //20kbps AQMD_CAN_BAUDRATE_50 2, //50kbps AQMD_CAN_BAUDRATE_125 3, //125kbps AQMD_CAN_BAUDRATE_250 4, //250kbps AQMD_CAN_BAUDRATE_500 5, //500kbps(电机默认值) AQMD_CAN_BAUDRATE_800 6, //800kbps AQMD_CAN_BAUDRATE_1000 7 //1Mbps } AQMD_CanBaudrate; /* * 无刷电机转动方向 */ typedef enum{ AQMD_BRUSHLESS_DIR_UNDEFINED 0, // 不确认的 AQMD_BRUSHLESS_DIR_HALT 1, // 停止 AQMD_BRUSHLESS_DIR_FORWARD 2, // 正转 AQMD_BRUSHLESS_DIR_BACKWARD 3, // 反转 } AQMD_WalkDir; //**************设置相关信息类数据******************** /** * 设置电机停止 */ void drdr_hw_walk_aqmdStop(); /** * 设置波特率 */ void drdr_hw_walk_aqmdBaudrate(AQMD_CanBaudrate can_baudrate); /** * 读取电机学习结果 */ void drdr_hw_walk_aqmdReadLearnMotor(); /** * 无刷行走电机配置初始化 */ void drdr_hw_initAqmdWalkConfig(void); /** * 无刷行走电机报警及CAN初始化 */ void drdr_hw_initWalkAqmd(PY_GPIO_InitTypeDef _walk_power_gpio); /** * 开启行走电机驱动器 */ void drdr_hw_openWalkAqmd(void); /** * 关闭行走电机驱动器 */ void drdr_hw_closeWalkAqmd(void); /** * 前进 */ void drdr_hw_walkForwardAqmd(); /** * 后退 */ void drdr_hw_walkBackwardAqmd(); /** * duty_cycle 驱动行走电机的占空比万分之。。线性转化 */ void drdr_hw_setWalkSpeedAqmd(uint16 duty_cycle); /** * 停止行走无刷电机 */ void drdr_hw_stopWalkAqmd(void); #endif // _HW_AQMD_H_

相关新闻

PAM8124与MKV46F256VLH16构建高效D类音频放大系统

PAM8124与MKV46F256VLH16构建高效D类音频放大系统

2026/7/11 5:52:23

1. 项目概述:打造高效音频放大系统PAM8124与MKV46F256VLH16的组合为音频爱好者提供了一个高性能的D类音频放大解决方案。这个系统特别适合需要高保真音质和高效能转换的应用场景,比如便携式音响系统、车载音频设备或智能家居音响。PAM8124作为Diodes公司…

加密压缩包密码恢复实战:ArchivePasswordTestTool工具原理与应用

加密压缩包密码恢复实战:ArchivePasswordTestTool工具原理与应用

2026/7/11 5:52:23

1. 项目概述:当加密压缩包成为“数字孤岛”你有没有遇到过这种情况?几年前备份的重要资料,为了安全加了密码,结果现在连自己都忘了密码是什么。或者,同事、朋友发来一个加密的压缩包,密码却忘了告诉你。那个…

kimi k2.6偶发故障排查:从电源相位噪声到OTP状态机的系统级调试

kimi k2.6偶发故障排查:从电源相位噪声到OTP状态机的系统级调试

2026/7/11 5:52:23

1. 标题背后的真实语境:当“我没辙了”成为技术人最诚实的自白“kimi k2.6 : 我真的没辙了”——这行字最近频繁出现在技术社区、开发者群聊和深夜朋友圈里,既不像产品公告,也不像教程标题,更像一句脱口而出的疲惫叹息。它没有主语…

参数权重失控?风格崩坏?——Midjourney提示词精准控制全链路拆解,含37组AB测试对比数据

参数权重失控?风格崩坏?——Midjourney提示词精准控制全链路拆解,含37组AB测试对比数据

2026/7/11 7:32:27

更多请点击: https://kaifayun.com 第一章:参数权重失控?风格崩坏?——Midjourney提示词精准控制全链路拆解,含37组AB测试对比数据 Midjourney的提示词解析机制并非线性加权,而是基于CLIP文本编码器与扩散…

2-(Pyridin-2-yldisulfanyl) ethyl methacrylate 功能单体,吡啶二硫基团用于高分子微球可逆表面修饰

2-(Pyridin-2-yldisulfanyl) ethyl methacrylate 功能单体,吡啶二硫基团用于高分子微球可逆表面修饰

2026/7/11 7:32:27

基本参数中文名称:2-(2-吡啶基二硫代)甲基丙烯酸乙酯英文名称:2-(Pyridin-2-yldisulfanyl)ethyl methacrylateCAS号:910128-59-5分子式:C₁₁H₁₃NO₂S₂分子量:255.36纯度:≥95%外观:淡黄色透…

Office 2021/365 安装排错:5种常见报错分析与KMS激活失败解决方案

Office 2021/365 安装排错:5种常见报错分析与KMS激活失败解决方案

2026/7/11 7:32:27

Office 2021/365 安装排错:5种常见报错分析与KMS激活失败解决方案1. 安装前的系统环境检查在部署Office套件前,确保系统环境符合要求是避免后续问题的关键步骤。根据微软官方技术文档,Office 2021/365需要Windows 10版本1909或更高版本&#…

精品课录播系统的技术架构与功能应用

精品课录播系统的技术架构与功能应用

2026/7/11 7:32:27

一、背景与需求课堂教学录制在最近几年已经变成了学校信息化建设里面比较常见的一个需求。不少学校现在面临着"一师一优课、一课一名师"这类政策上面的要求,需要把优秀教师的课堂教学过程给录制下来,作为优质资源去存储和共享。与此同时&#…

Origin科研绘图与数据分析全指南:安装配置、故障排查与期刊投稿规范

Origin科研绘图与数据分析全指南:安装配置、故障排查与期刊投稿规范

2026/7/11 7:32:27

1. Origin 是什么?为什么科研人绕不开它Origin 不是那种装完就扔在角落吃灰的软件,而是我实验室抽屉里常年备着三份安装包的“生产力刚需”——一份存U盘、一份压在笔记本底下、还有一份直接刻进移动硬盘。它不像 Python 那样靠代码堆砌功能,…

招投标公告结构化解析中的序列标注方案设计与工程实践

招投标公告结构化解析中的序列标注方案设计与工程实践

2026/7/11 7:22:27

在自然语言处理领域,命名实体识别(NER)是一项相对成熟的技术。但当将其应用于招投标公告解析这一垂直场景时,通用NER模型的表现往往难以达到工程可用标准。原因在于:招投标公告文本存在大量领域专有词汇、嵌套实体结构…

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南

2026/7/10 22:32:48

解锁AMD Ryzen处理器深层性能:SMU Debug Tool完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…

6个月转型AI工程师:实战路径与核心技能

6个月转型AI工程师:实战路径与核心技能

2026/7/9 18:28:30

1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公…

YOLOv5模型剪枝与量化实战:边缘设备部署优化

YOLOv5模型剪枝与量化实战:边缘设备部署优化

2026/7/10 6:57:56

1. 项目背景与核心价值在计算机视觉领域,YOLOv5因其出色的实时检测性能成为工业界宠儿。但当我们尝试将其部署到边缘设备(如树莓派、Jetson Nano或手机终端)时,立刻会遇到两个致命问题:模型体积庞大(原始YO…

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制

2026/7/11 0:02:03

WechatDecrypt技术解析:深入理解微信数据库AES-256-CBC解密机制 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 在数字隐私日益重要的今天,微信聊天记录作为个人数字资产的重要组成…

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 [特殊字符]

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 [特殊字符]

2026/7/11 0:02:03

5分钟搞定Kodi字幕难题:智能字幕插件让你追剧无忧 🎬 【免费下载链接】zimuku_for_kodi Kodi 插件,用于从「字幕库」网站下载字幕 项目地址: https://gitcode.com/gh_mirrors/zi/zimuku_for_kodi 还记得那个深夜吗?你刚下载…

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案

2026/7/11 0:02:03

PostgreSQL 备份与恢复实战:从 pg_dump 到时间点恢复的生产级方案 一、数据库备份最容易被忽略的问题,不是「有没有做备份」,而是「备份能不能恢复、恢复要多久、以及恢复后的数据对不对」 很多团队做数据库备份的方式是「写个 cron job&am…