OpenEdv-开源电子网

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

关于stm32F103ZET芯片定时器用作编码器采集并读数的问题

[复制链接]

1

主题

3

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2020-8-7
在线时间
10 小时
发表于 2020-10-24 16:59:26 | 显示全部楼层 |阅读模式
1金钱
#define ENCODER_PPR 4096            //编码器的线数
int Encoder_Timer_Overflow;          //编码器溢出次数(转一圈溢出溢出)
u16 Previous_Count;

void TIM4_Encode_init(void)

{
   GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
    TIM_ICInitTypeDef TIM_ICInitStructure;      
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;         
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);                           
    TIM_DeInit(TIM4);
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1;
    TIM_TimeBaseStructure.TIM_Prescaler = 8;//2ms中断溢出
    TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);  

    TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge);
    TIM_ICStructInit(&TIM_ICInitStructure);
    TIM_ICInitStructure.TIM_ICFilter = 0;
    TIM_ICInit(TIM4, &TIM_ICInitStructure);
   NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;                   //定时器4中断分组配置
   NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;                   //使能
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;      //抢占优先级1
   NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x02;            //响应优先级2
   NVIC_Init(&NVIC_InitStructure);                                 //配置定时器4

    TIM_ClearFlag(TIM4, TIM_FLAG_Update);
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

    TIM4->CNT = 0;
    TIM_Cmd(TIM4, ENABLE);
}
void TIM4_IRQHandler(void)                                        //定时器4中断服务函数
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)                    //溢出中断
{   
  Encoder_Timer_Overflow++;       //溢出加1
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);                      //清除中断标志位
}
u32 Read_Encoder(void)
{
  u32 Count;                                                      //一段时间内转过的脉冲数
  u16 Current_Count;                                              //当前TIM4->CNT的值
u16 Enc_Timer_Overflow_one;                                    
Enc_Timer_Overflow_one=Encoder_Timer_Overflow;                  
  Current_Count = TIM_GetCounter(TIM4);                           //获得当前TIM4->CNT的值
  Encoder_Timer_Overflow=0;                                       //清零,方便下次计算
  Count = (u32)(Current_Count - Previous_Count + (Enc_Timer_Overflow_one) * (4*ENCODER_PPR));   //计算出一个时间转过的脉冲数
  Previous_Count = Current_Count;  
  return(Count);
}
各位大佬,我想采集编码器的读数,根据别人的程序修改得到的。主要思想是:将TIM4配置成编码器模式,IO口用PB6和PB7,中断服务函数是现编码器转一圈(即4096个脉冲)就中断一次,将溢出的次数 Encoder_Timer_Overflow加1;Read_Encoder()函数是读取编码器的脉冲数,Current_Count是目前定时器计数器的值, Previous_Count 是上一次定时器的CNT值,两者相减的数再加上溢出的脉冲数(即(Enc_Timer_Overflow_one) * (4*ENCODER_PPR)))就是实际的脉冲个数。STM32参考资料没有关于定时器设置成编码器接口的程序,TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge)这一句是从别人的程序复制过来的,这样的程序能正确读到编码器的读数吗,有懂的大佬指点下。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 21:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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