shuaishuai2599 发表于 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);

usm4glx 发表于 2015-11-11 23:09:08

不能加个L滤波吗

error_dan 发表于 2015-11-11 23:54:22

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

fuquan_dai 发表于 2015-11-12 09:11:29

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

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

lxl_lw 发表于 2015-11-12 11:27:50

楼主只是来问程序问题的,估计是对速度采集硬件电路部分没有问题。

xuyaqi 发表于 2015-11-12 11:45:49

信息太少,程序要有注释。

shuaishuai2599 发表于 2015-11-12 19:55:38

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

shuaishuai2599 发表于 2015-11-12 20:00:23

fuquan_dai 发表于 2015-11-12 09:11
貌似楼主没用编码器。。。是不是他只想通过霍尔测速?

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

shuaishuai2599 发表于 2015-11-12 20:01:09

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

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

逸翮孤风 发表于 2015-11-12 22:13:22

用什么采集的?

逸翮孤风 发表于 2015-11-12 22:13:38

你的速度用什么采集的?

mandylion2008 发表于 2015-11-14 20:58:07

英飞凌有个XC866的应用笔记,关于正弦波驱动的,里面有怎样用HALL信号测速的详细解释和代码,有兴趣看一下。

fuquan_dai 发表于 2015-11-14 21:32:03

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

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

shuaishuai2599 发表于 2015-11-15 18:41:06

因为手头没事示波器,没办法观察HALL的信号,随之改为计数模式,发现电机在停止的时候任然会进入计数中断,随机将 TIM_ICInitStructure.TIM_ICFilter = 0的值改为了10,问题解决,速度精度较高,谢谢各位的指导

bi大痣 发表于 2015-11-15 19:28:36

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

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

shuaishuai2599 发表于 2016-1-6 22:14:36

bi大痣 发表于 2015-11-15 19:28
本人目前在做FOC双电机驱动,参照ST的方案,电流采样那边之前用的是MOS管内阻采样的方式,但是103只有2个 ...

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

凌晨一点 发表于 2017-8-14 21:20:32

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

我去找来看看
页: [1]
查看完整版本: 关于直流无刷电机速度采集的疑问