STM32F407 电机编码器测量

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

一、STM32F407 定时器编码器功能

1.1 STM32定时器简介

STM32的定时器功能非常强大,根据官方手册,定时器的功能如下
高级定时器
TIM1 和 TIM8 主要特性
TIM1 和 TIM8 定时器具有以下特性:
● 16 位递增、递减、递增/递减自动重载计数器。
● 16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数
介于 1 到 65536 之间。
● 多达 4 个独立通道,可用于:
— 输入捕获
— 输出比较
— PWM 生成(边沿和中心对齐模式)
— 单脉冲模式输出
● 带可编程死区的互补输出。
● 使用外部信号控制定时器且可实现多个定时器互连的同步电路。
● 重复计数器,用于仅在给定数目的计数器周期后更新定时器寄存器。
● 用于将定时器的输出信号置于复位状态或已知状态的断路输入。
● 发生如下事件时生成中断/DMA 请求:
— 更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)
— 触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
— 输入捕获
— 输出比较
— 断路输入
● 支持定位用增量(正交)编码器和霍尔传感器电路。
● 外部时钟触发输入或逐周期电流管理。

通用定时器
TIM2 到 TIM5 主要特性
通用 TIMx 定时器具有以下特性:
● 16 位(TIM3 和 TIM4)或 32 位(TIM2 和 TIM5) 递增、递减和递增/递减自动重载计
数器。
● 16 位可编程预分频器,用于对计数器时钟频率进行分频 (即运行时修改),分频系数介
于 1 到 65536 之间。
● 多达 4 个独立通道,可用于:
— 输入捕获
— 输出比较
— PWM 生成(边沿和中心对齐模式)
— 单脉冲模式输出
● 使用外部信号控制定时器且可实现多个定时器互连的同步电路。
● 发生如下事件时生成中断/DMA 请求:
— 更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)
— 触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)
— 输入捕获
— 输出比较
● 支持定位用增量(正交)编码器和霍尔传感器电路
● 外部时钟触发输入或逐周期电流管理

1.2 STM32定时器编码器功能

根据下面的图可以看出通用定时器也是有编码器输入功能。
STM32F407 电机编码器测量

在编码输入时是有上升沿与下降沿的,我们可以利用外部中断分别捕获编码器A、B项边沿,手写逻辑消除毛刺并解析编码器数据,但这是比较复杂的。其实这里的脉冲输入是一种特殊的输入捕获情况,因此stm32专门在定时器中提供了编码器模式,可大大简化解析过程。

选择编码器接口模式时,如果计数器仅在 TI2 边沿处计数,在 TIMx_SMCR 寄存器中写入
SMS=001;如果计数器仅在 TI1 边沿处计数,写入 SMS=010;如果计数器在 TI1 和 TI2 边 沿处均计数,则写入 SMS=011。

通过编程 TIMx_CCER 寄存器的 CC1P 和 CC2P 位,选择 TI1 和 TI2 极性。如果需要,还可对输入滤波器进行编程TI1 和 TI2 两个输入用于连接增量编码器。请参见表 75。如果使能计数器(在 TIMx_CR1 寄 存器的 CEN 位中写入“1”),则计数器的时钟由 TI1FP1 或 TI2FP2 上的每次有效信号转 换提供。TI1FP1 和 TI2FP2 是进行输入滤波器和极性选择后 TI1 和 TI2 的信号,如果不进行 滤波和反相,则 TI1FP1=TI1,TI2FP2=TI2。将根据两个输入的信号转换序列,产生计数脉 冲和方向信号。根据该信号转换序列,计数器相应递增或递减计数,同时硬件对 TIMx_CR1 寄存器的 DIR 位进行相应修改。任何输入(TI1 或 TI2)发生信号转换时,都会计算 DIR 位,无论计数器是仅在 TI1 或 TI2 边沿处计数,还是同时在 TI1 和 TI2 处计数。

编码器接口模式就相当于带有方向选择的外部时钟。这意味着,计数器仅在 0 到 TIMx_ARR 寄存器中的自动重载值之间进行连续计数(根据具体方向,从 0 递增计数到 ARR,或从 ARR 递减计数到 0)。因此,在启动前必须先配置 TIMx_ARR。同样,捕获、比较、预分频 器、触发输出功能继续正常工作。

在此模式下,计数器会根据增量编码器的速度和方向自动进行修改,因此,其内容始终表示编码器的位置。计数方向对应于所连传感器的旋转方向。下表汇总了可能的组合(假设 TI1 和 TI2 不同时切换)。
STM32F407 电机编码器测量
下图为双项模式下计数效果,可见在A、B中仅一项有**抖动(**就是编译器无效的脉冲,需要过滤)时,计数值加减后保持不变,实现了抖动补偿
STM32F407 电机编码器测量
从图上可以看出,定时器是采集A、B两相的脉冲,当编码器输出一个周期时,定时器计数值为4,这是要必须记住的哈。

二、带编码器的直流电机

我手上刚好有一个带编码器的直流电机,电机参数如下,520电机包含编码器款该电机采用全金属齿轮,具备功率大、抗干扰好、精度高、寿命长的特点。
STM32F407 电机编码器测量
STM32F407 电机编码器测量
在这里需要说明一下,如果电机转一圈,那么黄线输出的脉冲数量为:1130 = 330个, 那么绿线输出的脉冲数量为:1130 = 330个。根据上面分析的定时器编码器模式,电机转一圈,定时器计数脉冲的个数为:330*4 = 1320个。

三、代码与验证

电机实物图
STM32F407 电机编码器测量

3.1 初始化代码

/****************************************
引脚说明

A相连接PB6
B相连接PB7

PB6 -- TIM4_CH1
PB7 -- TIM4_CH2

****************************************/

void TIM4_Int_Init(void) 
{		
	GPIO_InitTypeDef 	        GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef	 	TIM_TimeBaseInitStructure;
	TIM_ICInitTypeDef 			TIM_ICInitStructure;
	NVIC_InitTypeDef			NVIC_InitStructure;
		
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);//开启GPIOC的时钟
	

	
	GPIO_InitStruct.GPIO_Pin  	= GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_100MHz;
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_OD;
	GPIO_InitStruct.GPIO_PuPd	=  GPIO_PuPd_UP;
	
	GPIO_Init(GPIOB, &GPIO_InitStruct);                          
	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);//将引脚6映像到TIM8
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4);//将引脚7映像到TIM8
	
		

  //定时器设置-------------------------------------------------------------	
    TIM_TimeBaseInitStructure.TIM_Period = 330*4;   				//重装载值 这是两相脉冲总数量
	TIM_TimeBaseInitStructure.TIM_Prescaler=0x0; 				 	//预分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; 	//向上计数
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 		//时钟分割
	
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化TIM3

    //编码器模式设置--------------------------------------------------------------			  		

	TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//计数模式3
	
	TIM_ICStructInit(&TIM_ICInitStructure); 
    TIM_ICInitStructure.TIM_ICFilter = 10;  //滤波器值
    TIM_ICInit(TIM4, &TIM_ICInitStructure);
    //溢出中断设置--------------------------------------------------------------
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //允许TIM4溢出中断
	
	NVIC_InitStructure.NVIC_IRQChannel					=TIM4_IRQn; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority		=0x01; 
	NVIC_InitStructure.NVIC_IRQChannelCmd				=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
  
   //Reset counter-----------------------------------------------
   TIM_SetCounter(TIM4,0); //TIM3->CNT=0
   TIM_Cmd(TIM4, ENABLE); 
}




主函数

int Encoder_Timer_Overflow; //编码器溢出次数
 
u16 Previous_Count; 
u32 speed=0;
int circle_count = 0;   //记录电机正反转

//void TIM8_CC_IRQHandler(void)
//{
//	if(TIM_GetITStatus(TIM8,TIM_IT_Update)==SET)
//	{
//		Encoder_Timer_Overflow++;
//	}
//	TIM_ClearITPendingBit(TIM8,TIM_IT_Update); 

//}

//电机转动一圈产生中断
void TIM4_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)
	{
		Encoder_Timer_Overflow++;
		
		
		if((TIM4->CR1>>4 & 0x01)==0)     //DIR==0  通过寄存器TIMx_CR1第四位判断  0:电机正转
			circle_count++;
		else if((TIM4->CR1>>4 & 0x01)==1)//DIR==1  通过寄存器TIMx_CR1第四位判断  1:电机正转
			circle_count--;
	}
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update); 

}
 
void Read_Encoder(void)
{
                                                       
  u16 Current_Count;           //一段时间的脉冲数                                  
  u16 Enc_Timer_Overflow_one;  //当前脉冲数                                  
                    
  Enc_Timer_Overflow_one=Encoder_Timer_Overflow;                  //获取中断溢出次数  
  Current_Count = TIM_GetCounter(TIM4);                           //得到脉冲数
  Encoder_Timer_Overflow=0;                                       //清0方便下次计算

  //speed = (u32)(Enc_Timer_Overflow_one*车轮周长+Current_Count/(330*4.0)*车轮周长);   //进行平均测速
 
}





int main(void)
{
	u16 m = 0,n = 0;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	
	Delay_Init();
	usart1_init(115200);
	//TIM8_Int_Init();
	TIM4_Int_Init();
	
	
	while(1)
	{	


		delay_ms(500);
		delay_ms(500);
		//CNT的值,能够表示当前获取了多少个脉冲
		printf("获取定时器中的CNT值:%d\r\n",TIM4->CNT);
		//值为正,表示正转圈数比反转圈数多,反之亦然;值递增,表示正在正转,值递减,表示正在反转。
		printf("目前轮子正或反的圈数:%d\r\n",circle_count);

	}
	
	return 0;
}


3.2 验证

STM32F407 电机编码器测量

总结一下,通过对这些的理解,那么可以计算速度、角度、加速度等。
最后代码链接:https://download.csdn.net/download/wwwqqq2014/87124313?spm=1001.2014.3001.5503文章来源地址https://www.toymoban.com/news/detail-402953.html

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

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

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

相关文章

  • STM32之增量式编码器电机测速

    编码器,是一种用来测量机械旋转或位移的传感器。它能够测量机械部件在旋转或直线运动时的位移位置或速度等信息,并将其转换成一系列电信号。 . 按监测原理分类 光电编码器 光电编码器,是一种通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器

    2024年02月13日
    浏览(36)
  • SimpleFOC移植STM32(九)—— ABZ编码器电机

      SimpleFOC、ODrive和VESC 教程链接汇总:请点击     在SimpleFOC代码中,ABZ信号和霍尔电机信号处理方式很像,都是信号边沿触发中断,在中断中获取状态计算角度。 本次移植驱动板103和官方代码保持一致。 驱动板405采用的是定时器计数脉冲,处理方式不同。   ABZ或者ABI,叫

    2023年04月11日
    浏览(88)
  • Stm32-使用TB6612驱动电机及编码器测速

    最近在 学习编码电机以及尝试使用编码电机测速 。遇到了很多问题,花费了很多时间,在这里做一个记录,对自己学习到的知识进行一个总结 找了很多资料,看了很多视频,这些太多了,以至于让我不知道究竟哪一个是正确的,今天看这个,明天看这个,导致自己的学习效

    2023年04月16日
    浏览(67)
  • stm32f103单片机—编码器测速

    stm32f103ZET6开发板(非指定) MG513P3012V型号电机(带霍尔编码器)(非指定) 此种测速方法要求单片机的定时器具有编码器模式,对于stm32f1系列,具备编码器模式的定时器有TIM1/2/3/4/5/8, 定时器使用通道1、2来实现编码器功能 ,接线时注意把A/B相接到定时器通道1/2的引脚。 电

    2024年02月06日
    浏览(74)
  • (STM32)PWM输出控制电机旋转并且使用编码器读取脉冲数

    目录  前言 一、pwm输出让电机转  1.电机的接线说明 2.驱动的接线说明 3.pwm输出代码  pwm.c pwm.h 4.输出pwm控制电机旋转 二、配置定时器编码器模式 1.定时器编码器模式 编码器原理 编码器相关的概念 2.编码器模式——代码部分 3.获取脉冲数 三、定时读取编码器读取的脉冲数

    2024年02月03日
    浏览(55)
  • STM32自学笔记16-步进电机驱动项目-磁编码器的校准

    上节我把MT6816的驱动给大致整明白了,接下去需要看看如何 校准 。 为什么编码器需要校准? 如上节所说,MT6816是一款 绝对值编码器 ,它为每个测量位置分配了唯一的二进制代码或字, 即使断电,也可以跟踪编码器的确切位置 。 但是由于硬件或其他因素的影响,编码器输

    2024年02月16日
    浏览(108)
  • STM32自学笔记17-步进电机驱动项目-磁编码器的正常使用

    上节有这样一句话: 步进电机旋转角度和编码器输出数据之间的关系通常是非线性的。在校准过程中,可以通过采集一系列已知角度位置的数据点,并拟合出角度与编码器数据之间的关系。这个拟合可以使用曲线拟合算法或其他数学方法来实现。通过拟合,可以建立编码器输

    2024年02月16日
    浏览(46)
  • AS5600步进电机编码器(原理图+pcb+stm32控制代码)

    AS5600是一个易于编程的磁性旋转位置传感器,具有高分辨率的12位模拟或PWM输出。这种非接触式系统测量一个直径磁化的轴上磁铁的绝对角度。 引脚如下图 他有两种供电模式:5V和3.3V 我们为了和stm32F103C8T6单片机的电压一致,也使用3.3V供电,然后开始画PCB。 使用嘉立创EDA画

    2024年02月03日
    浏览(52)
  • STM32定时器编码器模式实现直流有刷电机测速(HAL库)

    最近在做一个单片机大作业,要用到直流有刷,在这里把学习编码器的知识记录一下,学习参考资料: 正点原子DMF407电机控制专题教程_V1.0 我所使用的编码器是市面上常见的 磁电增量式编码器 ,其有AB两相,用于输出电机转动时的 脉冲数 ,AB两相的先后顺序决定了电机的

    2023年04月24日
    浏览(64)
  • 【DRV8323】电机驱动芯片寄存器配置指南,通过STM32F407的SPI通信配置

    笔者计划使用一块使用到STM32F407控制芯片与DRV8323s驱动芯片的板子,驱动BLDC。了解到需要使用SPI通信来配置DRV8323s驱动芯片,配置过程中涉及DRV8323数据手册中提及的几个寄存器,故写此文做个记录。 另外,DRV8323芯片和DRV8302、DRV8303、DRV8353都有极大的相似之处,可以相互参考

    2024年02月02日
    浏览(58)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包