编码器是什么玩意呢,它可是一个好玩的东西,做小车测速必不可少的玩意,下面,我将从编码器的原理讲起,一直到用stm32的编码器接口模式,测出电机转速与方向。
1.编码器
图1 编码器示意图
图1为编码器的示意图,中间是一个带光栅的码盘,光通过光栅,接收管接收到高电平,没通过,接收到低电平。电机旋转一圈,码盘上有多少光栅,接受管就会接收多少个高电平。371电机中的码盘就是这样的,他是334线码盘,具有较高的测速精度,也就是电机转一圈输出334个脉冲,芯片上已集成了脉冲整形触发电路,输出的是矩形波,直接接单片机IO就OK。
增量式旋转编码器通过内部两个光敏接受管转化其角度码盘的时序和相位关系,得到其角度码盘角度位移量增加(正方向)或减少(负方向)。下图为编码器的原理图:
图2 增量式旋转编码器
A,B两点对应两个光敏接受管,A,B两点间距为 S2 ,码盘的光栅间距分别为S0和S1。S0+S1的距离是S2的四倍。这样保证了A,B波形相位相差90度。旋转的反向不同,锯齿波A,B先到达高电平的顺序就会不同,如上图左侧所示,顺序的不同,就可以得到旋转的方向。
2.stm32编码器接口模式(寄存器)
stm32的编码器接口模式在STM32中文参考手册中有详细的说明,在手册273页,14.3.12节。程序是完全按照 下图方式,设置寄存器的。
图3
从图3中可以看出,TI1波形先于TI2波形90°时,每遇到一个边沿变化是,计数器加1(可以通过寄存器设置加减),可以看出一个光栅,被计数了4次。TI1波形后于TI2波形90°时 ,每遇到一次边沿变化,计数器减1。
//TIM2_Encoder_Init,Tim2_CH1(PA0);Tim2_CH2(PA1)
//arr:自动重装值 0XFFFF
//psc:时钟预分频数 ,不分频
void TIM2_Encoder_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0XFFFFFF00; //PA0、PA1 清除之前设置
GPIOA->CRL|=0X00000044; //PA0、PA1 浮空输入
TIM2->ARR=arr; //设定计数器自动重装值
TIM2->PSC=psc; //预分频器
TIM2->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM2->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM2->CCER |= 0<<1; //IC1不反向
TIM2->CCER |= 0<<5; //IC2不反向
TIM2->SMCR |= 3<<0; //所用输入均在上升沿或下降沿有效
TIM2->CR1 |= 1<<0; //使能计数器
}
3 硬件
用到的模块有STM32核心板、L298电机驱动、371带编码器电机(1:34)。这里主要介绍一下电机,1:34指的是电机轴转动34圈,电机输出1圈。1:X,X值越小,电机的输出转速也就越快,扭矩也就越小;反之,X值越大,电机的输出转速越慢,扭矩也越大。
图4 电机实物图
左边两根黄线是电机两极。绿线和白线是脉冲输出线,分别接编码器的接收管A、B,用一根可以测得速度,两根同时用可测出电机速度与转向。红线和黑线是编码器电源接线,红正黑负,电压3.3V-5V,不不可接反。
4 控制代码
工作指示灯、电机方向与速度控制代码。
//LED IO 初始化 端口PD.2 运行指示灯
void LED_Init(void)
{
RCC->APB2ENR|=1<<5; //使能PORTD时钟
GPIOD->CRL&=0XFFFFF0FF;
GPIOD->CRL|=0X00000300; //PD.2推挽输出
GPIOD->ODR|=1<<2; //PD.2输出高
}
//电机旋转方向控制信号端口初始化
//PC1~0推挽输出,输出高
void M_Init(void)
{
RCC->APB2ENR|=1<<4; //使能PORTC时钟
GPIOC->CRL&=0XFFFFFF00;
GPIOC->CRL|=0X00000033; //PC1~0推挽输出
GPIOC->ODR|=0XF<<0; //PC1~0输出高电平
}
//定时器TIM3,PWM输出初始化,CH1(PA6)
//arr:自动重装值
//psc:时钟预分频数
//设置自动重装值为900,那么PWM频率=72000/900=8Khz
////见STM32参考手册,14.3.9PWM模式。
void TIM3_PWM_Init(u16 arr,u16 psc) //arr设定计数器自动重装值
//psc预分频器不分频,psc=0
{
RCC->APB1ENR|=1<<1; //TIM3时钟使能
GPIOA->CRL&=0XF0FFFFFF;//PA6输出
GPIOA->CRL|=0X0B000000;//复用功能输出
GPIOA->ODR|=1<<6;//PA6上拉
TIM3->ARR=arr;//设定计数器自动重装值
TIM3->PSC=psc;//预分频器不分频
TIM3->CCMR1|=6<<4; //CH1 PWM1模式 高电平有效
TIM3->CCMR1|=1<<3; //CH1预装载使能
TIM3->CCER|=1<<0; //OC1 输出使能
TIM3->CR1=0x0080; //ARPE使能
TIM3->CR1|=0x01; //使能定时器3
}
//电机方向与速度控制,速度调节范围为-100~+100
//大于0时,正转,小于0时,反转
// 占空比低于0.4时电机不转
//(占空比是指高电平在一个周期之内所占的时间比率)
//TIM3->CCR1的设定范围为0~900(因为arr=900)
//见STM32参考手册,14.3.9PWM模式。
void Motor_Speed_Control(s16 motorSpeed)
{
s16 speed = 0 ;
if(motorSpeed>100) speed = 100;
else if (motorSpeed<-100) speed = -100;
else speed = motorSpeed;
if(speed == 0)
{
M_1 = 0;
M_2 = 0;
}
else if(speed > 0)
{
M_1 = 0;
M_2 = 1;
TIM3->CCR1 = speed * 9;
}
else
{
M_1 = 1;
M_2 = 0;
TIM3->CCR1 = -speed * 9;
}
}
电机速度与方向检测代码
//TIM2_Encoder_Init,Tim2_CH1(PA0);Tim2_CH2(PA1)
//arr:自动重装值 0XFFFF
//psc:时钟预分频数 ,不分频
//见STM32中文手册 14.3.12编码器接口模式
void TIM2_Encoder_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->APB2ENR|=1<<2; //使能PORTA时钟
GPIOA->CRL&=0XFFFFFF00; //PA0、PA1 清除之前设置
GPIOA->CRL|=0X00000044; //PA0、PA1 浮空输入
TIM2->ARR=arr; //设定计数器自动重装值
TIM2->PSC=psc; //预分频器
TIM2->CCMR1 |= 1<<0; //输入模式,IC1FP1映射到TI1上
TIM2->CCMR1 |= 1<<8; //输入模式,IC2FP2映射到TI2上
TIM2->CCER |= 0<<1; //IC1不反向
TIM2->CCER |= 0<<5; //IC2不反向
TIM2->SMCR |= 3<<0; //所用输入均在上升沿或下降沿有效
TIM2->CR1 |= 1<<0; //使能计数器
}
//计数寄存器赋值
void TIM2_Encoder_Write(int data)
{
TIM2->CNT = data;
}
//读计数个数
int TIM2_Encoder_Read(void)
{
TIM2_Encoder_Write(0); //计数器清0
delay_ms(10); //检测时间,可调节
return (int)((s16)(TIM2->CNT)); //数据类型转换
//记录边沿变化次数(一个栅格被记录4次)
}
复制代码
这里我们只显示边沿变化次数,没有具体的算出速度。
主函数
int main(void)
{
// motorSpeed的范围为-100 ~ +100;
s16 motorSpeed = 100;
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口1初始化
LED_Init(); //初始化与LED连接的硬件接口
M_Init(); ////初始化电机运行方向控制端口
TIM3_PWM_Init(900,0); //不分频。PWM频率=72000/900=8Khz
TIM2_Encoder_Init(0xffff, 0); //计数器自动重装值为最大
while(1)
{
LED =! LED;
Motor_Speed_Control(motorSpeed);
printf("编码器值:%d\n ",TIM2_Encoder_Read());
}
}
5 估算验证
这里我们只是大概的估算验证测量值是否正确,不具有完全正确性。
我们设置motorSpeed = 100 ,得到测量值如下图:
图5 motorSpeed = 100
因为误差是不可避免的,所以看到每次检测的值都是不一样的。我们取462,因为一个光栅被记录了4次,所以在10ms内一共检测到了462/4=115.5,那么得到11.55个/ms,每ms内检测到11.55个光栅。
通过码表,记录电机输出50圈,用时50.2s,那么这时应该检测到的光栅个数为50*34(电机转34圈,输出1圈)*334(每圈有334个光栅)=567800,除以时间,得到估算值11.31个/ms。可以看出估算值与测量值是相近的,认为测量是准确的。
设置motorSpeed = -50 ,得到测量值如下图 :
图6 motorSpeed=-50
可以看到测量值是负值,说明电机是反转,与实际设置相符。
我们读的是计数器TIM2->CNT中的值,此值为什么会是负的,这里为什么这样用? 编码器模式中使用上下计数,假设我们初始化TIM2_Encoder_Init_1(0xff, 0);自动装载值为0xFF,这时,计数器中的值,就会在0x00与0xFF之间循环变化,由0x01减为0x00,再减1时,计数器中的值为0xFF,我们将此数做为有符型整数处理,当然,计数的前提是每个周期的计数个数不能超过0x7F,超过,计数将不准确。
符号强制转换,return (int)((s16)(TIM2->CNT));里面有个类型转换,强制转换返回有符型数据。数值都是以补码表示的,正整数补码是源码,负整数补码是绝对值取反加1。向下计数时减1,为0时,就需要向高位借位减“1”,可以这样理解,一个8位数00000000B-00000001B,但0不够减1的,就向不存在的第9位借1,100000000B-00000001B=11111111B,数是以补码形式表示的,这样11111111B就为-1了。
在例程中,初始化自动重装值为0xFFFF可以做个实验,直接输出TIM2->CNT的值看一下: printf("编码器值1:%x \r\n",TIM2->CNT)。
上一篇:STM32的16位编码器溢出问题
下一篇:STM32对码盘的正交信号处理
推荐阅读
史海拾趣
浙江东亚电子注重企业文化的建设,致力于为员工提供一个良好的工作环境和发展平台。公司关注员工的学习和成长,为员工提供持续长效的发展机会和有竞争力的薪酬。同时,公司还积极开展各类文化活动和社会公益活动,增强员工的归属感和凝聚力。
这些故事框架展示了浙江东亚电子在电子行业中发展起来的几个重要方面。通过技术创新、产业布局拓展、国际市场开拓、品质管理提升和企业文化建设等方面的努力,公司不断壮大自身实力,成为行业内的佼佼者。
在电子行业的激烈竞争中,Electrolube公司始终坚持以客户需求为导向,不断创新和拓展产品线。除了UVCL涂层外,公司还推出了一系列树脂、涂料和热管理解决方案的产品组合,为EV电池提供全面保护。
这些产品不仅具有优异的性能表现,而且能够满足不同客户的需求。例如,某些产品具有优异的耐高温性能,适用于高温环境下的电子设备;而另一些产品则具有出色的耐化学腐蚀性能,能够在恶劣的工作环境中保持稳定的性能。
Electrolube公司通过不断的技术创新和产品优化,成功拓展了市场份额,并在电子行业中树立了良好的品牌形象。同时,公司还积极与各大汽车制造商合作,共同推动电动汽车产业的发展。
在20世纪90年代初,Herga公司凭借其在精密电机技术上的突破,成功研发出一款高效能、低噪音的步进电机,迅速在自动化设备和电子设备市场中脱颖而出。这款电机不仅提高了生产效率,还显著降低了能耗和噪音水平,赢得了众多知名电子制造商的青睐。Herga公司借此机会,进一步拓展产品线,逐步确立了在电子行业精密传动组件领域的领先地位。
随着产品技术的成熟和市场需求的增长,Delus Corp公司开始积极拓展市场。公司不仅在国内市场取得了显著成绩,还通过参加国际展览、建立海外销售网络等方式,成功打入国际市场。此外,公司还与国际知名企业开展合作,共同研发新产品,进一步提升了公司的国际竞争力。
海芯科技自创立以来,一直秉持着创新和技术的核心理念。在公司的初期阶段,创始人凭借其丰富的行业经验和敏锐的市场洞察力,成功吸引了一批技术精湛、充满激情的团队成员。这些成员在各自的领域里都有深厚的背景和出色的能力,他们共同构成了海芯科技的核心研发团队。在公司的发展初期,这支团队便通过不断地技术创新和研发,为公司后续的发展奠定了坚实的基础。
Deltron Emcon,即现在的DEM Manufacturing,起源于四家英国制造企业的合并。这些企业分别是成立于1946年的Deltron Components,专业音频连接器和压铸盒制造商Roxburgh EMC(成立于1969年),EMC滤波器和组件的制造商Media Products(成立于1990年),以及广播跳线产品制造商BES Electronics(成立于1982年)。这些公司在各自的领域内都有着丰富的经验和卓越的技术,合并后,DEM Manufacturing凭借这些优势,在电子行业中迅速崭露头角。
RTOS应用程序开发指南,大量实例!!!! 一个自己写的RTOS,运行起来很不错,使用与51等RAM,ROM小容量的单片机 转自 ouravr… 查看全部问答∨ |
|
DS18B20的N个问题彻底解决,感慨万千,写出来让大家共享。 问题: 1、有的DS18B20初始化困难,读数始终为85度。 2、温度读数不平滑,比如2次值:15度 25读的变化,而环境温度基本无变化。 3、系统中有DS18B20的时候频繁自动重启动。 解决: 我 ...… 查看全部问答∨ |
|
这些造型酷似气泡的LED灯泡可以挂在天花板上作吊灯使用。每当需要排解压力的时候,这款灯泡正好能成你的发泄道具。挤按的时候,灯泡表面不仅会凹陷进去,还会发出“呜呜”的声音,非常可爱。… 查看全部问答∨ |