小米电机CyberGear STM32HAL 使用指南

这篇具有很好参考价值的文章主要介绍了小米电机CyberGear STM32HAL 使用指南。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

小米电机CyberGear STM32HAL 使用指南

在23年8月底 小米正式发售了用于其铁蛋2代的小米“微电机”,准确来说就是目前机器人方向流行的关节电机。根据其参数可知,在同等重量下,小米此款电机不仅在额定扭矩上达到了4NM,峰值扭矩达到了12NM的水平,同时在价格上也基本上算是全网最低。笔者也是通过预购,在发售之初拿到了“年轻人的第一个微电机”。故想发出此文,和各位一起,通过最简单,最流行的硬件,完成对电机的基础控制。

硬件介绍

由于小米电机采用了当前在关节电机行业上比较流行的TX30 2+2的接口,通过一个接口就可以同时完成信号和供电的传输,使得线路连接非常简单,且几乎不存在反插问题(CAN信号线需要额外注意与控制板的连接顺序)。但是此种连接方式还是有些细节方面的问题,比如插头连接松动,端子容易虚焊或损坏,以及价格偏贵等问题,故在使用此种插头时,一定要确保连接可靠,同时can信号线最好需要严格双绞以保证型号传输的稳定性。
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

主控方面,笔者采用的是自己设计的用来做其他项目的F103C6T6主控,包含了采用VP230的can通信硬件电路,故使用此板作为电机控制实验的主控板,其中CAN接口采用2.54 3P的接口。
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

至此,完成控制电路的硬件连接。

软件编写

新建一个工程,采用CUBEMX进行工程建立,极大地提高了效率,降低了学习成本。
选择了对应芯片之后,完成基础配置:外置晶振,DEBUG,UART,TIM2定时器(2ms中断)以及CAN通信:

时钟配置(8MHz外置晶振,主控倍频至72MHz)
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

can配置(1M波特率,CAN接收中断)
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

uart配置(115200波特率,DMA接收中断)
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

TIM配置(2ms定时中断)
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机
生成工程
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

其他
自行配置LED GPIO等 方便调试

首次生成工程编译通过之后,进行系统初始化:

  /* USER CODE BEGIN 2 */
	//CAN过滤器初始化
	CAN_FilterTypeDef can_filter_st;
    can_filter_st.FilterActivation = ENABLE;
    can_filter_st.FilterMode = CAN_FILTERMODE_IDMASK;
    can_filter_st.FilterScale = CAN_FILTERSCALE_32BIT;
    can_filter_st.FilterIdHigh = 0x0000;
    can_filter_st.FilterIdLow = 0x0000;
    can_filter_st.FilterMaskIdHigh = 0x0000;
    can_filter_st.FilterMaskIdLow = 0x0000;
    can_filter_st.FilterBank = 0;
    can_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0;
    can_filter_st.SlaveStartFilterBank = 14;
    HAL_CAN_ConfigFilter(&hcan, &can_filter_st);
    HAL_CAN_Start(&hcan);
    HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
    
    HAL_TIM_Base_Start_IT(&htim2);//定时中断初始化
  /* USER CODE END 2 */

导入笔者编写的cybergear.c/.h文件,并加入编译目录中(不会的话移步其他人的基础教程)

小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

至此,完成控制电机的全部准备工作。

控制电机:

对于控制电机的命令,大致分为三种:

  1. 启停控制: 需要让电机运动起来,首先需通过命令要开启电机,电机开启之后会有轻微震动。
  2. 运动控制: 使用运控指令完成对电机的控制,一般将其放入一个中断内定时调用,以期精细控制并及时得到回传数据。
  3. 数据读取: 一般用于更改电机的参数,一般在首次使用或者更换使用场景,调整电机性能时对电机使用。

调试电机:

1.调用初始化函数,设置电机工作模式,使能电机

  /* USER CODE BEGIN 2 */
   	HAL_Delay(500);              //一定时间延时 等待电机初始化完成 
	init_cybergear(&mi_motor[0], 0x7F, Motion_mode);//小米电机 启动!
  /* USER CODE END 2 */

2.调用运动控制函数(放入主循环或者中断中),控制电机转动

  /* USER CODE BEGIN 3 */
      motor_controlmode(&mi_motor[0], 0, 0, 0, 0 , 0);  
      HAL_Delay(2);
  /* USER CODE END 3 */

运控函数使用可通过官方说明书给出的传递函数作为参考,完成对电机的控制。
小米电机CyberGear STM32HAL 使用指南,stm32,嵌入式硬件,单片机

其中,有三种典型控制方法:

  • 力矩控制:仅输入力矩,其他均为0,即为纯力矩模式,单位为NM,注意在无负载情况下,很容易达到最大转速;
  • 速度控制:输入期望速度,kd,其他均为0,即为速度控制模式,其中kd大小影响其响应速度,一般可取0.1-1;
  • 位置控制:输入期望位置,kp,kd,其他均为0,即为位置控制模式,其中kp大小影响响应速度(到达位置快慢),kd大小影响着电机阻尼,过小会震荡,过大电机会震动明显。kp一般1-10,kd一般0.5左右。
  • 其他控制方式就有待广大爱好者发掘,这里不再深究。

踩坑:

由于笔者在首次调试的时候没有官方can转usb调试器,无法通过官方上位机调试故只能盲调,控制电机几经失败后发现小米电机出厂ID为极其阴间的0X7F,其他踩坑暂无。

最后:

感谢广大群友相助,在此为两大关节电机群打个广告:
174204312 达妙电机交流群
869911140 大然电机交流群
特别的,借鉴并参考了乌苏哥写的小米电机STM32库函数
本文也是笔者首次编写,如有不足,错误之处,烦请各位大佬指正。

附上代码

cybergear.c

/**
  ****************************(C)SWJTU_ROBOTCON****************************
  * @file       cybergear.c/h
  * @brief      小米电机函数库
  * @note       
  * @history
  *  Version    Date            Author          Modification
  *  V1.0.0     1-10-2023       ZDYukino        1. done
  *
  @verbatim
  =========================================================================
  =========================================================================
  @endverbatim
  ****************************(C)SWJTU_ROBOTCON****************************
  **/
#include "main.h"
#include "can.h"
#include "cybergear.h"

CAN_RxHeaderTypeDef rxMsg;//发送接收结构体
CAN_TxHeaderTypeDef txMsg;//发送配置结构体
uint8_t rx_data[8];       //接收数据
uint32_t Motor_Can_ID;    //接收数据电机ID
uint8_t byte[4];          //转换临时数据
uint32_t send_mail_box = {0};//NONE
    
#define can_txd() HAL_CAN_AddTxMessage(&hcan, &txMsg, tx_data, &send_mail_box)//CAN发送宏定义

MI_Motor mi_motor[4];//预先定义四个小米电机

/**
  * @brief          浮点数转4字节函数
  * @param[in]      f:浮点数
  * @retval         4字节数组
  * @description  : IEEE 754 协议
  */
static uint8_t* Float_to_Byte(float f)
{
	unsigned long longdata = 0;
	longdata = *(unsigned long*)&f;       
	byte[0] = (longdata & 0xFF000000) >> 24;
	byte[1] = (longdata & 0x00FF0000) >> 16;
	byte[2] = (longdata & 0x0000FF00) >> 8;
	byte[3] = (longdata & 0x000000FF);
	return byte;
}

/**
  * @brief          小米电机回文16位数据转浮点
  * @param[in]      x:16位回文
  * @param[in]      x_min:对应参数下限
  * @param[in]      x_max:对应参数上限
  * @param[in]      bits:参数位数
  * @retval         返回浮点值
  */
static float uint16_to_float(uint16_t x,float x_min,float x_max,int bits)
{
    uint32_t span = (1 << bits) - 1;
    float offset = x_max - x_min;
    return offset * x / span + x_min;
}

/**
  * @brief          小米电机发送浮点转16位数据
  * @param[in]      x:浮点
  * @param[in]      x_min:对应参数下限
  * @param[in]      x_max:对应参数上限
  * @param[in]      bits:参数位数
  * @retval         返回浮点值
  */
static int float_to_uint(float x, float x_min, float x_max, int bits)
{
  float span = x_max - x_min;
  float offset = x_min;
  if(x > x_max) x=x_max;
  else if(x < x_min) x= x_min;
  return (int) ((x-offset)*((float)((1<<bits)-1))/span);
}

/**
  * @brief          写入电机参数
  * @param[in]      Motor:对应控制电机结构体
  * @param[in]      Index:写入参数对应地址
  * @param[in]      Value:写入参数值
  * @param[in]      Value_type:写入参数数据类型
  * @retval         none
  */
static void Set_Motor_Parameter(MI_Motor *Motor,uint16_t Index,float Value,char Value_type){
	uint8_t tx_data[8];
	txMsg.ExtId = Communication_Type_SetSingleParameter<<24|Master_CAN_ID<<8|Motor->CAN_ID;
	tx_data[0]=Index;
	tx_data[1]=Index>>8;
	tx_data[2]=0x00;
	tx_data[3]=0x00;
	if(Value_type == 'f'){
		Float_to_Byte(Value);
		tx_data[4]=byte[3];
		tx_data[5]=byte[2];
		tx_data[6]=byte[1];
		tx_data[7]=byte[0];		
	}
	else if(Value_type == 's'){
		tx_data[4]=(uint8_t)Value;
		tx_data[5]=0x00;
		tx_data[6]=0x00;
		tx_data[7]=0x00;				
	}
	can_txd();	
}

/**
  * @brief          提取电机回复帧扩展ID中的电机CANID
  * @param[in]      CAN_ID_Frame:电机回复帧中的扩展CANID   
  * @retval         电机CANID
  */
static uint32_t Get_Motor_ID(uint32_t CAN_ID_Frame)
{
	return (CAN_ID_Frame&0xFFFF)>>8;
}

/**
  * @brief          电机回复帧数据处理函数
  * @param[in]      Motor:对应控制电机结构体   
  * @param[in]      DataFrame:数据帧
  * @param[in]      IDFrame:扩展ID帧
  * @retval         None
  */
static void Motor_Data_Handler(MI_Motor *Motor,uint8_t DataFrame[8],uint32_t IDFrame)
{	
		Motor->Angle=uint16_to_float(DataFrame[0]<<8|DataFrame[1],MIN_P,MAX_P,16);
		Motor->Speed=uint16_to_float(DataFrame[2]<<8|DataFrame[3],V_MIN,V_MAX,16);			
		Motor->Torque=uint16_to_float(DataFrame[4]<<8|DataFrame[5],T_MIN,T_MAX,16);				
		Motor->Temp=(DataFrame[6]<<8|DataFrame[7])*Temp_Gain;
		Motor->error_code=(IDFrame&0x1F0000)>>16;	
}

/**
  * @brief          小米电机ID检查
  * @param[in]      id:  控制电机CAN_ID【出厂默认0x7F】
  * @retval         none
  */
void chack_cybergear(uint8_t ID)
{
    uint8_t tx_data[8] = {0};
    txMsg.ExtId = Communication_Type_GetID<<24|Master_CAN_ID<<8|ID;
    can_txd();
}

/**
  * @brief          使能小米电机
  * @param[in]      Motor:对应控制电机结构体   
  * @retval         none
  */
void start_cybergear(MI_Motor *Motor)
{
    uint8_t tx_data[8] = {0}; 
    txMsg.ExtId = Communication_Type_MotorEnable<<24|Master_CAN_ID<<8|Motor->CAN_ID;
    can_txd();
}

/**
  * @brief          停止电机
  * @param[in]      Motor:对应控制电机结构体   
  * @param[in]      clear_error:清除错误位(0 不清除 1清除)
  * @retval         None
  */
void stop_cybergear(MI_Motor *Motor,uint8_t clear_error)
{
	uint8_t tx_data[8]={0};
	tx_data[0]=clear_error;//清除错误位设置
	txMsg.ExtId = Communication_Type_MotorStop<<24|Master_CAN_ID<<8|Motor->CAN_ID;
    can_txd();
}

/**
  * @brief          设置电机模式(必须停止时调整!)
  * @param[in]      Motor:  电机结构体
  * @param[in]      Mode:   电机工作模式(1.运动模式Motion_mode 2. 位置模式Position_mode 3. 速度模式Speed_mode 4. 电流模式Current_mode)
  * @retval         none
  */
void set_mode_cybergear(MI_Motor *Motor,uint8_t Mode)
{	
	Set_Motor_Parameter(Motor,Run_mode,Mode,'s');
}

/**
  * @brief          电流控制模式下设置电流
  * @param[in]      Motor:  电机结构体
  * @param[in]      Current:电流设置
  * @retval         none
  */
void set_current_cybergear(MI_Motor *Motor,float Current)
{
	Set_Motor_Parameter(Motor,Iq_Ref,Current,'f');
}

/**
  * @brief          设置电机零点
  * @param[in]      Motor:  电机结构体
  * @retval         none
  */
void set_zeropos_cybergear(MI_Motor *Motor)
{
	uint8_t tx_data[8]={0};
	txMsg.ExtId = Communication_Type_SetPosZero<<24|Master_CAN_ID<<8|Motor->CAN_ID;
	can_txd();		
}

/**
  * @brief          设置电机CANID
  * @param[in]      Motor:  电机结构体
  * @param[in]      Motor:  设置新ID
  * @retval         none
  */
void set_CANID_cybergear(MI_Motor *Motor,uint8_t CAN_ID)
{
	uint8_t tx_data[8]={0};
	txMsg.ExtId = Communication_Type_CanID<<24|CAN_ID<<16|Master_CAN_ID<<8|Motor->CAN_ID;
    Motor->CAN_ID = CAN_ID;//将新的ID导入电机结构体
    can_txd();	
}
/**
  * @brief          小米电机初始化
  * @param[in]      Motor:  电机结构体
  * @param[in]      Can_Id: 小米电机ID(默认0x7F)
  * @param[in]      Motor_Num: 电机编号
  * @param[in]      mode: 电机工作模式(0.运动模式Motion_mode 1. 位置模式Position_mode 2. 速度模式Speed_mode 3. 电流模式Current_mode)
  * @retval         none
  */
void init_cybergear(MI_Motor *Motor,uint8_t Can_Id, uint8_t mode)
{
    txMsg.StdId = 0;            //配置CAN发送:标准帧清零 
    txMsg.ExtId = 0;            //配置CAN发送:扩展帧清零     
    txMsg.IDE = CAN_ID_EXT;     //配置CAN发送:扩展帧
    txMsg.RTR = CAN_RTR_DATA;   //配置CAN发送:数据帧
    txMsg.DLC = 0x08;           //配置CAN发送:数据长度
    
	Motor->CAN_ID=Can_Id;       //ID设置 
	set_mode_cybergear(Motor,mode);//设置电机模式
	start_cybergear(Motor);        //使能电机
}

/**
  * @brief          小米运控模式指令
  * @param[in]      Motor:  目标电机结构体
  * @param[in]      torque: 力矩设置[-12,12] N*M
  * @param[in]      MechPosition: 位置设置[-12.5,12.5] rad
  * @param[in]      speed: 速度设置[-30,30] rpm
  * @param[in]      kp: 比例参数设置
  * @param[in]      kd: 微分参数设置
  * @retval         none
  */
void motor_controlmode(MI_Motor *Motor,float torque, float MechPosition, float speed, float kp, float kd)
{   
    uint8_t tx_data[8];//发送数据初始化
    //装填发送数据
    tx_data[0]=float_to_uint(MechPosition,P_MIN,P_MAX,16)>>8;  
    tx_data[1]=float_to_uint(MechPosition,P_MIN,P_MAX,16);  
    tx_data[2]=float_to_uint(speed,V_MIN,V_MAX,16)>>8;  
    tx_data[3]=float_to_uint(speed,V_MIN,V_MAX,16);  
    tx_data[4]=float_to_uint(kp,KP_MIN,KP_MAX,16)>>8;  
    tx_data[5]=float_to_uint(kp,KP_MIN,KP_MAX,16);  
    tx_data[6]=float_to_uint(kd,KD_MIN,KD_MAX,16)>>8;  
    tx_data[7]=float_to_uint(kd,KD_MIN,KD_MAX,16); 
    
    txMsg.ExtId = Communication_Type_MotionControl<<24|float_to_uint(torque,T_MIN,T_MAX,16)<<8|Motor->CAN_ID;//装填扩展帧数据
    can_txd();
}

/*****************************回调函数 负责接回传信息 可转移至别处*****************************/
/**
  * @brief          hal库CAN回调函数,接收电机数据
  * @param[in]      hcan:CAN句柄指针
  * @retval         none
  */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);              //LED闪烁指示
    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxMsg, rx_data);//接收数据
	Motor_Can_ID=Get_Motor_ID(rxMsg.ExtId);//首先获取回传电机ID信息  
    switch(Motor_Can_ID)                   //将对应ID电机信息提取至对应结构体
    {
        case 0X7F:  
            if(rxMsg.ExtId>>24 != 0)               //检查是否为广播模式
                Motor_Data_Handler(&mi_motor[0],rx_data,rxMsg.ExtId);
            else 
                mi_motor[0].MCU_ID = rx_data[0];
            break;           
        default:
            break;		
    }
}

cybergear.h文章来源地址https://www.toymoban.com/news/detail-714527.html

/**
  ****************************(C)SWJTU_ROBOTCON****************************
  * @file       cybergear.c/h
  * @brief      小米电机函数库
  * @note       
  * @history
  *  Version    Date            Author          Modification
  *  V1.0.0     1-10-2023       ZDYukino        1. done
  *
  @verbatim
  =========================================================================
  =========================================================================
  @endverbatim
  ****************************(C)SWJTU_ROBOTCON****************************
  **/
#include "main.h"
#include "can.h"
//控制参数最值,谨慎更改
#define P_MIN -12.5f
#define P_MAX 12.5f
#define V_MIN -30.0f
#define V_MAX 30.0f
#define KP_MIN 0.0f
#define KP_MAX 500.0f
#define KD_MIN 0.0f
#define KD_MAX 5.0f
#define T_MIN -12.0f
#define T_MAX 12.0f
#define MAX_P 720
#define MIN_P -720
//主机CANID设置
#define Master_CAN_ID 0x00                      //主机ID
//控制命令宏定义
#define Communication_Type_GetID 0x00           //获取设备的ID和64位MCU唯一标识符
#define Communication_Type_MotionControl 0x01 	//用来向主机发送控制指令
#define Communication_Type_MotorRequest 0x02	//用来向主机反馈电机运行状态
#define Communication_Type_MotorEnable 0x03	    //电机使能运行
#define Communication_Type_MotorStop 0x04	    //电机停止运行
#define Communication_Type_SetPosZero 0x06	    //设置电机机械零位
#define Communication_Type_CanID 0x07	        //更改当前电机CAN_ID
#define Communication_Type_Control_Mode 0x12
#define Communication_Type_GetSingleParameter 0x11	//读取单个参数
#define Communication_Type_SetSingleParameter 0x12	//设定单个参数
#define Communication_Type_ErrorFeedback 0x15	    //故障反馈帧
//参数读取宏定义
#define Run_mode 0x7005	
#define Iq_Ref   0x7006
#define Spd_Ref  0x700A
#define Limit_Torque 0x700B
#define Cur_Kp 0x7010
#define Cur_Ki 0x7011
#define Cur_Filt_Gain 0x7014
#define Loc_Ref 0x7016
#define Limit_Spd 0x7017
#define Limit_Cur 0x7018

#define Gain_Angle 720/32767.0
#define Bias_Angle 0x8000
#define Gain_Speed 30/32767.0
#define Bias_Speed 0x8000
#define Gain_Torque 12/32767.0
#define Bias_Torque 0x8000
#define Temp_Gain   0.1

#define Motor_Error 0x00
#define Motor_OK 0X01

enum CONTROL_MODE   //控制模式定义
{
    Motion_mode = 0,//运控模式  
    Position_mode,  //位置模式
    Speed_mode,     //速度模式  
    Current_mode    //电流模式
};
enum ERROR_TAG      //错误回传对照
{
    OK                 = 0,//无故障
    BAT_LOW_ERR        = 1,//欠压故障
    OVER_CURRENT_ERR   = 2,//过流
    OVER_TEMP_ERR      = 3,//过温
    MAGNETIC_ERR       = 4,//磁编码故障
    HALL_ERR_ERR       = 5,//HALL编码故障
    NO_CALIBRATION_ERR = 6//未标定
};

typedef struct{           //小米电机结构体
	uint8_t CAN_ID;       //CAN ID
    uint8_t MCU_ID;       //MCU唯一标识符[后8位,共64位]
	float Angle;          //回传角度
	float Speed;          //回传速度
	float Torque;         //回传力矩
	float Temp;			  //回传温度
	
	uint16_t set_current;
	uint16_t set_speed;
	uint16_t set_position;
	
	uint8_t error_code;
	
	float Angle_Bias;
	
}MI_Motor;
extern MI_Motor mi_motor[4];//预先定义四个小米电机

extern void chack_cybergear(uint8_t ID);
extern void start_cybergear(MI_Motor *Motor);
extern void stop_cybergear(MI_Motor *Motor, uint8_t clear_error);
extern void set_mode_cybergear(MI_Motor *Motor, uint8_t Mode);
extern void set_current_cybergear(MI_Motor *Motor, float Current);
extern void set_zeropos_cybergear(MI_Motor *Motor);
extern void set_CANID_cybergear(MI_Motor *Motor, uint8_t CAN_ID);
extern void init_cybergear(MI_Motor *Motor, uint8_t Can_Id, uint8_t mode);
extern void motor_controlmode(MI_Motor *Motor,float torque, float MechPosition, float speed, float kp, float kd);

到了这里,关于小米电机CyberGear STM32HAL 使用指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】使用HAL库进行电机速度环PID控制,代码+调参

    主控:STM32F103C8T6 在进行速度控制之前,我们首先需要进行速度采样,这里参见这篇博文 ​ 这里不细说电机驱动模块的选型和使用,而是说一个常见的误区。我们驱动电机要使用两路PWM,一般是一路给PWM信号,一路是纯低电平。但这其实是不好的,正确的做法是一路给PWM,另

    2023年04月20日
    浏览(49)
  • 【STM32】使用HAL库对ULN2003控制28BYJ-48步进电机

    步进电机是将电脉冲信号转变为角位移或线位移,通过控制施加在电机线圈上的电脉冲顺序、频率和数量,可以控制步进电机的转向、速度和旋转角度。 配合以直线运动执行机构(螺纹丝杆)或齿轮箱装置,更可以实现更加复杂、精密的线性运动控制要求。 在非超载的情况下,

    2024年02月16日
    浏览(49)
  • PWM在STM32中使用指南

    PWM(脉冲宽度调制)是一种常用来控制模拟电路的技术,通过修改脉冲的宽度(即在固定周期内的高电平持续时间)来调控输出信号的平均电压。 一个PWM信号主要包括两个部分:一个是 占空比 ,它决定了信号高电平状态的时间比例;另一个是 频率 ,它决定了PWM周期的长短

    2024年02月22日
    浏览(36)
  • STM32入门指南(6)—DAC的使用

    本文以 STM32F103ZET6 为例,介绍STM32的DAC的如何在 STM32CubeMX 中配置,以及一些代码上的说明。主要是针对用DAC输出一些特定信号(以各种频率的正弦信号为例)。 硬件: 一块STM32F103ZET6开发板 软件: MDK 532 STM32CubeMX 6.0.1 该芯片的数据手册可以从ST的官网下载到: https://www.stmic

    2024年02月14日
    浏览(31)
  • STM32机器人控制开发教程No.4 使用串口通信控制电机(基于HAL库)

    在机器人控制中,单片机(Arduino/STM32)与上位机(Raspberry Pi/NVIDIA Jetson nano)之间的通信经常采用串口通信的方式,那应该如何使用STM32的串口通信以及根据自己定义的协议来完成数据的接收与发送呢?在本篇文章中将给你演示如何通过自定协议来完成对电机的控制以及获取编码

    2023年04月25日
    浏览(54)
  • STM32:CMSIS-DSP使用指南(在单片机上运用常用的数学运算)

    1.keil环境搭建 在STM32中使用DSP库_linuxweiyh的博客-CSDN博客 2.官方文档 [STM32官方DSP文档](file:///E:/Professional_APP/stm32_cubeMX/install_pack/STM32Cube_FW_F4_V1.27.1/Drivers/CMSIS/docs/DSP/html/modules.html) -1.基本数学运算函数 -2.快速数学运算函数 -3.复数运算函数 -4.滤波器 -5.矩阵函数 -6.数学变换 -7.电机

    2024年02月13日
    浏览(55)
  • stm32cubemx hal学习记录:电机控制

    1、配置RCC、SYS,SYS的Timebase Source选择TIM6 2、配置USART1、时钟84MHz 3、激活FreeRTOS,选择CMSIS_V1,Config parameters种USE_TIMERS选择ENABLE 1、选用TIM3的编码器模式  2、驱动使用L298N,将PB6、PB7设置为输出模式  3、使用TIM2的CH1输出1kHz的PWM 1、设置两个软件定时器,一个用于总控制,一个

    2024年02月17日
    浏览(37)
  • stm32编码器电机测速(hal库)

    记录一下今天参考别人的代码实现了四个电机的测速。   编码器被广泛应用于电机测速,实现电机闭环控制 。所以不论是自己做小车还是后续参加各种比赛,必须要学会编码器测速。         编码电机其实就是一个带有编码器的电机,我的这个电机是一个带霍尔传感器的

    2024年02月13日
    浏览(47)
  • 【正点原子STM32连载】第四章 APM32初体验 摘自【正点原子】APM32E103最小系统板使用指南

    1)实验平台:正点原子APM32E103最小系统板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban 本章并不涉及程序代码的编写,而是介绍如何编译工程、烧录程序以及进行程序的调试仿真,让读者

    2024年02月21日
    浏览(56)
  • 【正点原子STM32连载】第十章 跑马灯实验 摘自【正点原子】APM32E103最小系统板使用指南

    1)实验平台:正点原子APM32E103最小系统板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban 跑马灯程序是嵌入式开发的一个经典程序,类似于学习C语言时,编写的“Hello World”程序。跑马灯本

    2024年02月02日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包