OpenEdv-开源电子网

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

直流无刷电机速度检测采用什么方式采集脉冲数更好?

[复制链接]

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
发表于 2016-8-24 11:04:44 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 特朗姆斯 于 2016-8-24 15:12 编辑

直流无刷电机控制方式比较简单,直接用PWM控制速度即可。

目前碰到的问题是在相同的PWM占空比下,两个相同的电机真实呈现的速度不一样,因此我想到了利用速度检测功能来对其进行校准。但是速度检测功能令我很头疼,目前采用的是把速度检测引脚连接到I/O引脚,用外部中断的方式采集一秒钟内的脉冲数来进行判断。按原子哥的说法是这种方式会使ARM频繁进入中断,不是理想的实现方式。

想到过用定时器捕获输入的方式,看完datasheet中关于定时器捕获输入的内容,似乎也是要通过中断来实现脉冲捕获,那和我使用的外部中断采集没有区别。

另外还有看到定时器外部时钟模式2,可以通过TIMx_CHx引脚触发开始计数,通过TIMx_ETR引脚来对脉冲进行计数。使用这种模式虽然可以不使用中断,但是要占用两个定时器,这两个定时器还必须是有TIMx_ETR引脚的高级定时器,加上额外的I/O资源开销似乎也是得不偿失。


目前研究下来差不多是上述情况,希望有大神给予指引。


ps:我用的直流无刷电机有配套的控制器,ARM采集的脉冲数由控制器发出。

最佳答案

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

我以前试过,这个方法至少可以测到5Hz~25MHz的频率,精度0.03%以下 [mw_shl_code=c,true]//TIM7->100ms //TIM2_CH2->PB3 void TIM_Cnt_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_DeInit(TIM2); TIM_DeInit(TIM7); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM7,ENABLE); //TIM ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-8-24 11:04:45 | 显示全部楼层
特朗姆斯 发表于 2016-8-24 13:57
可能是我没讲清楚,我用了一个控制器控制直流无刷电机,这个控制器会返回脉冲数。

我想要统计1s内采 ...

我以前试过,这个方法至少可以测到5Hz~25MHz的频率,精度0.03%以下
[mw_shl_code=c,true]//TIM7->100ms
//TIM2_CH2->PB3
void TIM_Cnt_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        TIM_DeInit(TIM2);
        TIM_DeInit(TIM7);
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM7,ENABLE);          //TIM2时钟使能   
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);         //使能PORTA时钟       
//IO       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //GPIOA0
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;        //速度100MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //下拉
        GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PA0
       
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_TIM2); //PA0复用位定时器5
//TIM2配置       
        TIM_TimeBaseStructure.TIM_Prescaler=0;  //定时器分频
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStructure.TIM_Period=0xFFFFFFFF;   //自动重装载值
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
       
        TIM_TIxExternalClockConfig(TIM2,TIM_TIxExternalCLK1Source_TI2,TIM_ICPolarity_Rising,0);//外部时钟源
//TIM7        100ms       
        TIM_TimeBaseStructure.TIM_Prescaler=18000-1;  //定时器分频
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStructure.TIM_Period=1000-1;   //自动重装载值
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_TimeBaseInit(TIM7,&TIM_TimeBaseStructure);
//中断
  NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器、
        TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);//允许更新中断 ,允许CC1IE捕获中断       

        TIM_Cmd(TIM7,ENABLE );         //使能定时器5
  TIM_Cmd(TIM2,ENABLE );         //使能定时器5       
}
volatile u32 TIM_ExtCntFreq;
u32 TIM7_LastCnt;
void TIM7_IRQHandler(void)
{
        char        str[32];
        TIM_ExtCntFreq=(TIM2->CNT-TIM7_LastCnt)*10;
        sprintf(str,"%3.3f",TIM_ExtCntFreq/1000.0);//必须加这一句,莫明其妙
        TIM7_LastCnt=TIM2->CNT;
        TIM_ClearITPendingBit(TIM7,TIM_IT_Update);
}[/mw_shl_code]
回复

使用道具 举报

5

主题

121

帖子

0

精华

高级会员

Rank: 4

积分
617
金钱
617
注册时间
2016-1-26
在线时间
149 小时
发表于 2016-8-24 11:09:18 | 显示全部楼层
定时器有主从模式,用主定时器来给从定时器提供时钟,这样主定时器每产生一个脉冲,从定时器计数一次,即你所需的脉冲数
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-24 11:16:43 | 显示全部楼层
无休 发表于 2016-8-24 11:09
定时器有主从模式,用主定时器来给从定时器提供时钟,这样主定时器每产生一个脉冲,从定时器计数一次,即你 ...

脉冲是由直流无刷电机提供的,不是主定时器提供脉冲
回复

使用道具 举报

5

主题

121

帖子

0

精华

高级会员

Rank: 4

积分
617
金钱
617
注册时间
2016-1-26
在线时间
149 小时
发表于 2016-8-24 11:21:58 | 显示全部楼层
特朗姆斯 发表于 2016-8-24 11:16
脉冲是由直流无刷电机提供的,不是主定时器提供脉冲

脉冲怎么会是由电机提供的,电机可以给自身提供脉冲?你用了编码器的吧?
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-8-24 11:26:10 | 显示全部楼层
配置两个定时器,定时器a设置为外部时钟计数器模式,定时器b设置为定时器(比如50ms溢出一次),然后定时器b中断函数中统计定时器a在这段时间内的增量就行
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-8-24 11:34:45 | 显示全部楼层
本帖最后由 止天 于 2016-8-24 11:35 编辑

定时器捕获输入可以用dma   我用过,
计数模式只是用频率低的  
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-24 13:53:00 | 显示全部楼层
无休 发表于 2016-8-24 11:21
脉冲怎么会是由电机提供的,电机可以给自身提供脉冲?你用了编码器的吧?

对,用了一个控制器
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-24 13:54:31 | 显示全部楼层
止天 发表于 2016-8-24 11:34
定时器捕获输入可以用dma   我用过,
计数模式只是用频率低的

DMA的话还是要用到中断,我的整个工程要跑RTOS,频繁中断不妥
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-24 13:57:09 | 显示全部楼层
yyx112358 发表于 2016-8-24 11:26
配置两个定时器,定时器a设置为外部时钟计数器模式,定时器b设置为定时器(比如50ms溢出一次),然后定时器 ...


可能是我没讲清楚,我用了一个控制器控制直流无刷电机,这个控制器会返回脉冲数。

我想要统计1s内采集的脉冲数来获得速度值,目前困惑于如何去采集更佳
回复

使用道具 举报

5

主题

121

帖子

0

精华

高级会员

Rank: 4

积分
617
金钱
617
注册时间
2016-1-26
在线时间
149 小时
发表于 2016-8-24 15:21:14 | 显示全部楼层
无休 发表于 2016-8-24 11:21
脉冲怎么会是由电机提供的,电机可以给自身提供脉冲?你用了编码器的吧?

我觉得你方向走错了!不应该去考虑速度上的一致,首先是这种方式受电机单个特性影响,而电机随着工作时间的不同,也会表现出不同的性能,也会受电源的影响,其次你得到的速度也不一定是准确的,这要考虑到时间的问题,比较复杂。建议不采用这种方式,如果两个电机速度不一样可以考虑PID调节,这样两个电机才有可能实现一种速度同步
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-24 15:36:34 | 显示全部楼层
无休 发表于 2016-8-24 15:21
我觉得你方向走错了!不应该去考虑速度上的一致,首先是这种方式受电机单个特性影响,而电机随着工作时间 ...

我知道可以用PID调节两个电机速度,从而实现同步。

问题是最基本的检测两个电机速度的功能也没有做好,何谈PID调节?
回复

使用道具 举报

5

主题

121

帖子

0

精华

高级会员

Rank: 4

积分
617
金钱
617
注册时间
2016-1-26
在线时间
149 小时
发表于 2016-8-24 15:47:11 | 显示全部楼层
特朗姆斯 发表于 2016-8-24 15:36
我知道可以用PID调节两个电机速度,从而实现同步。

问题是最基本的检测两个电机速度的功能也没有做好 ...

检测脉冲数无非是使用查询和中断两种方式,这就得看你用的什么编码器了,一般确实是用的中断获取这个值,但如果你不在中断里做太多的事,肯定是可以使用的!
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-24 15:55:20 | 显示全部楼层
无休 发表于 2016-8-24 15:47
检测脉冲数无非是使用查询和中断两种方式,这就得看你用的什么编码器了,一般确实是用的中断获取这个值, ...

中断服务程序中只做计数加一,目前确实可以实现。但是在电机速度比较快的情况下这个中断频率可能会达到0.7ms一次,我认为过于频繁了。

至于轮询那不可能,RTOS系统下轮询0.7ms一个的脉冲效率太低了。


这个帖子想要探讨的是不使用频繁中断,实现对I/O电平收到的脉冲计数。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2016-8-24 19:49:50 | 显示全部楼层
特朗姆斯 发表于 2016-8-24 15:55
中断服务程序中只做计数加一,目前确实可以实现。但是在电机速度比较快的情况下这个中断频率可能会达到0. ...

用外部脉冲计数,溢出时才进入一次中断。
这样65536个脉冲才进入一次中断,可以去到很高的计数频率,而中断频率则不高。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-25 16:32:47 | 显示全部楼层
本帖最后由 特朗姆斯 于 2016-8-25 16:34 编辑
正点原子 发表于 2016-8-24 19:49
用外部脉冲计数,溢出时才进入一次中断。
这样65536个脉冲才进入一次中断,可以去到很高的计数频率,而 ...


感谢原子哥晚上来回复!

这个外部脉冲计数模式是指定时器的从模式里的外部计数模式2吗 ?我看到datasheet里写的是要用到定时期通道引脚来触发外部脉冲计数开始,然后用定时器ETR引脚来进行脉冲计数。这样是不是相当于用硬件I/O资源和定时期资源来换取程序的稳定性。
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-25 17:55:19 | 显示全部楼层
yyx112358 发表于 2016-8-24 15:52
我以前试过,这个方法至少可以测到5Hz~25MHz的频率,精度0.03%以下
[mw_shl_code=c,true]//TIM7->100ms
...

MARK~非常感谢

但是这个方案耗费2个定时器,目前没有这么多资源可用。
回复

使用道具 举报

62

主题

902

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3559
金钱
3559
注册时间
2016-1-8
在线时间
543 小时
发表于 2016-8-25 18:04:52 | 显示全部楼层
中断
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-8-25 19:45:21 | 显示全部楼层
特朗姆斯 发表于 2016-8-25 17:55
MARK~非常感谢

但是这个方案耗费2个定时器,目前没有这么多资源可用。

那也可以用ucos的软件定时器啊,就是精度低些
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-26 10:17:12 | 显示全部楼层
yyx112358 发表于 2016-8-25 19:45
那也可以用ucos的软件定时器啊,就是精度低些

软件定时器精度差太多了。。从来不考虑用这个。。
回复

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-8-26 22:46:45 | 显示全部楼层
回复

使用道具 举报

6

主题

201

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1149
金钱
1149
注册时间
2015-11-13
在线时间
267 小时
 楼主| 发表于 2016-8-29 08:49:30 | 显示全部楼层
yyx112358 发表于 2016-8-26 22:46
我发了一个教程
http://www.openedv.com/thread-82594-1-1.html

感谢奉献精神,推荐置酷。

@正点原子
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-8-14
在线时间
3 小时
发表于 2016-9-30 11:29:20 | 显示全部楼层
???????????
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-28 18:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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