OpenEdv-开源电子网

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

关于stm32f407编码器测速问题

[复制链接]

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
发表于 2020-4-15 16:05:36 | 显示全部楼层 |阅读模式
10金钱
我的编码器是E6B2-CWZ6C 2000P/R  电机是AFB0912SH -A  2800R.P.M
我用网上的程序,测试了一下我的编码器所读到的脉冲数,但是它不是转一圈才有这么多脉冲数,而是直接乘以它的4倍数,每一次转都保持在8000我这里就不懂了,不是说好的转一圈才会满脉冲吗?为什么只是转动一个角度都满脉冲了。
而且当我用手的时候还有数据,一旦测试电机速度就测试不了显示值一直为0,想问一下各位大神,是不是我哪里做错了。
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "lcd.h"
  6. #include "motor.h"
  7. #include "timer.h"
  8. #include "pwm.h"
  9. #include "key.h"
  10. #include "encode.h"

  11. extern int Encoder_Timer_Overflow;

  12. int PWM=100;
  13. u32 encode;
  14. float speed,t;

  15. int main(void)
  16. {
  17. //        int k;
  18.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //设置系统中断优先级分组2
  19.         delay_init(168);                                 //初始化延时函数
  20.         uart_init(115200);                                           //初始化串口波特率为115200
  21.         LED_Init();                                                                     //初始化LED
  22.         KEY_Init();                                                                     //初始化按键
  23.         //LCD_Init();                                      //初始化LCD FSMC接口
  24.         TIM3_Encode_init((ENCODER_PPR-1)*4,1-1);         //编码器初始化
  25.         TIM4_PWM_Init(100-1,84-1);                       //84M/100/84=10KHZ  //GPIOB6复用为定时器4  
  26.         TIM5_Int_Init(500-1,8400-1);                     //84M/8400=10Khz,10Khz/500 = 20hz 1秒   
  27.         while(1)
  28.         {
  29. //                k=KEY_Scan(0);                                 //得到键值       
  30. //          if(k)
  31. //                {
  32. //                        switch(k)                                    //根据不同按键返回值执行不同任务
  33. //                        {                                                                                                                               
  34. //                          case KEY0_PRES:                            //KEY0键增加电机转速                                          
  35. //            PWM+=20;
  36. //                                    if(PWM>100)
  37. //                                            PWM=0;
  38. //                                                break;                               
  39. //                          case KEY1_PRES:                            //KEY1键用减小电机转速
  40. //            PWM-=20;
  41. //                                    if(PWM<0)
  42. //                                            PWM=100;
  43. //                                                break;                                               
  44. //                        }
  45. //                }       
  46. //                TIM_SetCompare1(TIM4,PWM);  
  47.         }
  48. }

  49. void TIM5_IRQHandler(void)                          //定时器5中断服务函数
  50. {
  51.         if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)      //溢出中断
  52.         {  
  53.                 encode=Read_Encoder();                          //获得编码器的值
  54.                 printf("编码器脉冲数为:%d\r\n",encode);
  55.                 speed=encode/2000.0f/4.0f/0.05f;
  56.                 printf("电机转速为:%f\r\n",speed);               
  57.         }
  58.         TIM_ClearITPendingBit(TIM5,TIM_IT_Update);        //清除中断标志位
  59. }




  60. #include "encode.h"
  61. #include "sys.h"

  62. Encode_Data EncodeData;

  63. //int Encoder_Timer_Overflow;                                      //编码器溢出次数(每389*4溢出一次)
  64. //u16 Previous_Count;                                              //上次TIM3->CNT的值

  65. void TIM3_Encode_init(u16 arr,u16 psc)
  66. {
  67.         GPIO_InitTypeDef GPIO_InitStructure;
  68.         NVIC_InitTypeDef  NVIC_InitStructure;
  69.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  70.   TIM_ICInitTypeDef TIM_ICInitStructure;   

  71.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   
  72.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  
  73.                
  74.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;          //GPIOA6和GPIOA7
  75.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                    //复用模式
  76.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;              //速度100MHz
  77.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;                //浮空       
  78.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                  //推挽复用输出
  79.   GPIO_Init(GPIOA, &GPIO_InitStructure);                          //初始化PA6和PA7

  80.   GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3);           //GPIOA6复用为定时器3通道1
  81.         GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM3);           //GPIOA7复用为定时器3通道2
  82.        
  83.   TIM_TimeBaseStructure.TIM_Period = arr;                               //(编码器线数-1)*4        四倍频原理
  84.         TIM_TimeBaseStructure.TIM_Prescaler=psc;                        //定时器分频
  85.         TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;       //向上计数模式
  86.         TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;           //时钟分频因子,不分频
  87.         TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);                  //初始化TIM3
  88.        
  89.         TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;                  //选择输入端IC1映射到TI1上
  90.   TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;              //上升沿捕获
  91.   TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;   //映射到TI1上
  92.   TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;                    //配置输入分频,不分频
  93.   TIM_ICInitStructure.TIM_ICFilter =6;                            //配置输入滤波器
  94.   TIM_ICInit(TIM3,&TIM_ICInitStructure);
  95.        
  96.         TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;                  //选择输入端IC2映射到TI2上
  97.   TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;              //上升沿捕获
  98.   TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;   //映射到TI2上
  99.   TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;                    //配置输入分频,不分频
  100.   TIM_ICInitStructure.TIM_ICFilter=6;                             //配置输入滤波器
  101.   TIM_ICInit(TIM3,&TIM_ICInitStructure);
  102.        
  103.         TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising );//编码器配置(定时器、编码模式、上升沿、上升沿)
  104.                
  105.   NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;                   //定时器3中断分组配置
  106.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;                   //使能
  107.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;      //抢占优先级1
  108.         NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x02;            //响应优先级2
  109.         NVIC_Init(&NVIC_InitStructure);                                 //配置定时器3
  110.                
  111.         TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);                        //允许定时器3更新中断
  112.         TIM_Cmd(TIM3,ENABLE);                                           //使能定时器3
  113. }

  114. void TIM3_IRQHandler(void)                                        //定时器3中断服务函数
  115. {
  116.         if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)                    //溢出中断
  117.         {   
  118.                 EncodeData.Encoder_Timer_Overflow++;                    
  119.         }
  120.         TIM_ClearITPendingBit(TIM3,TIM_IT_Update);                      //清除中断标志位
  121. }

  122. u32 Read_Encoder(void)
  123. {
  124.   //u32 Count;                                                      //一段时间内转过的脉冲数
  125.   //u16 Current_Count;                                              //当前TIM3->CNT的值
  126.         //u16 Enc_Timer_Overflow_one;                                           

  127.   EncodeData.Enc_Timer_Overflow_one=EncodeData.Encoder_Timer_Overflow;                  
  128.   EncodeData.Current_Count = TIM_GetCounter(TIM3);                           //获得当前TIM3->CNT的值
  129.   EncodeData.Encoder_Timer_Overflow=0;                                       //清零,方便下次计算
  130.         if((TIM3->CR1&0x0010) == 0x0010)                                //如果反转
  131.     EncodeData.Count = (u32)((EncodeData.Enc_Timer_Overflow_one)* (-1)*(4*ENCODER_PPR) - (EncodeData.Current_Count - EncodeData.Previous_Count));   //计算出一个时间转过的脉冲数
  132.         else                                                            //如果正转
  133.                 EncodeData.Count = (u32)(EncodeData.Current_Count - EncodeData.Previous_Count + (EncodeData.Enc_Timer_Overflow_one) * (4*ENCODER_PPR));       //计算出一个时间转过的脉冲数
  134.   EncodeData.Previous_Count = EncodeData.Current_Count;  
  135.   return(EncodeData.Count);
  136. }

复制代码




最佳答案

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

其实就是没接上拉电阻,真坑,项目上的电路板不行,自己的开发板稳定运行,还要查查看到底是什么原因。害!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-15 16:05:37 | 显示全部楼层
Leven175 发表于 2020-4-17 10:40
单独测试编码器脉冲时,定时器计数值不准是什么原因

其实就是没接上拉电阻,真坑,项目上的电路板不行,自己的开发板稳定运行,还要查查看到底是什么原因。害!
回复

使用道具 举报

0

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2017-7-26
在线时间
99 小时
发表于 2020-4-15 16:36:47 | 显示全部楼层
我记得我用的时候没有判断正反,反转自动就是负数呀
回复

使用道具 举报

0

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2017-7-26
在线时间
99 小时
发表于 2020-4-15 16:39:49 | 显示全部楼层
int du_bmq(u8 ch)
{
   int a;   
   switch(ch)
         {
           case 2:  a= (short)TIM2 -> CNT;  TIM2 -> CNT=0;break;   //读取编码器的数据并清零
                 case 3:  a= (short)TIM3 -> CNT;  TIM3 -> CNT=0;break;         //读取编码器的数据并清零
                 case 4:  a= (short)TIM4 -> CNT;  TIM4 -> CNT=0;break;         //读取编码器的数据并清零
                 case 5:  a= (short)TIM5 -> CNT;  TIM5 -> CNT=0;break;         //读取编码器的数据并清零
                 default: a=0;
         }
                return a;
}
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-15 17:04:38 | 显示全部楼层
1176658950 发表于 2020-4-15 16:39
int du_bmq(u8 ch)
{
   int a;   

什么意思啊?就直接这样就可以了?因为我目前发现我只要转动就会出现读数8k。难道是我理解错了?
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-15 17:06:25 | 显示全部楼层
1176658950 发表于 2020-4-15 16:36
我记得我用的时候没有判断正反,反转自动就是负数呀

可是我现在的编码器读数,如果在电机的高速情况下,我单片机读不出编码器的脉冲数,即使编码器有脉冲输出
回复

使用道具 举报

0

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2017-7-26
在线时间
99 小时
发表于 2020-4-15 17:10:59 | 显示全部楼层
Leven175 发表于 2020-4-15 17:04
什么意思啊?就直接这样就可以了?因为我目前发现我只要转动就会出现读数8k。难道是我理解错了?

在定时器里面读,定时器周期看你编码器速度了,一个周期不要超过2^15个周期就好
回复

使用道具 举报

0

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2017-7-26
在线时间
99 小时
发表于 2020-4-15 17:13:38 | 显示全部楼层
Leven175 发表于 2020-4-15 17:06
可是我现在的编码器读数,如果在电机的高速情况下,我单片机读不出编码器的脉冲数,即使编码器有脉冲输出

可能你定时器周期太短了,溢出了
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-15 17:23:02 | 显示全部楼层
1176658950 发表于 2020-4-15 17:13
可能你定时器周期太短了,溢出了

不太懂你的意思,因为我这边测试过1s 5s都是有点问题的,可是我的定时器读编码器也没超过2^15.还有没有其它可能性?我这边实在想不到,因为只要电机转动,但是编码器却读不到脉冲我就觉得奇怪,会不会电机转速大于编码器的转速所以导致读不出来,可是我明显感觉到的是定时器模式下,读数好像也不准啊
回复

使用道具 举报

0

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2017-7-26
在线时间
99 小时
发表于 2020-4-15 17:27:20 | 显示全部楼层
Leven175 发表于 2020-4-15 17:23
不太懂你的意思,因为我这边测试过1s 5s都是有点问题的,可是我的定时器读编码器也没超过2^15.还有没有其 ...

一秒几百万个周期的编码器407还是妥妥的识别的
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-15 17:31:12 | 显示全部楼层
1176658950 发表于 2020-4-15 17:27
一秒几百万个周期的编码器407还是妥妥的识别的

但是脉冲值还是读不准是还需要配置什么或者加电阻吗?
回复

使用道具 举报

0

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2017-7-26
在线时间
99 小时
发表于 2020-4-15 17:34:06 | 显示全部楼层
Leven175 发表于 2020-4-15 17:31
但是脉冲值还是读不准是还需要配置什么或者加电阻吗?

这就不知道了,我用普通电机屁股后面的光电编码器,霍尔编码器是没问题的
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-15 17:35:10 | 显示全部楼层
1176658950 发表于 2020-4-15 17:34
这就不知道了,我用普通电机屁股后面的光电编码器,霍尔编码器是没问题的

好的,先谢谢你,我再找找,毕竟不一样
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-4-15 17:36:20 | 显示全部楼层
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-15 17:38:36 | 显示全部楼层
nashui_sx 发表于 2020-4-15 17:36
为啥是*4 参考407给103 基本一样 http://www.openedv.com/forum.php?mod=viewthread&tid=301406&extra=

不是,可能上面问题没说清楚,我现在是能读脉冲数,但是不准,不知道是什么问题。。。而且设置的对过应该是没问题的,就是无论我转多少度,它的脉冲数都是直接到8k。而不是转一圈之后才8k
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-4-15 17:45:53 | 显示全部楼层
Leven175 发表于 2020-4-15 17:38
不是,可能上面问题没说清楚,我现在是能读脉冲数,但是不准,不知道是什么问题。。。而且设置的对过应该 ...
你把回调函数都删了  回调函数后半部分删了就是正常的中断函数了
  1. #include "tim_encode.h"
  2. //编码器模式

  3. void TIM4_Encode_Test(void)
  4. {
  5.         s32  TIM4_Old_Count;

  6.         TIM4_Init_Encode(TIM4_IRQHandler_Callback_Encode);

  7.         while(1)
  8.         {
  9.                 TIM4_Count=TIM4_Get_Encode();

  10.                 if(TIM4_Old_Count != TIM4_Count)//如果先前的计数值与当前计数值不相等,说明编码器已转动打印当前数值
  11.                 {
  12.                         TIM4_Old_Count = TIM4_Count;                                                                                                                //获取先前的计数值
  13.                         printf("脉冲4=%8ld  圈数4=%8ld  位置4=%5d  圈脉冲4=%8ld\r\n"\
  14.                         ,TIM4_Count,TIM4_Circle_Count,TIM4->CNT,TIM4_Encoder_Line_Number*TIM4_Encoder_Line_Multiple);                        
  15.                 }               
  16.         }        
  17. }


  18. //编码器必须用定时器的通道1 2来捕获
  19. s32 TIM4_Count,TIM4_Circle_Count,TIM4_Encoder_Line_Multiple;//总计数、圈数计数、脉冲倍频系数(一圈脉冲数=TIM4_Encoder_Line_Number*TIM4_Encoder_Line_Multiple)

  20. void TIM4_Init_Encode(IRQ_IRQHandler_Callback cb)
  21. {
  22.         GPIO_InitTypeDef         GPIO_InitStructure;
  23.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  24.         TIM_ICInitTypeDef        TIM_ICInitStructure;           
  25.         NVIC_InitTypeDef         NVIC_InitStructure;
  26.         
  27.         TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);  //设置缺省值,这一步最好加上防止放到串口初始化后出问题
  28.         //TIM_OCStructInit(&TIM_OCInitStructure);        //设置缺省值,这一步最好加上防止放到串口初始化后出问题
  29.         TIM_ICStructInit(&TIM_ICInitStructure);          //设置缺省值,这一步最好加上防止放到串口初始化后出问题
  30.         
  31.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  32.         RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  33.         GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);         //GPIOx复用为定时器
  34.         GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4);         //GPIOx复用为定时器
  35.         
  36.         /*- 正交编码器输入引脚 PB->6  PB->7 -*/
  37.         GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;         
  38.         GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  39.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  40.         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;                //拉不拉都一样,上啦一下保证电平确定     
  41.         GPIO_Init(GPIOB, &GPIO_InitStructure);                           

  42.         /*- TIM4编码器模式配置 -*/
  43.         TIM_DeInit(TIM4);
  44.         if (TIM4_ENCODER_MODE<TIM_EncoderMode_TI12) TIM4_Encoder_Line_Multiple=2;//单相单边沿计数,2倍
  45.         else                                        TIM4_Encoder_Line_Multiple=4;//双相双边沿计数,4倍
  46.         TIM_TimeBaseStructure.TIM_Period = TIM4_Encoder_Line_Number*TIM4_Encoder_Line_Multiple-1;
  47.         TIM_TimeBaseStructure.TIM_Prescaler = 0;
  48.         TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1 ;
  49.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  50.         TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);              
  51.                  
  52.         TIM_EncoderInterfaceConfig(TIM4, TIM4_ENCODER_MODE, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising);        //配置编码器模式触发源和极性
  53.         //TIM4_ENCODER_MODE
  54.         //TIM_EncoderMode_TI1 TIM_EncoderMode_TI2  单相单边沿计数,2倍  
  55.         //TIM_EncoderMode_TI12                     双相双边沿计数,4倍

  56.         //TIM_ICPolarity_Rising   极性不反相,另一通道高电平时计数情况   
  57.         //TIM_ICPolarity_Falling  极性反相  ,另一通道低电平时计数情况            
  58.         //TIM_ICPolarity_BothEdge 不能选择   看 IS_TIM_IC_POLARITY 判断
  59.         //表73(204页) 表77(252页) 说明了另一通道高低电平是对应本通道上升下降沿计数是增加还是减少
  60.         
  61.         TIM_ICStructInit(&TIM_ICInitStructure);                                                                                                                                                                                                                                                                                 
  62.         TIM_ICInitStructure.TIM_ICFilter = 6;
  63.         TIM_ICInit(TIM4, &TIM_ICInitStructure);
  64.         
  65.         //注册回调函数
  66.         TIM4_IRQHandler_Callback=cb;
  67.                
  68.         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;                                 
  69.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   
  70.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                  
  71.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                              
  72.         NVIC_Init(&NVIC_InitStructure);
  73.         
  74.         TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );
  75.         TIM_ClearFlag(TIM4, TIM_FLAG_Update);
  76.         
  77.         /*开启编码器溢出中断*/
  78.         TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
  79.         
  80.         TIM4->CNT = 0;
  81.         TIM_Cmd(TIM4, ENABLE);   //启动定时器
  82. }

  83. s32 TIM4_Get_Encode(void)
  84. {                                                                                                        
  85.         return TIM4_Circle_Count*TIM4_Encoder_Line_Number*TIM4_Encoder_Line_Multiple+(TIM4->CNT);//获取编码器当前数值
  86. }

  87. void TIM4_IRQHandler_Callback_Encode(void)   
  88. {
  89.         if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
  90.         {
  91.                 TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  
  92.                 if((((TIM4->CR1)>>4) & 0x01)==0)TIM4_Circle_Count++;//DIR==0
  93.                 else                            TIM4_Circle_Count--;//DIR==1
  94.         }
  95. }

复制代码
  1. #ifndef _TIM_ENCODE_H_
  2. #define _TIM_ENCODE_H_
  3. #include "sys.h"

  4. #define TIM4_ENCODER_MODE                        TIM_EncoderMode_TI1//TIM_EncoderMode_TI1  TIM_EncoderMode_TI1 单相单边沿计数,2倍
  5.                                                                     //TIM_EncoderMode_TI12                     双相双边沿计数,4倍
  6. #define TIM4_Encoder_Line_Number                                 390//编码器线数,一圈多少个脉冲
  7. extern  s32 TIM4_Count,TIM4_Circle_Count,TIM4_Encoder_Line_Multiple;//总计数、圈数计数、脉冲倍频系数(一圈脉冲数=TIM4_Encoder_Line_Number*TIM4_Encoder_Line_Multiple)

  8. void    TIM4_Init_Encode(IRQ_IRQHandler_Callback cb);
  9. s32     TIM4_Get_Encode(void);
  10. void    TIM4_IRQHandler_Callback_Encode(void);   
  11. void    TIM4_Encode_Test(void);

  12. #endif

复制代码


回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2020-4-16 00:53:44 | 显示全部楼层
帮顶
回复

使用道具 举报

19

主题

95

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-8-2
在线时间
170 小时
 楼主| 发表于 2020-4-17 10:40:22 | 显示全部楼层
单独测试编码器脉冲时,定时器计数值不准是什么原因
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-28 14:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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