STM32CubeMX(6) —— STM32利用定时器编码器模式处理带编码器直流电机

STM32利用定时器编码器模式处理带编码器直流电机


前言

电赛延期了,趁有时间再写点东西吧.

编码器电机配置较为繁琐,本文较长,耐心看下去,一定有收获.

本文适合已经对编码器有所了解的同学观看,如果对编码器原理还不太理解,可以看看CSDN中别人讲编码器的,个人觉得已经讲的十分清楚了,这里主要讲解怎么使用Cubemax去使用编码器


一、硬件准备

  1.         本次实验使用的是带增量式AB相霍尔编码器的直流减速电机

 简单介绍一下这款电机,减速比为1:30,即输出轴转一圈,电机内部实际转30圈,霍尔编码器为13位编码器,即电机每转,对于编码器有2的13次方的增量.(简单的说,上面那个霍尔编码器检测的圆盘,转一圈,检测13个脉冲)

 2.        电机所使用的电机驱动为应该大家都十分熟悉的L298N

                                 

这里就不过多介绍了,CSDN上也有很多对此介绍十分详细的.

3.        合适的8-12V的电源

                                           

电机额定电压为12V,可以选择串联3节锂电池12V,或者两节锂电池8V来进行实验.

二、接线 !!!

电机L298NSTM32
M-OUT1/
5V5V/
A/编码器模式定时器IO
B       /编码器模式定时器IO

GND

GNDGND
M+OUT2/
/ENAPWM输出IO
/M1输出IO
/M2输出IO

        其中,这里要说明几点.

        1.L298N,单片机和电机需要共地

        2.我这里使用的是单PWM输出IO来控制ENA,而不是和其他博主一样使用两路PWM输出去控制M1,M2,然后一直使能的方法,这样可以节约一个定时器产生PWM.

三、Cubemax配置

1.首先是接线中用来控制M1和M2的两个IO口的输出配置,这里我使用的是PC4和PC5

 2.开启定时器一的编码器模式

这里面修改Counter Period为20000,即代表,编码器计数器范围为0~20000.其他默认即可,这里的分配系数表示的对计数值分频,如果你这里写了3=4-1,那后面speed算的时候就不用除以4了。

 对应的IO口为PE9,PE11.

 3.开启用于控制ENA的PWM输出

这里采用的是定时器5的PWM输出.

本实验使用的是F103的板子,PWM输出频率为100hz

 4.开启每隔10ms对编码器定时器中值的读取的定时器

5.最后配置中断 

这里注意一下,最好编码器的更新中断定时器,要比10ms定时器的优先级高,可以防止在更新中打被打断.

四、代码

首先创建一个文件Motor.c和Motor.h,在此文件中来编写我们有关电机的代码.

首先在Motor.h中来定义一些我们常用的东西

1.Motor.h中定义Motor相关参数

#define RR 30u    //电机减速比
#define RELOADVALUE __HAL_TIM_GetAutoreload(&htim1)    //获取自动装载值,本例中为20000
#define COUNTERNUM __HAL_TIM_GetCounter(&htim1)        //获取编码器定时器中的计数值
#define IN1(state) HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,(GPIO_PinState)(state))    //M1
#define IN2(state) HAL_GPIO_WritePin(GPIOC,GPIO_PIN_5,(GPIO_PinState)(state))    //M2

//电机结构体
typedef struct _Motor
{
	int32_t lastAngle;        //上10ms转过的角度
	int32_t totalAngle;       //总的角度
	int16_t loopNum;          //溢出次数计数值
	float speed;              //电机输出轴目前转速,单位为RPM
}Motor;

2.Motor初始化

void Motor_Init()
{
	HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);      //开启编码器定时器
    __HAL_TIM_ENABLE_IT(&htim1,TIM_IT_UPDATE);           //开启编码器定时器更新中断,防溢出处理
	HAL_TIM_Base_Start_IT(&htim6);                       //开启10ms定时器中断
	HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_2);            //开启PWM
	__HAL_TIM_SET_COUNTER(&htim1, 10000);                //编码器定时器初始值设定为10000
	motor.loopNum = 0;                                   //溢出计数
}

此函数在main中使用即可.

 3.中断处理函数重写

我们需要重写HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)来处理中断

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==htim6.Instance)		              //10ms中断
	{
		
		int16_t pluse = COUNTERNUM - RELOADVALUE/2;
        //从开始到现在当前10ms的总脉冲数							               									
		motor.totalAngle = pluse + motor.loopNum * RELOADVALUE/2;  
        //进行速度计算,根据前文所说的,4倍频,编码器13位,减速比30,再乘以6000即为每分钟输出轴多少转
        //motor.totalAngle - motor.lastAngle为当前10ms内的增量,即脉冲数
		motor.speed = (float)(motor.totalAngle - motor.lastAngle)/(4*13*RR)*6000;			
		motor.lastAngle = motor.totalAngle;              //更新转过的圈数
	}

    //如果是编码器更新中断,即10ms内,脉冲数超过了计数范围,需要进行处理
	else if(htim->Instance == htim1.Instance)            
	{
		if(COUNTERNUM < 10000)	motor.loopNum++;         //向上计数超过10000,正溢出+1
		else if(COUNTERNUM > 10000)	motor.loopNum--;     //向下计数小于0,负溢出+1
		__HAL_TIM_SetCounter(&htim1, 10000);             //重新设定初始值			
	}
}

这里注意,本文采用了编码器更新中断的方法,防止出现10ms内出现电机转速过快,脉冲计数超过设定值的情况出现,跟其他博主不同,主流在编码器计数时都采用限定值为65535,并没有考虑这个情况,不过多数电机不是转太快的情景,主流的方法都可行.

之后我们可以通过,对IN1,IN2写值,来控制电机正转,反转,然后对PWM写值,来控制电机运动来观察结构体中Motor中speed值的变化.

如果懒的写,就用手去选择一下输出轴或者上面的编码器盘,在debug中观察一下现象.

总结

本文介绍了编码器电机数据的读取,当我们可以读取到编码器电机中的值后,我们就可以在后续进行PID速度和串级PID角度的控制.

STM32 Cubemax(七) —— 单级PID控制带编码器的直流减速电机速度

<think>嗯,用户想找关于如何使用STM32 CubeMX配置编码电机来控制小车的教程或示例。首先,我需要回忆一下CubeMX的基本操作,特别是与编码器和电机相关的配置。记得编码电机通常使用定时器编码器模式,所以可能需要配置TIM模块为编码器接口。 根据引用[3],用户提到需要在CubeMX生成的工程中加入一些初始化代码,比如HAL_TIM_Encoder_Start和HAL_TIM_PWM_Start。这说明编码器模式和PWM输出是关键部分。可能用户需要配置两个定时器,一个用于编码器输入,另一个用于PWM输出控制电机速度。 接下来,电机驱动部分,引用[2]提到TB6612驱动器,需要了解如何通过STM32的GPIO控制电机的方向和速度。CubeMX中需要配置相应的GPIO引脚作为输出,用于控制电机的方向,同时PWM信号控制速度。 然后,用户可能还需要整合PID控制,因为引用[1]提到了PID循迹模式。所以在代码中可能需要实现PID算法,根据编码器的反馈调整PWM占空比。这部分需要定时器中断来定期计算PID输出。 可能用户遇到的问题包括如何正确配置定时器编码器模式,如何设置预分频器和自动重载值以适应编码器的分辨率,以及如何将PWM信号与电机驱动器的输入对应起来。此外,代码中需要处理电机的正反转,这涉及到GPIO引脚的电平设置。 还需要考虑CubeMX中的项目设置,比如时钟配置是否正确,定时器的通道是否分配到正确的引脚,以及中断的使能情况。用户可能需要参考具体的硬件连接,例如编码器的A、B相连接到哪个定时器的通道,电机驱动器的输入引脚对应STM32的哪些GPIO。 最后,示例代码的结构可能包括初始化函数、中断服务程序中的编码器读数处理PID计算和PWM更新。需要确保代码能够正确读取编码器的脉冲数,并根据目标速度调整电机输出。 总结一下,用户需要的步骤可能包括CubeMX定时器配置、GPIO设置、PWM生成、编码器接口配置,以及编写相应的控制代码整合这些模块。同时,需要参考现有的教程和示例代码,如引用[2]和[3]中的内容,来确保正确性和效率。</think>根据引用内容,我将为您整理STM32 CubeMX配置编码电机控制小车的实现步骤: ### 一、硬件配置基础 1. 编码电机接口使用TIM3/TIM4的编码器模式(引用[3]) 2. TB6612电机驱动需要配置: - PWM输出:TIM1_CH1和TIM1_CH4(引用[3]) - 方向控制GPIO:需自行定义(引用[2]) 3. 运动模式标志位需要定义全局变量(引用[1]) ### 二、CubeMX配置步骤 1. **定时器配置**: ```c /* 编码器模式配置示例 */ TIM3->EncoderMode = TIM_ENCODERMODE_TI12; TIM3->Polarity = TIM_INPUTCHANNELPOLARITY_RISING; TIM4->EncoderMode = TIM_ENCODERMODE_TI12; // 类似配置 ``` 2. **PWM输出配置**: ```c // 在CubeMX中配置TIM1的通道1和4为PWM模式 // 设置预分频值和自动重载值,例如: TIM1->PSC = 71; // 72MHz/(71+1)=1MHz TIM1->ARR = 999; // PWM频率=1MHz/(999+1)=1kHz ``` ### 三、关键代码实现 1. **初始化代码**(引用[3]): ```c HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL); HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4); ``` 2. **电机控制函数**: ```c void Motor_SetSpeed(int16_t speed, uint8_t motor_id) { // 设置方向引脚(引用[2]的H桥控制原理) GPIO_PinState dir = (speed >= 0) ? GPIO_PIN_SET : GPIO_PIN_RESET; HAL_GPIO_WritePin(GPIOC, motor_dir_pins[motor_id], dir); // 设置PWM占空比(引用[3]) __HAL_TIM_SET_COMPARE(&htim1, motor_pwm_channels[motor_id], abs(speed)); } ``` 3. **编码器数据读取**: ```c int32_t Encoder_GetCount(TIM_HandleTypeDef *htim) { return (int32_t)(__HAL_TIM_GET_COUNTER(htim)); } ``` ### 四、PID控制实现(引用[1]的PID模式) ```c typedef struct { float Kp, Ki, Kd; float integral; float prev_error; } PID_Controller; float PID_Update(PID_Controller* pid, float error, float dt) { pid->integral += error * dt; float derivative = (error - pid->prev_error) / dt; pid->prev_error = error; return pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative; } ```
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzzzzzzm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值