OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8184|回复: 24

编码器测速问题求助

[复制链接]

3

主题

9

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2014-5-7
在线时间
0 小时
发表于 2014-5-8 10:54:19 | 显示全部楼层 |阅读模式
5金钱

[mw_shl_code=c,true]int main(void) { u8 t; u8 len; u16 times=0; Init_All_Periph(); SysTick_Initaize(); STM_EVAL_LEDOff(LED1); STM_EVAL_LEDOff(LED2); TIM_Init(); while(1) { delay_ms(500); encoder_num=TIM_GetCounter(TIM3); printf("编码器数据是%d\n\t",encoder_num); } [/mw_shl_code]
[mw_shl_code=c,true]void TIM3_Mode_Config(void) { //u16 CCR1_Val = 2500; //u16 CCR2_Val = 1000; GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; //TIM_OCInitTypeDef TIM_OCInitStructure; /*----------------------------------------------------------------*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_StructInit(&GPIO_InitStructure); /* Configure PA.06,07 as encoder input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /*----------------------------------------------------------------*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3 TIM_DeInit(TIM3); TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period =0xffff; // TIM_TimeBaseStructure.TIM_Prescaler =0; //设置预分频: TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1 ; //设置时钟分频系数:不分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 //TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; /*初始化TIM2定时器 */ TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /*-----------------------------------------------------------------*/ //编码配置 编码模式 TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //TIM_ICPolarity_Rising上升沿捕获 TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_ICFilter = 6; //比较滤波器 TIM_ICInit(TIM3, &TIM_ICInitStructure); //TIM_ARRPreloadConfig(TIM3, ENABLE); // Clear all pending interrupts TIM_ClearFlag(TIM3, TIM_FLAG_Update); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能中断 //Reset counter TIM3->CNT =0; TIM_Cmd(TIM3, ENABLE); //使能定时器3 } void TIM_Init(void) { TIM3_Mode_Config(); }[/mw_shl_code]
小弟现在如图能测出编码器的输出脉冲数 是实际输出脉冲的4倍,但是小弟现在想通过串口显示我转速的实时速度,有没有人能指导我关于速度代码的编写最好是T法测速

最佳答案

查看完整内容[请看2#楼]

正交编码器=增量式编码器...................看得我=.=!! 我们行内多数叫增量式编码器,编码器一般有两种,一种叫增量式编码器,一种叫绝对值编码器。要搞运动控制,最好用CPLD。一个小片片能控制几十个步进电机,直流电机(PMW也行),伺服电机...........还能和上位机交换数据及用编码器实时回馈。最重要的是并行处理。很好玩的。 原子老大可以搞一个简单运动控制的代码吸引一新手玩机器人的兴趣呀。关键是又多了一个卖点嘛。 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
发表于 2014-5-8 10:54:20 | 显示全部楼层
正交编码器=增量式编码器...................看得我=.=!!

我们行内多数叫增量式编码器,编码器一般有两种,一种叫增量式编码器,一种叫绝对值编码器。要搞运动控制,最好用CPLD。一个小片片能控制几十个步进电机,直流电机(PMW也行),伺服电机...........还能和上位机交换数据及用编码器实时回馈。最重要的是并行处理。很好玩的。

原子老大可以搞一个简单运动控制的代码吸引一新手玩机器人的兴趣呀。关键是又多了一个卖点嘛。又可以卖步进电机,编码器,丝杆,光电传感器......................

近来老婆吵着要住新房,我清理了做了十几年的仓库,我做二手设备时留下了三层楼的日本精密机器部件。足足拆了我半个月,拆了1K多个各种各样的电机出来,光步进电机都有600多个。有很多是自带步进电机的。还有各种传动丝杆,直线导轨,几大箩光电传感器,几十个自动变焦镜头..............我在想是不是重操旧业,从日本弄一些精密机器回来拆了开间创客零件专门店.................同学们认不认为有点搞头??
=.=V
我的工作就是天天在玩
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-5-8 14:12:25 | 显示全部楼层
脉冲数可以先用示波器看看,再对比下.
速度,你开个定时器,统计1秒钟内的脉冲数,就可以计算了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2014-5-10
在线时间
4 小时
发表于 2014-5-10 22:30:23 | 显示全部楼层
哥们我也在做正交编码器  能给我一下你程序么  我qq243901712@qq.com   谢谢啦
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2014-5-10
在线时间
4 小时
发表于 2014-5-10 22:31:05 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
强烈建议原子哥出一个关于正交编码器的视频
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-5-11 00:01:29 | 显示全部楼层
回复【4楼】小刺猬:
---------------------------------
有时间再高。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
发表于 2014-5-11 00:26:44 | 显示全部楼层
运动控制器不单要用编码器,还要用AD转换得到电机的电流(可以组合机械部件换算成扭矩),然后用PMW控制转速
我的工作就是天天在玩
回复

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2014-5-11 00:37:44 | 显示全部楼层
回复【7楼】chinafox:
---------------------------------
业内哦.

正交编码器<增量式编码器.

增量式编码器还有走SSI协议等串行协议的,当然还有走私有协议的,典型代表是多磨川.霍尼韦尔走标准协议.>
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复

使用道具 举报

47

主题

360

帖子

0

精华

高级会员

Rank: 4

积分
726
金钱
726
注册时间
2014-3-6
在线时间
19 小时
发表于 2014-5-11 00:40:07 | 显示全部楼层
回复【6楼】chinafox:
---------------------------------
要是能提供技术支持的话,例如提供方法怎样组装成玩具呀,提供源程序呀,应该有搞头。总觉得只卖零件挣不了多少。话说有三层楼的部件。。。太夸张了吧- -
成长不是衣服越来越小,裤子越来越短,而是心和梦想一起越来越大!
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2014-5-10
在线时间
4 小时
发表于 2014-5-11 11:51:54 | 显示全部楼层
回复【6楼】chinafox:
---------------------------------老师是土豪呀
回复

使用道具 举报

4

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2013-8-11
在线时间
25 小时
发表于 2014-5-11 12:35:44 | 显示全部楼层
开一个1ms定时器中断,中断服务函数里计算脉冲的增量,每分钟转速=脉冲增量*1000*60/(编码器线数*4)
回复

使用道具 举报

4

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
185
金钱
185
注册时间
2013-8-11
在线时间
25 小时
发表于 2014-5-11 12:36:36 | 显示全部楼层
你那delay(500)太长了。。。。。
回复

使用道具 举报

3

主题

27

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
240
金钱
240
注册时间
2014-5-11
在线时间
5 小时
发表于 2014-5-11 13:45:15 | 显示全部楼层
这个当时学校做机器人的时候做过,用的STM32 + EPM570的方案,控制两路减速电机带正交编码,三路舵机,8路超声测距。
正交编码可以直接用STM32的Timer计数,然后直接读计数值差值就可以得到固定周期脉冲数。
回复

使用道具 举报

3

主题

9

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2014-5-7
在线时间
0 小时
 楼主| 发表于 2014-5-11 18:26:23 | 显示全部楼层
回复【11楼】holmesds:
---------------------------------
谢谢 我再试试
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-5-11 19:40:30 | 显示全部楼层
回复【6楼】chinafox:
---------------------------------
有搞头....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
发表于 2014-5-12 02:04:04 | 显示全部楼层
编码器的输出波型有几种:
编码器输出一般有4条,一条是电源正极,一条是电源负极,一条输出A,一条输出B。

1: A输出计数方波。B输出方向(高电平或底电平,看器件定义,正向为高电平,反向为底电平)
2: A,B都输出计数方波,如果A超前90度为正向,落后90度为反向。

有些器件的A,B输出是差分输出,这样就变6条线了。这个可以用75176变成单线的方波接MCU。差分输出很抗干扰的。
我的工作就是天天在玩
回复

使用道具 举报

71

主题

467

帖子

0

精华

高级会员

Rank: 4

积分
800
金钱
800
注册时间
2011-11-18
在线时间
5 小时
发表于 2014-5-12 02:09:12 | 显示全部楼层
我用得最多的是安川伺服,一圈下来有2的24次方个方波......................精度都超过了我精磨的辊了=.=!!
我的工作就是天天在玩
回复

使用道具 举报

20

主题

118

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2014-3-23
在线时间
22 小时
发表于 2014-8-13 15:58:57 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
为什么只能抄一方向转,当朝一个方向转了增加一些数据,然后在反向转回来到零就中断了啊,串口就不发送数据了怎么回事啊
回复

使用道具 举报

20

主题

118

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2014-3-23
在线时间
22 小时
发表于 2014-8-13 17:41:46 | 显示全部楼层
楼主及原子哥我这个数据变化对吗,显示的是正转增加反转减小到零然后直接到65336在开始减小,要是这样不太好测速啊
QQ截图20140813173830.png
回复

使用道具 举报

3

主题

9

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2014-5-7
在线时间
0 小时
 楼主| 发表于 2014-8-13 21:58:33 | 显示全部楼层
理论是这样的,但是65535只是计数器位数限制的上限,我后面采用了2个定时器来采样 第一个定时器来计数总脉冲数 第二定时器来周期采样定时器1中的计数值 通过算法计算速度 成功测出速度。
回复

使用道具 举报

3

主题

9

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2014-5-7
在线时间
0 小时
 楼主| 发表于 2014-8-13 22:13:17 | 显示全部楼层


你可以看到我用了TIM2 和TIM3两个定时器 一个定时器用来计数总的得到脉冲值 一个在预设分频值后周期进入终端来采样计算、


还要记得输出当前速度后去清空定时器中的值否则会累加计算出错误的速度
回复

使用道具 举报

20

主题

118

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2014-3-23
在线时间
22 小时
发表于 2014-8-13 22:28:52 | 显示全部楼层
回复【21楼】二蛋先生:
---------------------------------
楼主你上面的代码没这么设置啊,你能不能把你的代码上传上来啊
回复

使用道具 举报

3

主题

9

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2014-5-7
在线时间
0 小时
 楼主| 发表于 2014-8-13 22:35:07 | 显示全部楼层
[mw_shl_code=c,true]/******************************************************************************** 快乐的实验室 *******************************************************************************/ #include "encoder.h" #define ENCODER1_TIMER TIM3 // Encoder1 unit connected to TIM2 PA0 PA1 #define ENCODER_PPR1 (u16)(1000) // number of pulses per revolution uint16_t conter1 =0;//vu16表示__IO uint16_t // //volatile unsigned short Counter1表示vu16 __IO int16_t Encoder_Speed1 =0; //使用了tim4和tim5两个编码器模式,分别为这里耳朵2和1 //vs16表示__IO int16_t //typedef signed short int int16_t; //#define __IO volatile /*!< defines 'read / write' permissions */ //volatile signed short Counter2表示vs16 //volatile s16 encoder_num; // void TIM2_Mode_Config(void) // { // TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM3 // TIM_TimeBaseStructure.TIM_Period =5000; //当定时器从0计数到999,即为1000次,为一个定时周期 // TIM_TimeBaseStructure.TIM_Prescaler =7200-1; //设置预分频: // TIM_TimeBaseStructure.TIM_ClockDivision =0 ; //设置时钟分频系数:不分频 // TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 // /*初始化TIM2定时器 */ // TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // /* 使能TIM2中断 */ // TIM_ITConfig(TIM2,TIM_IT_Update, ENABLE); // /* 使能TIM2定时器 */ // TIM_Cmd(TIM2, ENABLE); // } void TIM3_Mode_Config(void) { //u16 CCR1_Val = 2500; //u16 CCR2_Val = 1000; GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; //TIM_OCInitTypeDef TIM_OCInitStructure; /*----------------------------------------------------------------*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_StructInit(&GPIO_InitStructure); /* Configure PA.06,07 as encoder input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /*----------------------------------------------------------------*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3 TIM_DeInit(TIM3); TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period =0xffff; // TIM_TimeBaseStructure.TIM_Prescaler =0; //设置预分频: TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1 ; //设置时钟分频系数:不分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 //TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; /*初始化TIM2定时器 */ TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /*-----------------------------------------------------------------*/ //编码配置 编码模式 TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //TIM_ICPolarity_Rising上升沿捕获 TIM_ICStructInit(&TIM_ICInitStructure); TIM_ICInitStructure.TIM_ICFilter = 6; //比较滤波器 TIM_ICInit(TIM3, &TIM_ICInitStructure); //TIM_ARRPreloadConfig(TIM3, ENABLE); // Clear all pending interrupts TIM_ClearFlag(TIM3, TIM_FLAG_Update); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能中断 //Reset counter TIM3->CNT =0; TIM_Cmd(TIM3, ENABLE); //使能定时器3 } void TIM_Init(void) { TIM3_Mode_Config(); } void TIM2_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStruct; RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE);//使能定时器2的时钟 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_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能定时器2的中断 NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority=3;//响应优先级 NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStruct);//按照配置参数初始化 TIM_Cmd(TIM2,ENABLE);//使能定时器2外设 } //定时器2的中断响应函数 //每次进入中断服务程序间隔时间为0.1秒 void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)//检查指定的定时器3中断发生与否 TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除定时器3的中断待处理位 conter1 = TIM_GetCounter(TIM3);//获得TIM3的计数器的数值 Encoder_Speed1 = (3*conter1)/20;//-32767;//1500*(Counter1-32767)/ENCODER_PPR1 ;//15*(Counter1-32767)/4; printf("电机转速%d\r\n",Encoder_Speed1);//串口终端上显示获得的电机转速n,单位为r/min // PIDSetPoint(MOTER1_PID ,1500);//设定PID目标值,输入参数为转速的目标值 // bike_left_pwm_set(PIDCalc(MOTER1_PID , Encoder_Speed1));//输入参数为计算出的转速,输出为驱动电机转动的PWM // bike_right_pwm_set(PIDCalc(MOTER1_PID , Encoder_Speed1)); // printf("Counter1 =%d\r\n",TIM_GetCounter(TIM2));//串口终端上显示获得的编码器脉冲数 // printf("Encoder_Speed1 =%d\r\n",(Counter1)/4000);//串口终端上显示获得的电机转速n,单位为r/min // // *Counter1)/64);//串口终端上显示获得的电机转速n,单位为r/min //USART1_SendLine(PIDCalc(MOTER1_PID , Encoder_Speed1),0,1); ////USART1_SendLine(Counter1,0,2); // // GPIO_ResetBits(GPIOA,GPIO_Pin_8); TIM2->CNT = 0;//定时器2的计数值清零 TIM3->CNT =0; [/mw_shl_code] [mw_shl_code=c,true]}[/mw_shl_code]
回复

使用道具 举报

29

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
247
金钱
247
注册时间
2015-4-26
在线时间
5 小时
发表于 2015-7-21 23:49:25 | 显示全部楼层
回复【21楼】二蛋先生:
---------------------------------
这样可以吗?我试试
回复

使用道具 举报

0

主题

8

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2016-2-27
在线时间
3 小时
发表于 2016-2-29 17:07:50 | 显示全部楼层
TIM_TimeBaseStructure.TIM_Period =为编码器线数减1;       //   TIM_TimeBaseStructure.TIM_Prescaler =3;       //设置预分频:  这样子出来的结果就是你想要的实现值了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 18:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表