OpenEdv-开源电子网

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

增量式正交编码器能测角度吗?

[复制链接]

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
发表于 2017-7-15 09:01:45 | 显示全部楼层 |阅读模式
20金钱
我用stm32编码器模式测角度,每次回原点读数都不为0,附上代码,请问是我程序的问题?还是增量式编码器本身就测不了角度?[mw_shl_code=applescript,true]extern u16 count1;
extern u16 count2;
//编码器1初始化,使用定时器3
void coder1_init()
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
        
        GPIO_InitTypeDef GPIO_Structure;
        GPIO_Structure.GPIO_Mode=GPIO_Mode_AF;
        GPIO_Structure.GPIO_OType=GPIO_OType_PP;
        GPIO_Structure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
        GPIO_Structure.GPIO_PuPd=GPIO_PuPd_UP;
        GPIO_Structure.GPIO_Speed=GPIO_High_Speed;
        GPIO_Init(GPIOB,&GPIO_Structure);
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_TIM3);
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_TIM3);
        
        NVIC_InitTypeDef NVIC_Structure;
        NVIC_Structure.NVIC_IRQChannel=TIM3_IRQn;
        NVIC_Structure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Structure.NVIC_IRQChannelPreemptionPriority=0;
        NVIC_Structure.NVIC_IRQChannelSubPriority=0;
        NVIC_Init(&NVIC_Structure);
        
        TIM_DeInit(TIM3);
        TIM_TimeBaseInitTypeDef TIM3_Structure;
        TIM3_Structure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM3_Structure.TIM_CounterMode=TIM_CounterMode_Up;
        TIM3_Structure.TIM_Period=399*4;//400线编码器
        TIM3_Structure.TIM_Prescaler=0;
        TIM_TimeBaseInit(TIM3,&TIM3_Structure);
        
        TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_BothEdge,TIM_ICPolarity_BothEdge);
        
        TIM_ICInitTypeDef IC_Structure;
        TIM_ICStructInit(&IC_Structure);
        IC_Structure.TIM_ICFilter=6;
        TIM_ICInit(TIM3,&IC_Structure);
        
        TIM_ClearFlag(TIM3, TIM_FLAG_Update);
        TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
        
        TIM3->CNT = 800;//设置一个基数,防止出现负值
        
        TIM_Cmd(TIM3, ENABLE);
}
//定时器中断,读取角度
void TIM1_UP_TIM10_IRQHandler()
{
//        if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)
                count1=TIM3->CNT;
               
        TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}[/mw_shl_code]

QQ图片20170715085703.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

26

帖子

0

精华

高级会员

Rank: 4

积分
737
金钱
737
注册时间
2016-9-20
在线时间
66 小时
发表于 2017-7-15 09:28:38 | 显示全部楼层
1.TIM3_Structure.TIM_Period=399*4;//400线编码器
这是有问题的,应该是TIM3_Structure.TIM_Period=400*4-1;//400线编码器
2.你回到零点得初始化为0,也就是你的TIM3->CNT=0。
3.有没有Z信号?有的话可以利用一下,没有就靠TIM3溢出了。
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-15 09:33:03 | 显示全部楼层
ljfc 发表于 2017-7-15 09:28
1.TIM3_Structure.TIM_Period=399*4;//400线编码器
这是有问题的,应该是TIM3_Structure.TIM_Period=400*4 ...

我这个没有z信号,而且单片机只是不停的计脉冲,单片机也不知道哪里是零点,怎么初始化0
回复

使用道具 举报

1

主题

26

帖子

0

精华

高级会员

Rank: 4

积分
737
金钱
737
注册时间
2016-9-20
在线时间
66 小时
发表于 2017-7-15 09:37:50 | 显示全部楼层
那就认为上电点为原点,初始化为TIM3->CNT = 0;
这样就可以了,编码器是可靠的可以测量位置的
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-15 09:45:44 | 显示全部楼层
ljfc 发表于 2017-7-15 09:37
那就认为上电点为原点,初始化为TIM3->CNT = 0;
这样就可以了,编码器是可靠的可以测量位置的

单片机捕获脉冲占用CPU资源吗?我总感觉是CPU执行其他程序的时候没有计到编码器脉冲
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-15 09:50:14 | 显示全部楼层
ljfc 发表于 2017-7-15 09:37
那就认为上电点为原点,初始化为TIM3->CNT = 0;
这样就可以了,编码器是可靠的可以测量位置的

按你说的还是不行,还是有误差,感觉就是单片机有些脉冲没有计到
回复

使用道具 举报

1

主题

26

帖子

0

精华

高级会员

Rank: 4

积分
737
金钱
737
注册时间
2016-9-20
在线时间
66 小时
发表于 2017-7-15 16:40:08 | 显示全部楼层
void ENC_Init(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_ICInitTypeDef TIM_ICInitStructure;
  
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
   
  /* TIM2 clock source enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  /* Enable GPIOA, clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  
  GPIO_StructInit(&GPIO_InitStructure);
  /* Configure PA.00,01 as encoder input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* Enable the TIM2 Update Interrupt */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_IRQChannelPreemptionPriority_ENC;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_IRQChannelSubPriority_ENC;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);


  /* Timer configuration in Encoder mode */
  TIM_DeInit(ENCODER_TIMER);
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0;  // No prescaling
  TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1;  
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   
  TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);

  TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12,
                             TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
        TIM_ICStructInit(&TIM_ICInitStructure);
  TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER;
  TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);
  
// Clear all pending interrupts
  TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);
  TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE);
  //Reset counter
  TIM2->CNT = COUNTER_RESET;
  
  TIM_Cmd(ENCODER_TIMER, ENABLE);
}

这是我在伺服中的初始化,跟你还是有点差异的。你自己改改咯
回复

使用道具 举报

29

主题

486

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3083
金钱
3083
注册时间
2014-7-19
在线时间
413 小时
发表于 2017-7-15 20:15:42 | 显示全部楼层
电子人生!
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-16 11:12:35 | 显示全部楼层
翱翔云端的鸟 发表于 2017-7-15 20:15
参考下我的这篇博客
http://blog.csdn.net/wang328452854/article/details/50579832

你这个博客也没说怎么测量角度额
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-16 11:14:20 | 显示全部楼层
ljfc 发表于 2017-7-15 16:40
void ENC_Init(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

你这个只是初始化,那又怎么读取角度呢
回复

使用道具 举报

29

主题

486

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3083
金钱
3083
注册时间
2014-7-19
在线时间
413 小时
发表于 2017-7-16 11:37:22 | 显示全部楼层
心语心愿 发表于 2017-7-16 11:14
你这个只是初始化,那又怎么读取角度呢

编码器的度数就是角度啊 !
电子人生!
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-16 12:07:03 | 显示全部楼层
翱翔云端的鸟 发表于 2017-7-16 11:37
编码器的度数就是角度啊 !

每次进入中断读数后CNT寄存器清零吗?
回复

使用道具 举报

29

主题

486

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3083
金钱
3083
注册时间
2014-7-19
在线时间
413 小时
发表于 2017-7-16 14:25:04 | 显示全部楼层
心语心愿 发表于 2017-7-16 12:07
每次进入中断读数后CNT寄存器清零吗?

可以不需要中断的,看你的具体应用  
电子人生!
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-17 08:31:15 | 显示全部楼层
翱翔云端的鸟 发表于 2017-7-16 14:25
可以不需要中断的,看你的具体应用

我是感觉它计数的时候丢计数脉冲,我也不知道到底是为什么,理论上编码器计数是不占用CPU资源的吧,但是怎么会这样?
回复

使用道具 举报

3

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2017-3-2
在线时间
15 小时
发表于 2017-7-17 11:08:19 来自手机 | 显示全部楼层
上拉输入
回复

使用道具 举报

14

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
356
金钱
356
注册时间
2016-7-20
在线时间
39 小时
 楼主| 发表于 2017-7-17 11:35:28 | 显示全部楼层

当然是上拉输入,如果不是上拉输入一个脉冲也计不到
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-12-18 21:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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