OpenEdv-开源电子网

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

stm32 F103 编码器模式 输入捕获预分频无效,求解?

[复制链接]

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
发表于 2018-8-17 20:39:01 | 显示全部楼层 |阅读模式
1金钱


使用的电机是12V的371电机,带光栅编码器,一圈是360线,电机带减速机,减速比是 1:34

加上减速,一圈的脉冲是 360 * 34 = 12240

现在遇到2个问题,

1,一圈的脉冲太高了,因为加上减速机,一圈是12240,算上4倍频,会变成48960,有点吃不销了,也用不上这么精确。

2,很奇怪,按道理算下来,一圈是12440,应该跑完360度,才会激发一次中断,但现在是在180度的时候,就已经产生一次中断,


主要是想解决第1个问题,本来我是想通过输入捕获预分频来控制,如果12240 / 8 = 1530,
可惜怎么试都不行,不知道为什么?
[mw_shl_code=c,true]
TIM_ICInitTypeDef  IC;
IC.TIM_ICPrescaler = TIM_ICPSC_DIV8;
[/mw_shl_code]

以下是定时器设置模块代码
[mw_shl_code=c,false]static void TIM4_Mode_Config(void)
{
        GPIO_InitTypeDef                                         GPIO;
        TIM_TimeBaseInitTypeDef          TimeBase;
        TIM_ICInitTypeDef                                 IC;          

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
       
        /*- Õy½»±àÂëÆ÷êäèëòy½Å PB->6   PB->7 -*/
        GPIO.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;         
        GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING; // GPIO_Mode_IPU ; //GPIO_Mode_IPD;
        GPIO.GPIO_Speed = GPIO_Speed_10MHz;
        GPIO_Init(GPIOB, &GPIO);                           

        /*- TIM4±àÂëÆ÷Ä£ê½ÅäÖà -*/
        TIM_DeInit(TIM4);
        TimeBase.TIM_Period = 12240;
        TimeBase.TIM_Prescaler = 0;
        TimeBase.TIM_ClockDivision =TIM_CKD_DIV1 ;
        TimeBase.TIM_CounterMode = TIM_CounterMode_Up;
        //TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
        TIM_TimeBaseInit(TIM4, &TimeBase);              
                 
        //TIM_ICStructInit(&IC);                                                         
        IC.TIM_Channel = TIM_Channel_1 | TIM_Channel_2;
        IC.TIM_ICPolarity = TIM_ICPolarity_Rising;   
        IC.TIM_ICSelection = TIM_ICSelection_DirectTI;
        /////////////////////////////////////////////
        IC.TIM_ICPrescaler = TIM_ICPSC_DIV8;
        /////////////////////////////////////////////
        IC.TIM_ICFilter = 0;                 //ÅäÖÃÂË2¨Æ÷
                                               
        TIM_ICInit(TIM4, &IC);                       
       

        //ÅäÖñàÂëÆ÷Ä£ê½′¥·¢Ô′oí¼«DÔ       
        TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising);                                         

        TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC1 ,ENABLE);
               
        TIM4->CNT = 0;

        TIM_Cmd(TIM4, ENABLE);
}

void TIM4_IRQHandler(void)
{                                                                   
                if(TIM4->SR&0X0001)
                {
                       
                                u8 dir = TIM4->CR1 & ( 1 << 4 );

                                if(dir == 0x0000) circle += 1;
                                else  circle -= 1;
                       
                }                                  
                TIM4->SR&=~(1<<0);
}


[/mw_shl_code]


IMG_20180817_201313.jpg

IMG_20180817_201328.jpg

IMG_20180817_201424.jpg



最佳答案

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

使用定时器的编码器模式,将时基配置中的TimeBase.TIM_Prescaler值改为7即可实现脉冲计数8分频
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2018-8-17 20:39:02 | 显示全部楼层
使用定时器的编码器模式,将时基配置中的TimeBase.TIM_Prescaler值改为7即可实现脉冲计数8分频

回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-8-17 20:47:32 | 显示全部楼层
为什么是用输入捕获, 而不是用输入时钟呢?
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-18 17:07:45 | 显示全部楼层
自己顶上去,目前我在尝试用输入捕获来统计,不使用编码器模式,希望能成功。
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-18 17:09:30 | 显示全部楼层
edmund1234 发表于 2018-8-17 20:47
为什么是用输入捕获, 而不是用输入时钟呢?

输入捕获,故名思义,就是可以捕获一些信号,典型应用就是测量PWM占空比,还有小车上的测速
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-8-18 17:18:35 | 显示全部楼层
你不是要数脉冲?而是要量占空比?

//TIM_ICStructInit(&IC);                             
    IC.TIM_Channel = TIM_Channel_1 | TIM_Channel_2;
    IC.TIM_ICPolarity = TIM_ICPolarity_Rising;   
    IC.TIM_ICSelection = TIM_ICSelection_DirectTI;
这是有问题的,
两个通路的ICSelection, 要相反, 一个是TIM_ICSelection_DirectTI, 另一个是TIM_ICSelection_IndirectTI
ICPolarity也要相反, 一个Rising另一个是Falling

回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-8-18 17:20:33 | 显示全部楼层
本帖最后由 edmund1234 于 2018-8-18 17:21 编辑

如果你是量占空比就是上面的问题

如果是数一段时间有几个脉冲则是另外的方法
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-18 23:29:27 | 显示全部楼层
edmund1234 发表于 2018-8-18 17:18
你不是要数脉冲?而是要量占空比?

//TIM_ICStructInit(&IC);                             

我不是要量脉宽,只是想数脉冲,
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2018-8-19 01:18:48 | 显示全部楼层
用 TIM1_ETRClockMode1Config
例如,  TIM1_ExternalCLK1Config(TIM1_ExtTRGPSC_DIV2, TIM1_ExtTRGPolarity_NonInverted, 0x0);
要数的脉冲在ETR输入
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-19 12:10:42 | 显示全部楼层
edmund1234 发表于 2018-8-19 01:18
用 TIM1_ETRClockMode1Config
例如,  TIM1_ExternalCLK1Config(TIM1_ExtTRGPSC_DIV2, TIM1_ExtTRGPolarit ...

不错的方法
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-19 12:14:31 | 显示全部楼层
ufbycd 发表于 2018-8-19 01:05
使用定时器的编码器模式,将时基配置中的TimeBase.TIM_Prescaler值改为7即可实现脉冲计数8分频

试了,确实能解决问题。

但我留意到,8分频是在通道1和通道2混合触发的情况下,也就是相当于始终运行在4倍频模式下来计算的,就是,我的情况,无论怎么设,都只能是 在1530 * 2 = 3060 脉冲/ 圈

有没有办法能够设成1530个脉冲/圈?
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2018-8-19 12:35:22 | 显示全部楼层
本帖最后由 ufbycd 于 2018-8-19 12:43 编辑
hank 发表于 2018-8-19 12:14
试了,确实能解决问题。

但我留意到,8分频是在通道1和通道2混合触发的情况下,也就是相当于始终运行 ...

编码器模式肯定要用通道1跟2啦,你驱动编码器不用定时的编码器模式?怎么实现正反转计数?
我前阵子驱动线数为2500的编码器,减速机60比,这样一圈的总计数值为600000,超过16位,不好计。我就将TimeBase.TIM_Prescaler设为9即10分频,实现将一圈计数值降为60000。
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-19 21:07:32 | 显示全部楼层
ufbycd 发表于 2018-8-19 12:35
编码器模式肯定要用通道1跟2啦,你驱动编码器不用定时的编码器模式?怎么实现正反转计数?
我前阵子驱动 ...

我发现我买的电机有个巨坑,网站上写减速比是1:34,但我拆开减速箱,数齿轮数,算减速比,

算出来的结果是 30613 : 900,也就是说,实际减速比是1:34.0144444444.……
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-19 21:52:57 | 显示全部楼层
ufbycd 发表于 2018-8-19 12:35
编码器模式肯定要用通道1跟2啦,你驱动编码器不用定时的编码器模式?怎么实现正反转计数?
我前阵子驱动 ...

也就是说,你的电机跑一圈,编码器输出的脉冲是2500 * 60 ?
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2018-8-19 22:08:03 | 显示全部楼层
本帖最后由 ufbycd 于 2018-8-19 22:09 编辑
hank 发表于 2018-8-19 21:52
也就是说,你的电机跑一圈,编码器输出的脉冲是2500 * 60 ?

其实不是直接接的编码器,而是伺服驱动器的脉冲输出。电机转一圈就输出10000个脉冲。奇葩的是,这个驱动器的脉冲输出的电子齿轮比竟设置不了,只好在MCU上做分频。
回复

使用道具 举报

3

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2018-7-12
在线时间
21 小时
 楼主| 发表于 2018-8-19 22:56:09 | 显示全部楼层
ufbycd 发表于 2018-8-19 22:08
其实不是直接接的编码器,而是伺服驱动器的脉冲输出。电机转一圈就输出10000个脉冲。奇葩的是,这个驱动 ...

请问用什么型号的MCU?
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2018-8-19 23:06:14 | 显示全部楼层
hank 发表于 2018-8-19 22:56
请问用什么型号的MCU?

STM32F103C8T6
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-18 17:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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