stm32-编码器测速

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

一、编码器简介

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

编码电机

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

旋转编码器

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

A,B相分别接通道一和二的引脚,VCC,GND接单片机VCC,GND

二、正交编码器工作原理

以前的代码是通过触发外部中断,然后在中断函数里手动进行计次。使用编码器接口的好处就是节约软件资源。对于频繁执行,操作简单的任务,一般设计一个硬件电路模块来自动完成。

使用定时器的编码器接口,再配合编码器,就可以测量旋转速度和旋转方向。编码器测速一般应用在电机控制的项目上。使用PWM驱动电机,再使用编码器测量电机的速度,然后再使用PID算法进行闭环控制。

平横车经常用到

1.计数方式

 2.框图分析

 由图可知,只有CH1和CH2有编码器接口,且编码器只用到了输入捕获结构体的输入滤波和边沿检测器,则其余的结构体成员都不用区配置。

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

 由框图可知,配置Encoder需要配置GPIO,输入捕获结构体的部分元素,时基单元,我们一般给ARR为65535-1,即最大计数量程,防止计数溢出。PSC=1-1,不分频,直接72M进行计数

3.计数方向与编码器信号的关系

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

 TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising)

这里TIM_EncoderMode_TI12即对应上面的计数边沿,仅在TI1和TI2计数就相当于只在A或B相的边沿计数,我们一般都使用AB相都计数

极性修改:可以使用上方的函数进行,也可以硬件直接调换AB相引脚

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

三、固件库使用

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机 

1.开启GPIO和TIM的时钟

2.配置GPIO结构体,模式配置为上拉输入

3.不用配置内部时钟源,因为编码器托管了时钟,编码器接口就是带方向控制的外部时钟,      所以内部时钟就没有用了    

4.配置时基单元,计数模式就不用配置了,取决于编码器的AB相边沿,ARR为65535-1,     PSC = 1-1不分频

5.配置输入捕获单元(因为是由)TI1FP1和2接入到编码器接口的,所以捕获单元结构体    元素只需配置输入滤波和边沿检测即可,这里边沿检测给上升沿还是下降沿并不是说是

   哪个有效,因为编码器模式下上/下沿都有效,这里指电平极性是否翻转,高电平不反转,

    低电平翻转

6.TIM_EncoderInterfaceConfig();配置编码器,TIM_Cmd();使能定时器

7.使用中断读取Encoder的值(测速度)

   若要测位置就直接读取Encoder的值即可,不需要中断stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

上拉输入还是下拉输入的选择

一般可以看一下接在这个引脚的外部模块输出的默认电平,如果外部模块空闲默认输出高电平,我们就选择上拉输入,默认输入高电平,如果外部模块默认输出低电平,我们配置下拉输入,默认输入低电平。总结,将需要配置电平的位置和外部模块保持默认状态一致,防止默认电平打架。

如果不确定外部模块输出的默认状态或者外部信号输出功率非常小,这时尽量选择浮空输入,浮空输入没有上下拉电阻去影响外部信号,缺点是当引脚悬空时,没有默认电平,输入就会受噪声干扰,来回不断跳变。

测位置:A、B相各出现了一个下降沿和上升沿,所以计次总共加了4次。

               如果转到0,再往左转,0自减,计数器反向溢出,回到自动重装值,65535,然后继续往下减

                解决方法是:如果我们想让0自减为-1,直接把uint16_t类型强制转换成int16_t即可

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机

stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机stm32-编码器测速,stm32,stm32,嵌入式硬件,单片机 

如果想让编码器测速度,可以在固定的闸门时间读一次CNT,然后把CNT清零,此时CNT的值代表速度,单位是脉冲个数/S 

(测频法)文章来源地址https://www.toymoban.com/news/detail-841417.html

#include "encoder.h"


void Encoder_Init(void)
{
	//开启GPIO和TIM3时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//初始化GPIO
	GPIO_InitTypeDef GPIO_InitStruct;//定义GPIO结构体
	//GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//输入不需要配置速度
	GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//因为编码器接口会托管时钟,编码器接口就是带方向控制的外部时钟,所以内部时钟就没有用了	
	//TIM_InternalClockConfig(TIM2);
	
	//配置时基单元
	//初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 1-1;//PSC-预分频器,给0,不分频
	//TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数方向被编码器托管了
	TIM_TimeBaseInitStruct.TIM_Period = 65535-1;//ARR寄存器-重装载寄存器
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;/*不分频----滤波器的采样频率,                                    
                                                                  可以由内部时钟直接提供,														                 
                                                        也可以由内部时钟加一个时钟分频而来,
												分频系数就是由TIM_ClockDivision决定*/
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器,只有高级定时器才有	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);

	//配置输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICStructInit(&TIM_ICInitStruct);
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//电平极性选择,高电平极性不反        
                                                                 转,低电平极性反转
	//TIM_ICInitStruct.TIM_ICSelection //直连or交叉连
	//TIM_ICInitStruct.TIM_ICPrescaler //分频器因子,即每N个边沿跳变事件捕获一次-CCMR1_ICPS
	TIM_ICInitStruct.TIM_ICFilter = 0xF;//CCMR1_ICF
	TIM_ICInit(TIM3, &TIM_ICInitStruct);
	
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//电平极性选择,高电平极性不反    
                                                             转,低电平极性反转
	TIM_ICInitStruct.TIM_ICFilter = 0xF;//CCMR1_ICF
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//这里的上升沿和上面结构体配置的效果一样,所以前面的可以删去

	//使能TIM
	TIM_Cmd(TIM3,ENABLE);
}

int16_t Encoder_Get(void)//int16_t 为了显示负数
{
	int16_t temp;
	temp = TIM_GetCounter(TIM3);
	TIM_SetCounter(TIM3,0);//这里每次获得了编码器的值后就清零CNT是为了得到速度
                           //我们使用了中断,一秒进入一次然后读取CNT的值作为旋转速度
	return temp;
}

#include "bsp_tim.h"

void Time_Config()
{
	//开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	//选择时基单元的时钟-为内部时钟--定时器上电后默认是内部时钟,故不写这一个也行
	TIM_InternalClockConfig(TIM2);
	
	//初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_Prescaler = 7200-1;//PSC-预分频器
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数 
	TIM_TimeBaseInitStruct.TIM_Period = 10000-1;//ARR寄存器-重装载寄存器
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;/*不分频----滤波器的采样频率,可以由内部时钟直接提供,
																													也可以由内部时钟加一个时钟分频而来,
																													分频系数就是由TIM_ClockDivision决定*/
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器,只有高级定时器才有
	
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	
	//使能中断-事件更新
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	TIM_ClearFlag(TIM2,TIM_IT_Update);//因为TIM_TimeBaseInit函数最后有一个直接操作UG位的操作
	                                  //使得直接产生了一个更新事件,因此直接进行给UIE位置1
									 //直接进入了中断,使得我们初始化ARR和PSC还未写入到
									//影子寄存器,使得Num一上电就是1
									//所以在进入中断之前先清楚中断标志位
	
	//使能中断之后就要进入NVIC了
	//先优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	//配置结构体
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;//中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
	
	//启动定时器
	TIM_Cmd(TIM2,ENABLE);
	//在_it文件里编写中断服务函数
}

#include ".\tim\bsp_tim.h"
#include "encoder.h"
#include ".\OLED\OLED.h"



int16_t speed;
int main()
{
	Time_Config();
	Encoder_Init();
	OLED_Init();
	while(1)
	{
		OLED_ShowSignedNum(1,5,speed,5);
	}
}
void TIM2_IRQHandler()
{
	//先获取中断标志位
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
	{
		speed = Encoder_Get();
		//清楚中断标志位
		TIM_ClearFlag(TIM2,TIM_FLAG_Update);
	}
}

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

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

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

相关文章

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

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

    2024年02月13日
    浏览(38)
  • STM32-微项目07-旋转编码器计数及测速

    一、微项目实现目标: 检测旋转编码器模式下,检测旋转编码器的转动计数值及转速。并且区分转向,一侧转动增加cout,转速值为正,一侧转动减少count,转速值为负;   二、微项目硬件配置需求: 1,stm32F103C8T6核心板一块 2,0.96寸OLED显示,用于显示计数 3,旋转编码器,

    2024年02月08日
    浏览(39)
  • stm32f103单片机—编码器测速

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

    2024年02月06日
    浏览(76)
  • 【STM32】【HAL库】定时器编码器模式测速

    目录 概述 HAL设置  定时器的编码器模式 定时器设置  常用函数 代码 电机AB相增量型编码器的介绍和解码方法在这里介绍过了 电机编码器 https://blog.csdn.net/m0_57585228/article/details/125791283 测速可以使用外部中断进行脉冲计数 很多型号的单片机中有专门的电路来计算脉冲的速度和

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

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

    2023年04月16日
    浏览(70)
  • STM32定时器捕获编码器模式测速和方向测不准问题

    ** 问题概述 关于STM32编码器模式电机测速的资料网上一抓一大把,却发现真的拿过来用还是有问题的,比如刚刚做了个东西,是个个头比较大的麦克纳姆轮车,控制运动就需要精确的测量转速和方向,我用的是直流有刷、减速比90、11线霍尔编码器的减速电机。 原本想着用个

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

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

    2023年04月24日
    浏览(67)
  • matlab读取pwm波数据,不用timer的方法,这里可以参考。Matlab/Simulink之STM32开发-编码器测速

    这里提供了一个不用timer的方法,可以参考: https://blog.csdn.net/weixin_36967309/article/details/88699830 Matlab/Simulink之STM32开发-编码器测速

    2024年01月18日
    浏览(55)
  • 【32单片机学习】(3)霍尔编码器减速直流电机控制及测速

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 1.实验现象 2.实验接线及原理图 接线图 原理图  电机接线图 3.代码部分 1.主函数  main.c 2.按键部分   key.c  key.h pwm代码   pwm.c  pwm.h 电机驱动   motor.c   motor.h  OLED显示 oled.c oled.h  编码器

    2024年02月11日
    浏览(58)
  • 编码器测速原理与实现

    通常情况下编码器旋转一周会输出固定的脉冲数,即编码器的分辨率,通过测量固定时间T内编码器输出的脉冲数即可求得电机的转速。 假设编码器的分辨率为P,T时间内测得脉冲数m个,则单倍频(编码器转动一圈输出的脉冲数与分辨率相同)情况下电机转速为: (其中m/p为

    2024年02月17日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包