以前调过好几款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_
爱思控无刷电机驱动器的软件驱动
发布时间:2026/7/11 5:52:20
以前调过好几款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_