OpenEdv-开源电子网

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

使用编码器模式2计数脉冲数量,有问题。

[复制链接]

2

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-12-14
在线时间
18 小时
发表于 2018-10-12 15:41:18 | 显示全部楼层 |阅读模式
22金钱
最近在调试编码器,通过32上的编码器模式统计每圈的脉冲数量(分辨率),编码器的型号上说是2500的,但是在测试的时候脉冲的数量和2500有很大的差别。
中断是通过编码器上面的Z相的调零信号触发外部中断。

下面是编码器模式的初始化程序

  • void TIM4_EncoderInit(u16 arr,u16 psc)
  • {
  •       TIM_TimeBaseInitTypeDef                  TIM_TimeBaseStructure;
  •     TIM_ICInitTypeDef                        TIM_ICInitStructure;
  •     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4     , ENABLE);//使能TIM4时钟
  •       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能GPIO时钟
  •       //GPIO初始化  连接编码器的A、B两相
  •       GPIO_Init(GPIOB ,6 , GPI_FLOAT , LOW);
  •       GPIO_Init(GPIOB ,7 , GPI_FLOAT , LOW);
  •       //将外设NVIC的寄存器设置为默认值
  •       TIM_DeInit(TIM4);
  •       //将时基设置的结构体设置为默认值
  •     TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  •        //设定计数器重装值
  •     TIM_TimeBaseStructure.TIM_Period = arr;
  •     //TIM时钟预分频值
  •     TIM_TimeBaseStructure.TIM_Prescaler = psc;
  •     //设置时钟分割 T_dts = T_ck_int
  •     TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1;
  •       //TIM向上计数
  •     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 = 6;
  •     //将TIM_ICInitStructure中的指定参数初始化TIM3
  •     TIM_ICInit(TIM4, &TIM_ICInitStructure);
  •         //计数初值为0
  •     TIM4->CNT = 0;  //计数初值为0
  • }

下面是中断处理的程序

  • void EXTI3_IRQHandler(void)
  • {
  •     int i=0;                                          //记录计数器的值
  •     TIM_Cmd(TIM4,DISABLE);                            //停止计数器计数
  •     if(EXTI_GetITStatus(EXTI_Line3) != RESET)             //检查是否发生中断
  •     {
  •         printf("进入中断\r\n");
  •       i=TIM4->CNT;                                    //计数器的值
  •       printf(" 脉冲数:%d \r\n",i/4);                    //输出脉冲数
  •      delay_ms(100);
  •         TIM4->CNT = 0;                                   //计数器初值重置为0
  •       TIM_Cmd(TIM4,ENABLE);                             //开启计数器计数
  •       EXTI_ClearITPendingBit(EXTI_Line3);                //清除中断线上的中断标志位
  •     }
  • }

下面是主程序的代码
  • int main(void)
  • {
  •     delay_init(SYSCLK_FREQ_72);   //延时初始化
  •     EXTI_Key_Config();            //外部中断初始化
  •         UARTx_Config();               //串口初始化
  •        TIM4_EncoderInit(65535,0);    //定时器编码器模式初始化
  •       TIM_Cmd(TIM4,ENABLE);         //开启计数器
  •           while(1)
  •         {
  •         }
  • }

测试的时候脉冲的数量一直不稳定



最佳答案

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

解决了,将编码器模式设置那段代码按照官方参考手册改成寄存器设置的 [*] TIM4->CCMR1 |= 1
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-12-14
在线时间
18 小时
 楼主| 发表于 2018-10-12 15:41:19 | 显示全部楼层
解决了,将编码器模式设置那段代码按照官方参考手册改成寄存器设置的
  •       TIM4->CCMR1 |= 1<<0;
  •       TIM4->CCMR1 |= 1<<8;
  •       TIM4->CCER |= 0<<1;
  •       TIM4->CCER |= 0<<5;
  •       TIM4->SMCR |= 3<<0;
  •       TIM4->CCMR1 |= 3<<4;

这样脉冲数量就正常了
还是不知道为什么这样就好了,有大神能够解答吗?


回复

使用道具 举报

2

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-12-14
在线时间
18 小时
 楼主| 发表于 2018-10-12 15:44:19 | 显示全部楼层
编码器型号是MK3810G-2500BM-C526
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

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

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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