打印

请教STM32F103中定时器配置成编码器的问题!

[复制链接]
5730|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fredinand|  楼主 | 2011-9-11 20:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用正交编码器,STM32中集成的定时器可以配置成编码器状态,感觉很好用,但是只有十六位,实在不能满足要求(要求至少二十位),请教各位大虾有没有好办法可以进行编码器的级联配置,另外STM32定时器的这种使用方法在硬件上有没有BUG,就是会不会丢步,这样的话就很影响精度。
沙发
airwill| | 2011-9-12 20:17 | 只看该作者
是啊, 确实是这样. 只有 16位, 显得很是不够!
但是 硬件只有 16 位. 有什么办法处理得好一点呢?
1. 定时器级联. 但是经过本人反复考虑, 总数不能满足我的要求. 很是失落.
2. 降低定时精度来凑合. 定时器的输入时钟采用分频后时钟. 降低工作频率, 我感觉其实很多时候并不要求 36Mhz/72Mhz 那么高的频率. 通过 8 分频乃至 16分频. 来延迟定时器的 16 位溢出时间. 这是最简单的办法.
3. 使用定时溢出中断. 如果不能接收 16分频的定时精度. 可以增加定时溢出中断, 通过软件来拓展定时器的精度. 这也是不算太复杂的解决办法.
4. 换个芯片吧, 我发现 STM32F2xx 系列有 32 位的定时器好用, 可以考虑改用这类芯片来做.
呵呵, 祝好运

使用特权

评论回复
板凳
Chaos_zc| | 2011-9-15 10:14 | 只看该作者
我用过这方面的功能,只是定义了一个变量,在溢出中断中根据溢出方向对变量进行加减来扩充编码器位数,目前没发现问题

使用特权

评论回复
地板
fredinand|  楼主 | 2011-9-17 00:16 | 只看该作者
我也尝试过,可是不太成功,变量总是不能及时修正,能否告知详细些,还有就是这样对精度有影响吗?

使用特权

评论回复
5
acgean| | 2011-9-18 16:53 | 只看该作者
丢步, 也许是你的中断服务程序的 BUG 导致的.

使用特权

评论回复
6
nieyaohua| | 2011-10-24 10:49 | 只看该作者
楼主,我也在做这方面的,但配置后调试一下不行,能不能把你的工程发给我看看啊,谢谢,我邮箱nieyaohuahappy@163.com

使用特权

评论回复
7
dami| | 2011-11-2 10:55 | 只看该作者
定时器级联的例子你可以去看一下。在我的21ic博客里有提到这个例子。编码器没试过。你可以试下。实在不行就只能用205,207之类的,开始有32位定时器了。

使用特权

评论回复
8
zxm19820916| | 2012-12-24 15:25 | 只看该作者
可以的,设置一个32位的全局变量。每次在溢出中断里把系数进行加减。3楼的方法可行。

使用特权

评论回复
9
明月小厨| | 2012-12-24 17:47 | 只看该作者
你自己另外增加一个变量当成高位字节就解决了吧;

使用特权

评论回复
10
qq84395064| | 2016-3-7 16:04 | 只看该作者
#include "encoding_disk.h"
#include "delay.h"

/**************************************************************************************
********ÂëÅÌÊäÈë¼ì²â*********°´¼üÊäÈë
TIM3 ÓÃÀ´¼ì²âÂëÅÌ
PA.6-> RUN-A2         TIM3-CH1//        
PA.7-> RUN-B2         TIM3-CH2//
PB.0-> RUN-A1         TIM3-CH3//
PB.1-> RUN-B1         TIM3-CH4//
Õý½»±àÂëÆ÷Ò²³ÆÔöÁ¿Ê½±àÂëÆ÷
****************************************************************************************/
#define ENCODER_TIMER   TIM3  // Encoder unit connected to TIM3
#define ENCODER_PPR           (u16)(100)   // number of pulses per revolution
#define SPEED_BUFFER_SIZE 8

#define COUNTER_RESET   (u16)0
#define ICx_FILTER      (u8) 6 // 6<-> 670nsec

#define TIMx_PRE_EMPTION_PRIORITY 1
#define TIMx_SUB_PRIORITY 0

#define ENCODER_TIM_PERIOD 0xffff//???????65536-1
#define MAX_COUNT          10000//10000???1ms?????10000???


void  EncodingDisk_Init(void)
{           

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_ICInitTypeDef TIM_ICInitStructure;
  /* Encoder unit connected to TIM1, 4X mode */   
  GPIO_InitTypeDef GPIO_InitStructure;
  //NVIC_InitTypeDef NVIC_InitStructure;
  /* TIM1 clock source enable */
  RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//
  /* Enable GPIOA, clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//??GPIOA??
  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;//PA8 PA9????
  GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Enable the TIM3 Update Interrupt */
//        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
//        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRIORITY;
//        NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;
//        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 //??????????0,???
  //TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1;  //????????
  TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD-1;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//?????? T_dts = T_ck_int
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //TIM????
  TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);
  TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//???????3
  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);//??TIM1??????
  TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE);
  //ENC_Clear_Speed_Buffer();
  //Reset counter
  TIM3->CNT = 0;
  //CurrentCount = TIM1->CNT;
  TIM_Cmd(ENCODER_TIMER, ENABLE);
// System.Device.Encoder.Enc_GetCount = Enc_GetCount;

}
s16 Enc_GetCount(void)
{
    static  u16   lastCount = 0;
    u16  curCount = ENCODER_TIMER->CNT;//?????
    s32 dAngle = curCount - lastCount;
    if(dAngle >= MAX_COUNT)
    {
      dAngle -= ENCODER_TIM_PERIOD;
    }
    else if(dAngle < -MAX_COUNT)
    {
      dAngle += ENCODER_TIM_PERIOD;
    }
    lastCount = curCount;
    return (s16)dAngle;
}
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/


/*s16 Enc_GetCount(void)
{
  static  u16   lastCount = 0;
  u16  curCount = ENCODER_TIM->CNT;
  s32 dAngle = curCount - lastCount;
  if(dAngle >= MAX_COUNT){
    dAngle -= ENCODER_TIM_PERIOD;
  }else if(dAngle < -MAX_COUNT){
    dAngle += ENCODER_TIM_PERIOD;
  }
  lastCount = curCount;
  return (s16)dAngle;
}*/
/*
1s¶¼²»»áÒç³öÖжϣ¬¿ÉÒÔ×öÒ»¸ö10ms²úÉúÒ»´ÎµÄÖжÏ
ÔÚÖжÏÖе÷ÓÃÉÏÃæµÄ´úÂë   ÉÏÊö´úÂëÖÐMAX_COUNTÊDZÈ10msÄÚ¿ÉÄܳöÏֵļÆÊý×î´óÖµ »¹Òª´òµÄÖµ
ENCODER_TIM_PERIODÊǶ¨Ê±Æ÷periodÖµ£¬×îºÃ±ÈMAX_COUNT´ó£¬È»ºó¶¨ÒåÒ»¸ö32λµÄÓзûºÅ±äÁ¿£¬
ÈçcurrentCount

*/
我的程序,老是取的值为零,请楼主,帮忙分析下。谢谢。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

124

主题

151

帖子

1

粉丝