爱思控无刷电机驱动器的软件驱动
以前调过好几款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 //实时换向频率(转速)-32768~32767当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 //电机实时位置低半字-2147483648~2147483647 电机换向脉冲数 #define AQMD_REMAINING_COMPLETION_TIME_H 0x4026 //剩余完成时间高半字 #define AQMD_REMAINING_COMPLETION_TIME_L 0x4027 //剩余完成时间低半字0~4294967295 单位为 ms #define AQMD_INPUT_DUTY_CYCLE 0x402e //IN1 输入占空比 0~1000 0x03 数值乘以 0.1%为占空比 #define AQMD_INPUT_FREQUENCY 0x402f //IN1 输入频率 0~100000 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波特率 0:10kbps 1:20kbps 2:50kbps 3:125kbps 4:250kbps 5:500kbps 6:800kbps 7:1Mbps #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~700)(0.1V) //0x38 uint16 aqmd_out_current; //实时电流(0~4000)(0.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~2000)(0.01A) //0x3a int16 aqmd_temperature; //温度(-400~1250)(0.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_