智能车|直流电机、编码器与驱动器---编码器
- 编码器
- 编码器简介
- 编码器的工作原理
- 四倍频采集
- 编码器采集程序实现
编码器
编码器简介
编码器是一种将角位移或者直线位移转换成一连串电数字脉冲的一种传感器。
可以通过编码器测量电机转动的位移或者速度信息。
编码器按照工作原理,可以分为
- 增量式编码器
常用的编码器为增量式编码器 - 绝对式编码器
绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有
关,而与测量的中间过程无关。
从编码器检测原理上来分,还可以分为
- 光学式
- 磁式
- 感应式
- 电容式
常见的是光电编码器(光学式)和霍尔编码器(磁式)。一般来说光电编码器是霍尔编码器精度的几十倍。
编码器的工作原理
光电编码器是由光码盘和光电检测装置组成。光码盘是在一定直径的圆板上等分地开通若干个长方形孔。由于光电码盘与电动机同轴,电动机旋转时,检测装置检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。
霍尔编码器是由霍尔码盘和霍尔元件组成。霍尔码盘是在一定直径的圆板上等分地布置有不同的磁极。霍尔码盘与电动机同轴,电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。
然后就可以通过单片机采集 AB 相的脉冲数据,根据脉冲换算即可得到电机位置数据。
四倍频采集
四倍频是通过程序提升我们的编码器的精度的一种数据处理方法,可以有效的最大化我们的编码器的精度和测量精度。
上图是一个我们编码器输出的波形图,正常我们一般的处理方式是通过 A 相去计数,B 相去判断目前的转动方向。具体实现比如:A 相的上升沿计数或者下降沿计数,同时在 A 相的上升沿或者下降沿来根据 B 相此时的电平状态来判断转向。
四倍频则是同时计算 AB 两相的每个跳边沿,这样子原本在 A 相计数的一个脉冲周期内就实现了四次计数,从而实现了精度的提升。
编码器采集程序实现
因为编码器输出的是标准的正交方波,所以我们可以使用单片机(STM32 STM8 51等)直接读取。在软件中的处理方法是分两种,自带编码器接口的单片机如 STM32,可以直接使用编码器硬件接口(定时器 CH1&CH2)计数,然后从对应的寄存器读出相应的数据即可。没有编码器硬件接口的单片机,可以通过外部中断接口测量,比如把编码器 A 相输出接到单片机的外部中断接口,这样就可以通过跳边沿触发中断,然后在对应的中断服务函数里面,通过 B 相的电平来确定正反转。如当 A 相来一个跳变沿的时候,如果 B 相是高电平就认为是正转,低电平就认为是反转。
void Encoder_Init_TIM4(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个引脚初始化的结构体
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定义一个定时器初始化的结构体
TIM_ICInitTypeDef TIM_ICInitStructure; //定义一个定时器编码器模式初始化的结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能CPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //PB6、PB7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据GPIO_InitStructure的参数初始化GPIOB0
TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值
TIM_TimeBaseStructure.TIM_Prescaler = psc; // 预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //选择时钟分频:不分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct的参数初始化定时器TIM4
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3:CH1、CH2同时计数,四分频
TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入
TIM_ICInitStructure.TIM_ICFilter = 10; //设置滤波器长度
TIM_ICInit(TIM4, &TIM_ICInitStructure); //根TIM_ICInitStructure参数初始化定时器TIM4编码器模式
TIM_Cmd(TIM4, ENABLE); //使能定时器4
}
//读取编码器计数
int Read_Encoder_TIM4(void)
{
int Encoder_TIM;
Encoder_TIM=TIM4->CNT; //读取计数
if(Encoder_TIM>0xefff)Encoder_TIM=Encoder_TIM-0xffff; //转化计数值为有方向的值,大于0正转,小于0反转。
//TIM4->CNT范围为0-0xffff,初值为0。
TIM4->CNT=0; //读取完后计数清零
return Encoder_TIM; //返回值
}