平衡车不用编码器可以吗_编码器结构及工作原理

平衡车不用编码器可以吗_编码器结构及工作原理感觉用在平衡小车上的编码器相关的博文和资料都超级多的,不慌不慌

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

平衡小车——编码器原理及其使用

结合了一些帖子以及用的过程中出现的一些问题,然后归纳出来的一个贴子

一,编码器概述

编码器是一种将角位移或者角速度转换成一连串电数字脉冲的旋转式传感器,我们可以通过编码器测量到底位移或者速度信息。编码器从输出数据类型上分,可以分为增量式编码器和绝对式编码器。

从编码器检测原理上来分,还可以分为光学式、磁式、感应式、电容式。常见的是光电编码器(光学式)和霍尔编码器(磁式)。

二,编码器原理

光电编码器是一种通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。光电编码器是由光码盘和光电检测装置组成。光码盘是在一 定直径的圆板上等分地开通若干个长方形孔。由于光电码盘与电动机同轴,电动机旋转时,检测装置检测输出若干脉冲信号,为判断转向,一般输出两组存在一 定相位差的方波信号。

霍尔编码器是一种通过磁电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。霍尔编码器是由霍尔码盘和霍尔元件组成。霍尔码盘是在一 定直径的圆板上等分地布置有不同的磁极。霍尔码盘与电动机同轴,电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。

三,电机编码器接线

然后这下面就是讲的平衡车上的编码器啦。
车轮上有根线,最边上的两根是电机电源线,配合tb6612驱动,可用来控制电机的转速和转向。然后中间四根是编码器接口,如下图:
在这里插入图片描述
要注意哦~小车用的是两个编码器是反过来的,如果测试时车轮同向转,计数值互为相反数,就把AB相调换一下就好啦。或者把其中一个读到的数前面加个负号。

然后编码器供电是5v,供电问题,这是一款增量式输出的霍尔编码器。编码器有 AB 相输出,所以不仅可以测 速,还可以辨别转向。根据上图的接线说明可以看到,我们只需给编码器电源5V 供电,在电机转动的时候即可通过 AB 相输出方波信号。编码器自带了上拉电阻,所以无需外部上拉,可以直接连接到单片机 IO 读取。

当然不是说编码器就一定要用定时器做接口,有些单片机没有编码器接口的功能,也是可以用外部中断来代替。把编码器 A 相输出接到单片机的外部中断输入口,这样 就可通过跳变沿触发中断,然后在对应的外部中断服务函数里面,然后通过 B 相的电平来确定正转反转。A相当于一个跳变沿的时候,B相高电平就为是正转,低电平就为是反转。然后,普通io口也是可以处理的。

but用stm32做编码器接口的好处是计数比较智能,容许接口出现抖动而不影响结果。而且配置的代码超级多,拉过来就可以用啦。所以下面就是stm32定时器做编码器接口的介绍啦

四,定时器做编码器接口的配置方式

1,计数模式

在这里插入图片描述
在这里插入图片描述
如上两张图对应着来看呐,显然用T1,T2共同计数比较精确,也就是实现了“四倍频”

2,滤波等级

在这里插入图片描述

3,计数重装载值

就是对“TIM_TimeBaseStructure.TIM_Period”赋值,
在这里插入图片描述

这些都有写在代码的注释里面

五,stm32代码(库函数版)

void Encoder_Init_TIM2(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
	TIM_ICInitTypeDef TIM_ICInitStructure;  
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);					      

	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
	TIM_TimeBaseStructure.TIM_Prescaler = 0x0; 
	TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值,我设的是65536,最大只能是66536,stm32f103的寄存器只有16bit
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3,就是四分频计数模式
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_ICFilter = 10;// TIMx->CCMRx的位7:4,输入捕获1滤波器 ,IC1F用来滤波¨
	TIM_ICInit(TIM2, &TIM_ICInitStructure);
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

	TIM_SetCounter(TIM2,0);//设置CNT的值,初始化的时候从0开始计数
	TIM_Cmd(TIM2, ENABLE); 
}

/*TIM4初始化为编码器接口*/
void Encoder_Init_TIM4(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
	TIM_ICInitTypeDef TIM_ICInitStructure;  
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//使能定时器4的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;	//端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);					      //根据设定参数初始化GPIOB

	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
	TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 
	TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM向上计数  
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
	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_ClearFlag(TIM4, TIM_FLAG_Update);//清除TIM的更新标志位
	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
	//Reset counter
	TIM_SetCounter(TIM4,0);
	TIM_Cmd(TIM4, ENABLE); 
}

/*单位时间编码器计数 输入定时器 输出速度值*/
int Read_Encoder(u8 TIMX)
{
	int Encoder_TIM;    
	switch(TIMX)
	{
		case 2:  Encoder_TIM= (short)TIM2 -> CNT;  TIM2 -> CNT=0;break;//读数据+计数值清零
		case 3:  Encoder_TIM= (short)TIM3 -> CNT;  TIM3 -> CNT=0;break;	
		case 4:  Encoder_TIM= (short)TIM4 -> CNT;  TIM4 -> CNT=0;break;	
		default:  Encoder_TIM=0;
	}
	return Encoder_TIM;
}


/*中断服务函数,计数值溢出了就会进入中断,然后又会从0开始计数*/
void TIM4_IRQHandler(void)
{ 		    		  			    
	if(TIM4->SR&0X0001)//溢出中断
	{    				   				     	    	
	}				   
	TIM4->SR&=~(1<<0);//清除中断标志位 	    
}

void TIM2_IRQHandler(void)
{ 		    		  			    
	if(TIM2->SR&0X0001)//溢出中断
	{    				   				     	    	
	}				   
	TIM2->SR&=~(1<<0);//清除中断标志位 	    
}

六,注意点(这里是用的别人的~)

1.编码器有个转速上限,超过这个上限是不能正常工作的,这个是硬件的限制,原则上线数越多转速就越低,这点在选型时要注意,编码器的输出一般是开漏的,所以单片机的io一定要上拉输入状态.
2.定时器初始化好以后,任何时候CNT寄存器的值就是编码器的位置信息,正转他会加反转他会减这部分是不需要软件干预的,初始化时给的TIM_Period 值应该是码盘整圈的刻度值,在减溢出会自动修正为这个数.加超过此数值就回0.
3.如果要扩展成多圈计数需要溢出中断像楼主说的,程序上圈计数加减方向位就行了.
4.每个定时器的输入脚可以通过软件设定滤波
5.应用中如果没有绝对位置信号或者初始化完成后还没有收到绝对位置信号前的计数只能是相对计数.收到绝对位置信号后重新修改一次CNT的值就行了.码盘一般都有零位置信号,结合到定时器捕获输入就行.上电以后要往返运动一下找到这个位置.
6.即便有滤波计数值偶尔也会有出错误的情况,一圈多计一个或少计一个数都是很正常的特别是转速比较高的时候尤其明显,有个绝对位置信号做修正是很有必要的.绝对位置信号不需要一定在零位置点,收到这个信号就将CNT修正为一个固定的数值即可.
7.开启定时器的输入中断可以达到每个步计数都作处理的效果,但是高速运转的时候你可能处理不过来.

参考

https://blog.csdn.net/qq_17280755/article/details/73770598
https://blog.csdn.net/qq_38721302/article/details/83448078

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187054.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • EJB学习一

    EJB学习一一、一个企业级Bean是由几个文件共同组成:1、Bean类SessionBean实现javax.ejb.SessionBean接口;EntityBean实现javax.ejb.EntityBean接口。2、EJB接口(远程接口或者本地接口)和EJB对象远程接口继承javax.ejb.EJBObject接口;本地接口继承javax.ejb.EJBLocalObject接口。3、Home接口(远程…

    2022年9月1日
    0
  • Linux终端删除文件夹命令「建议收藏」

    Linux终端删除文件夹命令「建议收藏」前言本文介绍Linux系统中删除文件夹的命令,包括:rmdir、rm。Linux系统下删除文件夹是一个非常高频的需求,有很多方法可以删除文件夹,比如使用图形界面,或者通过终端删除。本文将介绍在Linux命令行下使用命令删除文件夹。1.使用rmdir命令删除文件夹rmdir命令是英文单词removedirectory的缩写,主要作用是删除文件夹。但是请注意,该命令只能用于删除空文件夹,而如果文件夹非空的话,将会报错。$rmdirdatarmdir:fai..

    2022年7月13日
    39
  • linux复制文件到当前目录并重命名_Linux复制文件到当前文件夹

    linux复制文件到当前目录并重命名_Linux复制文件到当前文件夹./表示当前目录cptest/*.wav./-r递归子目录cp-r绝对路径/文件目标路径cp-r绝对路径/*.wav目标路径copy一个目录下的所有文件以及递归文件到当前文件夹cp-raudios/*./

    2022年8月23日
    5
  • python每天定时9点执行_python定时执行方法

    python每天定时9点执行_python定时执行方法1time.sleepimporttimeforiinrange(5):print(i)time.sleep(10)2用shedimporttimeimportschedschedule=sched.scheduler(time.time,time.sleep)deffunc(string1,float1):print(“nowis”,time.time(),”…

    2022年7月17日
    23
  • 分享6个国内优秀Java后台管理框架的开源项目,建议shou藏

    分享6个国内优秀Java后台管理框架的开源项目,建议shou藏相关阅读:阿里P7/P8学习路线图——技术封神之路宁愿月薪1万招新人,却不愿给月薪5千的老员工涨薪互联网技术(java框架、分布式、集群)干货视频大全,不看后悔!(免费下…

    2022年7月19日
    16
  • appnode默认关闭allow_url_fopen,导致无法使用file_get_contents

    appnode默认关闭allow_url_fopen,导致无法使用file_get_contents一、全局设置网站管理-运行环境管理-默认参数-php-php安全二、单站设置网站管理-选中网站-php-php安全

    2022年7月21日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号