搜索
bottom↓
回复: 16

关于直流无刷电机速度采集的疑问

[复制链接]

出0入0汤圆

发表于 2015-11-11 22:04:57 | 显示全部楼层 |阅读模式
  
上图为本人设计的双BLCD控制系统,主要是通过2.4G遥控器来控制直流无刷电机的转速。现欲实现转速闭环控制,但在速度的采集上出现了问题,速度的采集原理大概是通过定时器捕捉中断,读取此时的捕捉值,但定时器的捕捉值不稳定,偏差太大,根本无法实现速度的采集。代码如下,希望大家看看问题出在了哪,谢谢

捕捉中断处理函数
void TIM4_IRQHandler()
{
        static uint8_t R_Count=0;

        DriveR_Motor();
        if(TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET)  //溢出中断
        {

                R_Overflow++;                               
                TIM_ClearITPendingBit(TIM4, TIM_IT_Update);       
        }
  if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)
  {
                if(TIM4->CCER&0x0002)                                       
                {
                        TIM4->CCER&=0xfffD;                               
                        R_SpeedValData+=TIM_GetCapture1(TIM4)+(R_Overflow*65535);          //读取捕捉值
                        R_Overflow=0;                                                       
                        TIM_SetCounter(TIM4,0);                 
                        R_Count++;
                        if(R_Count>200)
                        {
                                R_Count=0;
                                R_SpeedVal=R_SpeedValData/200;
                                R_SpeedValData=0;
                        }
                }
                else        
                {
                        TIM4->CCER|=0x0002;                               
                }
                TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
  }               
        if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET)
  {
                TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);
                if(TIM4->CCER&0x0020)                                       
                {
                        TIM4->CCER&=0xffdf;                                       
                }
                else        
                {
                        TIM4->CCER|=0x0020;                               
                }
  }       
        if (TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET)
  {
                TIM_ClearITPendingBit(TIM4, TIM_IT_CC3);
                if(TIM4->CCER&0x0200)                                       
                {
                        TIM4->CCER&=0xfDFf;                               
                }
                else        
                {
                        TIM4->CCER|=0x0200;                                       
                }
  }       
}


定时器初始化函数


TIM_TimeBaseStructure.TIM_Period = 0xffff;               
        TIM_TimeBaseStructure.TIM_Prescaler = 27;       
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                       
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;                                       
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;       
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
       
        /* TIM2 configuration in Input Capture Mode */
  TIM_ICStructInit(&TIM_ICInitStructure);
//TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_PWMI;
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;                               
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;       
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;                               
  TIM_ICInitStructure.TIM_ICFilter = 0;                                                                               
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
       
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;                               
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
       
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;                               
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
       
//  TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);                       
  TIM_Cmd(TIM2, ENABLE);
  TIM_ITConfig(TIM2, TIM_IT_Update|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4, ENABLE);

        /* TIM4 configuration in Input Capture Mode */
  TIM_ICStructInit(&TIM_ICInitStructure);
//TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_PWMI;
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;                               
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising ;       
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;                       
  TIM_ICInitStructure.TIM_ICFilter = 0;                                                                       
  TIM_ICInit(TIM4, &TIM_ICInitStructure);
       
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;                               
  TIM_ICInit(TIM4, &TIM_ICInitStructure);
       
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;                               
  TIM_ICInit(TIM4, &TIM_ICInitStructure);
       
// TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);                       

  TIM_Cmd(TIM4, ENABLE);
  TIM_ITConfig(TIM4, TIM_IT_Update|TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3, ENABLE);

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-11-11 23:09:08 | 显示全部楼层
不能加个L滤波吗

出0入0汤圆

发表于 2015-11-11 23:54:22 | 显示全部楼层
LZ给的信息太少了.
速度采集用的啥,目测编码器,那你定时器捕捉中断采集的是编码器的哪一相?
正交编码器的AB相信号跟编码器线数有关,直接采集的话转速一快很容易丢的.
或者采集Z相的话,太慢导致直接溢出了.
STM32的定时器只有16bit,外部信号速度快,或者时钟太快的话,溢出很快的.
其实STM32定时器直接有编码器模式,为什么不用呢?

出0入0汤圆

发表于 2015-11-12 09:11:29 | 显示全部楼层
error_dan 发表于 2015-11-11 23:54
LZ给的信息太少了.
速度采集用的啥,目测编码器,那你定时器捕捉中断采集的是编码器的哪一相?
正交编码器的AB ...

貌似楼主没用编码器。。。是不是他只想通过霍尔测速?

出0入0汤圆

发表于 2015-11-12 11:27:50 来自手机 | 显示全部楼层
楼主只是来问程序问题的,估计是对速度采集硬件电路部分没有问题。

出0入0汤圆

发表于 2015-11-12 11:45:49 | 显示全部楼层
信息太少,程序要有注释。

出0入0汤圆

 楼主| 发表于 2015-11-12 19:55:38 | 显示全部楼层
没有用编码器,只是通过电机内部的霍尔位置信号,电机能正常转动,说明霍尔信号的采集是正确的。我是想通过采集某一路霍尔信号的上升沿之间的时间,然后求导,就可以算出转速,不知道这样是否合理。现在采集的霍尔上升沿的值差的太远,非常不稳定,不知道是问题出在了哪

出0入0汤圆

 楼主| 发表于 2015-11-12 20:00:23 | 显示全部楼层
fuquan_dai 发表于 2015-11-12 09:11
貌似楼主没用编码器。。。是不是他只想通过霍尔测速?

是的,只是想通过霍尔测速,这样的小直流电机(大概300W,滑板车用),霍尔的话能否准确测出速度呢?谢谢

出0入0汤圆

 楼主| 发表于 2015-11-12 20:01:09 | 显示全部楼层
error_dan 发表于 2015-11-11 23:54
LZ给的信息太少了.
速度采集用的啥,目测编码器,那你定时器捕捉中断采集的是编码器的哪一相?
正交编码器的AB ...

感谢您的指导。没有用编码器,只是通过电机内部的霍尔位置信号,电机能正常转动,说明霍尔信号的采集是正确的。我是想通过采集某一路霍尔信号的上升沿之间的时间,然后求导,就可以算出转速,不知道这样是否合理。现在采集的霍尔上升沿的值差的太远,非常不稳定,不知道是问题出在了哪

出0入0汤圆

发表于 2015-11-12 22:13:22 | 显示全部楼层
用什么采集的?

出0入0汤圆

发表于 2015-11-12 22:13:38 | 显示全部楼层
你的速度用什么采集的?

出0入0汤圆

发表于 2015-11-14 20:58:07 | 显示全部楼层
英飞凌有个XC866的应用笔记,关于正弦波驱动的,里面有怎样用HALL信号测速的详细解释和代码,有兴趣看一下。

出0入0汤圆

发表于 2015-11-14 21:32:03 | 显示全部楼层
shuaishuai2599 发表于 2015-11-12 20:00
是的,只是想通过霍尔测速,这样的小直流电机(大概300W,滑板车用),霍尔的话能否准确测出速度呢?谢谢 ...

理论上是可以的,但是霍尔一周才有6种状态,因此得到的速度精度很低,相当于6线的编码器,而普通编码器动辄几百线。

出0入0汤圆

 楼主| 发表于 2015-11-15 18:41:06 | 显示全部楼层
因为手头没事示波器,没办法观察HALL的信号,随之改为计数模式,发现电机在停止的时候任然会进入计数中断,随机将 TIM_ICInitStructure.TIM_ICFilter = 0的值改为了10,问题解决,速度精度较高,谢谢各位的指导

出0入0汤圆

发表于 2015-11-15 19:28:36 | 显示全部楼层
mandylion2008 发表于 2015-11-14 20:58
英飞凌有个XC866的应用笔记,关于正弦波驱动的,里面有怎样用HALL信号测速的详细解释和代码,有兴趣看一下 ...

本人目前在做FOC双电机驱动,参照ST的方案,电流采样那边之前用的是MOS管内阻采样的方式,但是103只有2个ADC,还望指教一下在不改采样方案的情况下该如何处理!
或者有什么应用手册可以推荐看一下!
谢谢!

出0入0汤圆

 楼主| 发表于 2016-1-6 22:14:36 | 显示全部楼层
bi大痣 发表于 2015-11-15 19:28
本人目前在做FOC双电机驱动,参照ST的方案,电流采样那边之前用的是MOS管内阻采样的方式,但是103只有2个 ...

虽然只有2个ADC,但是每个ADC均有多个通道啊,每个通道都可以采集不同的信号啊

出0入0汤圆

发表于 2017-8-14 21:20:32 来自手机 | 显示全部楼层
mandylion2008 发表于 2015-11-14 20:58
英飞凌有个XC866的应用笔记,关于正弦波驱动的,里面有怎样用HALL信号测速的详细解释和代码,有兴趣看一下 ...

我去找来看看
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 13:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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