带编码器的直流减速电机——基于STM32F407_stm32f407控制带编码器的直流减速电机转动

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

入口参量:(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising);
通过这样配置,我们就完成了编码器软件的初始化。通过以上配置,我们完成了TIM3输入捕获的初始化以及编码器接口模式的相关配置,每来一个跳变沿,计数值变化一次。

至此,为了避免我们忘了初衷,现在我们来回顾一下我们最开始用编码器的初衷,前面我们说要用编码器来干嘛来着?获取电机转动角度、转速。
现在的处境是,我们通过STM32的TIM3的编码器模式,能够测出任意时刻的脉冲值了。现在要解决的就是如何将这个脉冲值转换成我们所要得到的信息(即转动角度、转速)。
首先,根据带编码器的直流减速电机的原理,显然无论电机的转速如何,每转产生的脉冲数是固定的。这里假设电机每转产生260个脉冲(具体数据各位自行查看自己的电机参数啦),那么只要我们用‘电机已产生的脉冲数’除以‘260个/转’,就可以得到电机转了多少圈,一圈即为360度,由此便可将脉冲数和转动角度联系起来。
这里要注意一点,由于我们用的是编码器模式3(也就是TIM_EncoderMode_TI12),我们得到的脉冲数是电机实际产生的脉冲数的四倍。则电机实际产生的脉冲数应为‘得到的计数值’除以4。于是,电机转动圈数为脉冲数除以260再除以4。
转动角度算出来了,转速呢?则是根据计数方向(递增计数或递减计数)来判断的,所以我们接下来的工作就是要搞清楚计数方向和编码器信号的关系。
让我们来看一下STM32的中文参考手册:
中文参考手册
网上几乎在这张表的讲解上都是一带而过,真正能把这张表讲清楚的几乎没有。后来看到一个人在表格上做了类似上图的注释,我才终于搞懂了。
大家还记得我们前面提到的TIM_EncoderInterfaceConfig函数吗,里面有个参量就是选择模式的,对吧。让我们再来回顾一下:
STM32官方库函数
注意到各模式后面的“xx edge depending on xx level”了吗?这就是上面这个表里的第二纵列所提到的“相反信号的电平”。
TIM_EncoderMode_TI1: Counter counts on TI1FP1 edge depending on TI2FP2 level,意思就是当选择模式1时,计数器根据TI2的电平高低来记录TI1的边沿信号。
这样说可能不好理解,我们来举个具体的例子:
中文参考手册
如上图,电机转动时产生A、B两相信号通过TI1、TI2输入到TIM3。
假设我们选择的是模式1,即计数器仅在TI1的边沿处计数。我们观察TI1的上升沿,若此时对应的TI2信号处于低电平(下图红框),于是根据表格我们可以得到计数方向为递增,假设计数器递增时电机正向转动,则可判断此时电机正转。
在这里插入图片描述
在这里插入图片描述
再譬如,假设我们选择模式2,即计数器仅在TI2的边沿处计数。我们观察TI2的下降沿,若此时对应的TI1信号为高电平(下图蓝框),于是根据表格我们可以得到计数方向为递减,假设计数器递减时电机反向转动,则可判断此时电机反转。
在这里插入图片描述
在这里插入图片描述
也就是说,当以TI1为计数信号时,需要根据TI2的电平(也就是第二纵列的“相对信号的电平”)来进行判断是向上计数还是向下计数。TI2也同理。
e.g.如果“仅在TI1计数”,当TI1为“上升”沿(表中第三纵列),此时要根据TI2的电平来做判断。根据下图,可知当TI1为上升沿的时候TI2为低电平,则根据上表可得知计数器为向上计数。这在下图得到了验证。
在这里插入图片描述
再例如,如果“仅在TI2计数”时,当TI2为下降沿时,如果TI1为低电平,则为向上计数(上图左侧);当TI2为下降沿时,如果TI1为高电平,则为向下计数(上图中部);当TI2为上升沿时,如果TI1为高电平,则为向上计数(上图左部);当TI2为上升沿时,如果TI1为低电平,则为向下计数(图中中部);
至此为止,我们便实现了这样的操作:通过使用带编码器的直流减速电机产生正交脉冲,通过STM32的TIM的编码器模式对脉冲进行计数,根据计数方向和编码器信号的关系来判断电机转动方向,利用脉冲计数值来计算电机转动位移。

接下来是代码部分,有些容易让人迷惑的地方(至少是让我迷惑了很久):
输入捕获初始化时Period和Prescaler的作用:
这里的period即为计数器的重装载值,prescaler即为预分频系数。注意在编码器模式时,要把TIM理解为计数器,而不是定时器,这样的话,时钟信号就不是系统内部产生的,而是通过PA6、PA7输入到TIM3的TI1和TI2的。
有了这么个理解,再来看Period和Prescaler就不难理解了。Period就是计数器每一次能检测脉冲的最大值,每来一个脉冲计数值就加一,当计数值超过period就溢出中断。Prescaler就是对电机产生的脉冲信号进行分频的分频系数。比如当分频系数为2时,每当电机产生两个脉冲,stm32才认为接收到一个有效脉冲,计数值才加一。

以下为部分代码

//思路:初始化TIM的编码器模式后,在main函数里死循环不断的读取CNT的值,从而来获得电机的脉冲数数据,以此来计算电机的转速、所转圈数等参数
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "pwm.h"
#include "encode.h"
#include "exti.h"
#include "key.h"

u32 pwm = 50000;

int main(void)
{
	uint32_t cnt_temp;			//用于暂存TIM的计数值,即TIM检测到的脉冲的数量
	float pulse;				//电机产生的实际脉冲值
	float round;				//电机转的圈数
	
	encoder_init();				//TIM3编码器模式初始化,A6、A7分别作为A相和B相的脉冲输入
	exti_init();				//外部中断,用于通过按键修改数据(比如PWM)
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置系统中断优先级分组2
	delay_init(168);  								//初始化延时函数
	uart_init(115200);								//初始化串口波特率为115200
 	TIM4_PWM_Init(50000-1,84-1);					//TIM4初始化,用于产生PWM供给直流减速电机
													//84M/84=1Mhz的计数频率,重装载值50000,所以PWM频率为100000/50000=2hz,即整个周期为500ms
	while(1)
	{
		TIM_SetCompare1(TIM4,pwm);					//设置供给电机的PWM值
		cnt_temp = read_cnt();						//得到脉冲计数值
		pulse = cnt_temp/4.0f;						//由于是TIM_EncoderMode_TI12,所以要四分频,即除以四,得到实际的脉冲值
		round = cnt_temp/4.0f/260.0f;				//假设电机每转产生260个脉冲,则通过该公式可求出电机转了几圈
		printf("cnt_temp:%d\r\n", cnt_temp);		//向串口打印脉冲计数值
		printf("pulse:%f\r\n", pulse);				//向串口打印实际脉冲值
		printf("round:%f\r\n", round);				//向串口打印电机转了几圈
		delay_ms(1000);								//每1s循环更新一次
//		if(TIM3->CR1&1<<4)	printf("forward");
//		else	printf("backward");
	}
}




//把TIM3理解为一个计数器而不是一个定时器,则没有了时序信号。
//这里TIM3的时钟信号(或者说是计数信号)将由电机编码器输出的脉冲代替,也就是说电机脉冲信号成为TIM3的信号,电机每产生一个脉冲被TIM3检测到,则计数器CNT加一(类比于时序信号时每隔一个时间段计数值加一)
//这样的话,输入捕获的自动重装载值period则影响着脉冲值计数到多少之后就溢出,比如65535的话,则接收到65535个脉冲信号之后计数值置零溢出
//这样的话,输入捕获的预分频系数prescaler的作用是,当我不分频时,来一个电机脉冲信号我计数值就加一,当我二分频时,只有接收到两个脉冲信号我才认为是一个有效脉冲,计数值才加一,简单来说就是计数值总体除以二了
//这样我们就把输入捕获初始化完成了,接下来是编码器模式的初始化
//设为TIM_EncoderMode_TI12模式,即计数器在TI1和TI2上升沿处均计数,再根据设置的极性是TIM_ICPolarity_Rising,也就是在TI1和TI2的上升沿计数器累加(或累减)-->那么到时候要除以二
//这样,编码器的初始化就完成了,接下来我们只要通过函数得出它的计数值,就可以知道电机产生的脉冲数,再根据电机的参数(每转产生多少个脉冲)就可以得到电机转了几圈
#include "encode.h"
#include "sys.h"

//初始化编码器
void encoder_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);    
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3);
	
	//Specifies the prescaler value used to divide the TIM clock.
	//也就是说,这里的TIM3的时钟信号其实是由A/B相的频率来决定的,类似于外部时钟,然后分频就是对这个脉冲频率分频,比如二分频就是把两个脉冲记为一个脉冲。
	TIM_TimeBaseStructure.TIM_Prescaler = 1-1;					//这里我们把它设为1,即不分频
	TIM_TimeBaseStructure.TIM_Period = 65535;					//每来一个脉冲信号的上升沿(下面有设置)计数值就累加(或累减),65535则为最大计数值,就溢出了
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //这里按理来说应该不起作用,因为计数方向是受TI1和TI2信号的影响的
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_ICStructInit(&TIM_ICInitStructure);						//Fills each TIM_ICInitStruct member with its default value


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/28d32105f61e0e4d09140ba29d9c5472.png)
![img](https://img-blog.csdnimg.cn/img_convert/705db463e28e1e2eb705a71e89c290bd.png)

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

s://bbs.csdn.net/topics/618679757)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 18
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
直流减速电机编码器是一种常见的电机系统,它结合了直流减速电机编码器的功能。直流减速电机通过减速装置降低输出速度并增加扭矩,而编码器则用于测量电机的转速和位置。这种电机系统通常用于需要精确控制和反馈的应用,例如机器人、自动化设备和精密仪器。 在引用\[1\]中提到的实验中,作者使用了JGB37-520减速直流电机,并通过STM32定时器输出比较生成PWM控制电机输出。同时,作者还使用了编码器接口对电机进行测速,并通过OLED显示PWM输出占空比和电机转速。这种设计可以实现对直流减速电机的精确控制和监测。 根据引用\[2\]中的描述,直流减速电机的减速装置可以采用不同的传动类型,如齿轮减速器、蜗杆减速器和行星齿轮减速器。每种传动类型都有其特点和适用场景。齿轮减速器体积小、传递扭矩大,但存在一定的回程间隙;蜗杆减速器具有反向自锁功能,减速比较大,但体积较大、传动效率不高、精度不高;行星齿轮减速器结构紧凑、回程间隙小、精度较高、使用寿命长,但价格较高。 最后,在引用\[3\]中给出了一个Motor.h的头文件,其中定义了一些宏和函数用于电机的初始化和设置速度。这个头文件可能是作者在实验中使用的电机控制代码的一部分。 综上所述,直流减速电机编码器是一种常见的电机系统,可以实现精确控制和监测。在实验中,作者使用了JGB37-520减速直流电机,并通过STM32定时器和编码器实现了对电机的控制和测速。同时,作者还使用了OLED显示PWM输出占空比和电机转速。不同的减速装置类型可以根据具体需求选择,而Motor.h头文件可能是作者在实验中使用的电机控制代码的一部分。 #### 引用[.reference_title] - *1* *3* [【32单片机学习】(3)霍尔编码器减速直流电机控制及测速](https://blog.csdn.net/sudoeast/article/details/127938592)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [智能车|直流电机、编码器与驱动器---减速器](https://blog.csdn.net/qq_32761549/article/details/128451572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值