使用STM32H723VGT6芯片驱动达妙电机

首先,安装H7的pack包:

Arm Keil | Keil STM32H7xx_DFP

在这个网站中下载例如这个版本的pack包:

下载完成后,双击pack文件进行安装,会自动安装到keil的安装路径中,再电机Next:

安装完成,点击Finish:


接下来就可以开发基于STM32H7的工程了,基于达妙官方开源的stm32例程【dm_ctrl(h7 fdcan)v1.1 裸机】进行研究:

官方文档:‍​​‌​​⁠‌‍​​‌‌‌‌‌‍​​⁠⁠​​​​⁠⁠​‌‌​‍‌​‍​‌2. 达妙电机上手流程(二)-使用开发板控制电机 - 飞书云文档

查看文档中的MIT模式控制,注意motor[Motor1].id我的设置为了0x03:

cpp 复制代码
/* 在 dm_motor_ctrl.c 文件中 */
void dm_motor_init(void)
{
    memset(&motor[Motor1], 0, sizeof(motor[Motor1]));    // 初始化Motor1电机结构体

    // 设置Motor1的电机信息
    motor[Motor1].id = 0x03;
    motor[Motor1].mst_id = 0x00;        // 实际没有用上,只做标识作用
    motor[Motor1].tmp.read_flag = 1;
    motor[Motor1].ctrl.mode     = mit_mode;    // 选择 MIT 模式
    motor[Motor1].ctrl.vel_set  = 1.0f;        // 设置速度为 1
    motor[Motor1].ctrl.pos_set  = 0.0f;
    motor[Motor1].ctrl.tor_set  = 0.0f;
    motor[Motor1].ctrl.cur_set  = 0.0f;
    motor[Motor1].ctrl.kp_set   = 0.0f;        
    motor[Motor1].ctrl.kd_set   = 1.0f;        // 设置 Kd 为 1
    // DM4310的 PMAX VMAX TMAX
    motor[Motor1].tmp.PMAX      = 12.5f;
    motor[Motor1].tmp.VMAX      = 30.0f;
    motor[Motor1].tmp.TMAX      = 10.0f;
}


/* 在 main.c 文件中*/
int main(void)
{
    /* 截取添加的代码如下 */
    power(1);        // 打开开发板的可控电源接口
    HAL_Delay(1000); // 等待电机上电自检通过
    
    bsp_fdcan_set_baud(&hfdcan1, CAN_CLASS, CAN_BR_1M);      // 设置CAN为经典模式 波特率为1M
    bsp_can_init();
    dm_motor_init();
    HAL_Delay(10);
    /* 往电机的寄存器里面写入MIT模式 */
    write_motor_data(motor[Motor1].id, 10, mit_mode, 0, 0, 0);    // 修改电机为MIT模式
    HAL_Delay(100);
    save_motor_data(motor[Motor1].id, 10);        // 保存电机参数
    HAL_Delay(100);
    dm_motor_enable(&hfdcan1, &motor[Motor1]);    // 使能电机
    HAL_Delay(1000);
    
    HAL_TIM_Base_Start_IT(&htim3);                // 开启1ms定时器中断用于发送can命令
    while (1)
    {

    }
}

// 1ms 定时器中断函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM3) {
        dm_motor_ctrl_send(&hfdcan1, &motor[Motor1]);
    }
}

/* 在 dm_motor_ctrl.c 文件中 */
// 接收中断回调 处理电机回传的信息,默认master id为0,所以这里 rec_id = 0
void fdcan1_rx_callback(void)
{
    uint16_t rec_id;
    uint8_t rx_data[8] = {0};
    fdcanx_receive(&hfdcan1, &rec_id, rx_data);
    switch (rec_id)
    {
        case 0x00: dm_motor_fbdata(&motor[Motor1], rx_data); receive_motor_data(&motor[Motor1], rx_data); break;
    }
}

将上面代码下载入单片机,可以观察到电机匀速旋转


接下来,我们再来基于MIT 模式来使电机按照指定轨迹运动:

电机 MIT模式的控制框图:

给出MIT 模式用法说明:

  1. kp=0kd≠0 时,给定 v_des 即可实现匀速转动。匀速转动过程中存在静差,另外 kd 不宜过大,kd 过大时会引起震荡。

  2. kp=0kd=0 时,给定 t_ff 即可实现给定扭矩输出。在该情况下,电机会持续输出一个恒定力矩。但是当电机空转或负载较小时,如果给定 t_ff 较大,电机会持续加速,直到加速到最大速度,这时也仍然达不到目标力矩 t_ff

  3. kp≠0,kd=0 时,会引起震荡。即对位置进行控制时,kd不能赋0,否则会造成电机震荡,甚至失控。

  4. kp≠0,kd≠0 时,有多种情况,这里下面简单介绍两种情况。

  • 当期望位置 p_des 为常量,期望速度 v_des 为0时,可实现定点控制,在这个过程中,实际位置趋近于p_des ,实际速度 dθm 趋近于0。

  • p_des 是随时间变化的连续可导函数时,同时 v_desp_des 的导数,可实现位置跟踪和速度跟踪,即按照期望速度旋转期望角度。

以下是基于达妙H7开发板的一个简单例子:

cpp 复制代码
// mit 模式控制函数
void mit_ctrl(hcan_t* hcan, motor_t *motor, uint16_t motor_id, float pos, float vel,float kp, float kd, float tor)
{
    uint8_t data[8];
    uint16_t pos_tmp,vel_tmp,kp_tmp,kd_tmp,tor_tmp;
    uint16_t id = motor_id + MIT_MODE;

    pos_tmp = float_to_uint(pos, -motor->tmp.PMAX, motor->tmp.PMAX, 16);
    vel_tmp = float_to_uint(vel, -motor->tmp.VMAX, motor->tmp.VMAX, 12);
    tor_tmp = float_to_uint(tor, -motor->tmp.TMAX, motor->tmp.TMAX, 12);
    kp_tmp  = float_to_uint(kp,  KP_MIN, KP_MAX, 12);
    kd_tmp  = float_to_uint(kd,  KD_MIN, KD_MAX, 12);

    data[0] = (pos_tmp >> 8);
    data[1] = pos_tmp;
    data[2] = (vel_tmp >> 4);
    data[3] = ((vel_tmp&0xF)<<4)|(kp_tmp>>8);
    data[4] = kp_tmp;
    data[5] = (kd_tmp >> 4);
    data[6] = ((kd_tmp&0xF)<<4)|(tor_tmp>>8);
    data[7] = tor_tmp;
    
    fdcanx_send_data(hcan, id, data, 8);
}

基于这个mit_ctrl,我们来修改原先的main函数,补充如下代码:

cpp 复制代码
// 电机控制变量
static float time = 0.0f;       // 时间累积
static float kp = 1.0f;         // 比例增益
static float kd = 1.0f;         // 微分增益
static float tor_set = 0.0f;    // 力矩设定值
static float pos_set = 0.0f;    // 位置设定值
static float vel_set = 0.0f;    // 速度设定值
// 轨迹生成参数
const float amplitude = 1.0f;   // 正弦波幅度
const float frequency = 1.0f;   // 正弦波频率(Hz)
const float PI = 3.1415926f;    // π值


// 1ms 定时器中断函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */
//	if (htim->Instance == TIM3) {
//		
//		read_all_motor_data(&motor[Motor1]);
//		
//		if(motor[Motor1].tmp.read_flag == 0)
//			dm_motor_ctrl_send(&hfdcan1, &motor[Motor1]);	
//	}
	
	if (htim->Instance == TIM3) {
       time=time+0.001f;     
        kp=1.0f;  
        kd=1.0f;  
        tor_set=0.0f;  
        pos_set=sin(2*3.1415926f*1.0f*time);  
        vel_set=2*3.1415926f*1.0f*cos(2*3.1415926f*1.0f*time);  
        mit_ctrl(&hfdcan1, &motor[Motor1], 3, pos_set, vel_set, kp, kd,tor_set); //MIT模式发送力矩;  // 电机ID: 3  
    }
	
}

将该代码下载入H7单片机,可以观察到电机按照指定轨迹运转!

相关推荐
嘿嘿嘿x34 小时前
F280025的时钟设置
单片机·嵌入式硬件
GilgameshJSS4 小时前
STM32H743-ARM例程30-Modbus
c语言·arm开发·stm32·单片机·嵌入式硬件
nassi_5 小时前
开发板网络配置
linux·网络·嵌入式硬件
申克Lab5 小时前
STM32 系统定时器(精准延迟)
stm32·单片机·嵌入式硬件
瑞江无限5 小时前
南麟NP3401MR-M-G技术规格与应用全解析
单片机·嵌入式硬件
kuan_li_lyg5 小时前
笛卡尔坐标机器人控制的虚拟前向动力学模型
人工智能·stm32·机器人·机械臂·动力学·运动学·导纳控制
典则6 小时前
STM32FreeRtos入门(五)——同步互斥与通信
java·jvm·stm32
qq_401700416 小时前
自恢复保险丝
单片机·嵌入式硬件
三佛科技-134163842126 小时前
暖手宝方案开发,暖手宝MCU控制方案开发设计
单片机·嵌入式硬件·智能家居·pcb工艺