平衡小车—编码器使用教程与测速原理
时间:2023-12-23 14:37:01
文章目录
-
- 1.编码器概述
- 2.编码器原理
- 3.编码器接线说明
- 4.编码器软件四倍频技术
- 5.单片机如何收集编码器数据?
- 6.获取方式
来自平衡汽车之家,学习编码器的使用和测速原理。
1.编码器概述
??编码器是一种旋转传感器,将角位移或角速转换为一系列电数字脉冲。我们可以通过编码器测量位移或速度信息。编码器可分为增量编码器和绝对编码器。
??从编码器检测原理来看,也可分为光学、磁性、感应和电容。常见的是光电编码器(光学)和霍尔编码器(磁性)。
2.编码器原理
??光电编码器是一种通过光电转换将输出轴上的机械几何位移转换为脉冲或数字量的传感器。光电编码器由光盘和光电检测装置组成。光盘在一定直径的圆板上打开多个矩形孔。由于光电码盘与电机同轴,当电机旋转时,检测装置检测输出多个脉冲信号。为了判断转向,通常输出两组具有一定相位差的方波信号。
??霍尔编码器是一种通过磁电转换将输出轴上的机械几何位移转换为脉冲或数字的传感器。霍尔编码器由霍尔代码盘和霍尔元件组成。霍尔代码盘在一定直径的圆板上等分布置不同的磁极。霍尔代码盘与电机同轴。当电机旋转时,霍尔元件检测输出多个脉冲信号。为了判断转向,通常输出两组方波信号。
??可以看出,编码器的目的是获取两个原理AB方波信号的使用方法相同,以下是一个简单的示意图。
谈谈增量旋转编码器的工作原理,然后打开编码器查看内部结构
3.编码器接线说明
??对于我们的编码器电机,我们可以看到电机编码器的实物。
??这是霍尔编码器的增量输出。编码器有AB相输出,不仅可以测量速度,还可以识别转向。根据上图的接线说明,我们只需要给编码器5电源V电源可以在电机旋转时通过AB相输出方波信号。编码器有自己的上拉电阻,可以直接连接到单片机,无需外部上拉。IO读取。
4.编码器软件四倍频技术
??让我们谈谈编码器倍频的原理。为了提高您对以下学习的兴趣,我们首先明确表示,这是一项实用技术,可以真正提高编码器的精度4倍。其功能可以类似于单反相机的光学变焦,而不是牺牲清晰度来扩大图像的数字变焦。
??0K,先看下面编码器输出的波形图。
??在这里,我们通过软件实现四倍频率。首先,你可以看到上面的编码器输出AB在正常情况下,当我们使用M法测量速度时,速度信息将通过测量单位时间内A相输出的脉冲数来获得。在常规方法中,我们只测量A相(或B相)的上升或下降,即上图中对应数字1234中的一个,只能计数三次。四倍频的方法是测量A相和B相编码器的上下边缘。这样可以在同一时间内计数12次(3个1234循环)。这就是软件四倍频的原理。
***********************************************************************
*
*
*
/
/************************************************************************** 函数功能:把TIM2初始化为编码器接口模式 入口参数:无 返回 值:无 **************************************************************************/
void
Encoder_Init_TIM2
(
void
)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure
; TIM_ICInitTypeDef TIM_ICInitStructure
; GPIO_InitTypeDef GPIO_InitStructure
;
RCC_APB1PeriphClockCmd
(RCC_APB1Periph_TIM2
, ENABLE
)
;
//使能定时器2的时钟
RCC_APB2PeriphClockCmd
(RCC_APB2Periph_GPIOA
, ENABLE
)
;
//使能PB端口时钟 GPIO_InitStructure
.GPIO_Pin
= GPIO_Pin_0
|GPIO_Pin_1
;
//端口配置 GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IN_FLOATING
;
//浮空输入
GPIO_Init
(GPIOA
,
&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
(TIM2
,
&TIM_TimeBaseStructure
)
;
TIM_EncoderInterfaceConfig
(TIM2
, TIM_EncoderMode_TI12
, TIM_ICPolarity_Rising
, TIM_ICPolarity_Rising
)
;
//使用编码器模式3,模式3就我们在这里所说的4倍频,详细信息查看stm32f1技术手册
TIM_ICStructInit
(
&TIM_ICInitStructure
)
; TIM_ICInitStructure
.TIM_ICFilter
=
10
;
TIM_ICInit
(TIM2
,
&TIM_ICInitStructure
)
;
TIM_ClearFlag
(TIM2
, TIM_FLAG_Update
)
;
//清除TIM的更新标志位
TIM_ITConfig
(TIM2
, TIM_IT_Update
, ENABLE
)
;
//Reset counter
TIM_SetCounter
(TIM2
,
0
)
;
TIM_Cmd
(TIM2
, ENABLE
)
;
}
/************************************************************************** 函数功能:把TIM4初始化为编码器接口模式 和TIM2同理 入口参数:无 返回 值:无 **************************************************************************/
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
)
;
}
5.单片机如何采集编码器数据
因为编码器输出的是标准的方波,所以我们可以使用单片机(STM32\STM851等)直接读取。在软件中的处理方法是分两种,自带编码器接口的单片机如STM32,可以直接使用硬件计数。而没有编码器接口的单片机如51单片机,可以通过外部中断读取,比如把编码器A相输出接到单片机的外部中断输入口,这样就可通过跳变沿触发中断,然后在对应的外部中断服务函数里面,通过B相的电平来确定正反转。如当A相来一个跳变沿的时候,如果B相是高电平就认为是正转,低电平就认为是反转。
/************************************************************************** 函数功能:单位时间读取编码器计数 入口参数:定时器 返回 值:速度值 **************************************************************************/
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;
}
/************************************************************************** 函数功能:TIM4中断服务函数 入口参数:无 返回 值:无 **************************************************************************/
void TIM4_IRQHandler(void)
{
if(TIM4->SR&0X0001)//溢出中断
{
}
TIM4->SR&=~(1<<0);//清除中断标志位
}
/************************************************************************** 函数功能:TIM2中断服务函数 入口参数:无 返回 值:无 **************************************************************************/
void TIM2_IRQHandler(void)
{
if(TIM2->SR&0X0001)//溢出中断
{
}
TIM2->SR&=~(1<<0);//清除中断标志位
}
6.获取方式
测试编码器代码获取方式,关注微信公众号:果果小师弟,后套回复:编码器。即可获取STM32测试编码器代码。