zoukankan      html  css  js  c++  java
  • BLDC开发笔记4.转速的计算

    以下结合自己的理解,如有错误请帮忙及时指正。

    转速公式

    转速的计算我现在是通过一定时间内,霍尔信号的边沿数量来计算的。这里每隔50ms在滴答定时器中断服务函数里面计算一次。霍尔信号每变化一次,就产生一次霍尔触发中断。因为我的电机是2对极,所以在一圈内有12个霍尔状态,即电机转动一圈会触发12次中断。假设在50ms内,霍尔触发了 n 次中断,我们可以得到转速 x 的公式:

    50ms内,

    [x=n/12 (rpms) ]

    则1ms内

    [x=n/12/50 (rpms) ]

    1s内

    [x=(n/12/50)*1000 (rps) ]

    1min内

    [x=(n/12/50)*1000*60=100n (rpm) ]

    根据这个式子就能计算出转速。

    电机参数初始化

    在头文件中声明电机参数结构体

    typedef struct
    {
    	int16_t MOTOR_POLE_NUM;    //电机极对数
            int16_t Speed_OPEN_LOOP;   //开环电机转速
    	int16_t step_counter;      //霍尔传感器脉冲数量,用于计算转速
    	uint32_t HallSpanTime;     //霍尔两次状态之间时间
    	uint8_t HallGet;           // 是否是hall触发中断
    	int32_t SpeedBck;          //速度反馈值
    }MOTOR_DEVICE;
    

    宏定义

    #define BLDC_POLE_NUM 2  //极对数
    

    对电机参数初始化

    MOTOR_DEVICE bldc_dev;         //电机参数结构体
    void Motor_Init(void)
    {
            bldc_dev.MOTOR_POLE_NUM=BLDC_POLE_NUM;  //极对数
    	bldc_dev.HallGet=0;
    	bldc_dev.HallSpanTime=0;
    	bldc_dev.SpeedBck=0;
    	bldc_dev.Speed_OPEN_LOOP=0;
    	bldc_dev.step_counter=0;
    }
    

    滴答定时器初始化

    定时器初始化,每1ms中断一次

    void SysTick_Init(void)
    {
        uint32_t prioritygroup = 0x00;
      
    	/* SystemFrequency / 1000    1ms中断一次
    	 * SystemFrequency / 100000  10us中断一次
    	 * SystemFrequency / 1000000 1us中断一次
    	 */
        SysTick_Config(SystemCoreClock / 1000);
      
        prioritygroup = NVIC_GetPriorityGrouping();  
        NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(prioritygroup, 1, 0));
    }
    

    滴答定时器中断服务函数

    编写滴答定时器中断服务函数,每50ms计算一次转速

    void SysTick_Handler(void)
    {
    	static uint16_t time_count=0;
    	time_count++;
    	if(time_count>50) // 50ms计算一次
           {
    	  uint16_t temp;
    	  temp=bldc_dev.step_counter*200/bldc_dev.MOTOR_POLE_NUM;  //计算转速
    	  printf("Speed_OPEN_LOOP=%d
    ",temp);  //打印转速 (RPM)到串口调试助手
    	  time_count=0;  //清零,重新计数
    	  bldc_dev.step_counter=0;
    	}
    	
    }
    

    霍尔触发中断服务函数

    在霍尔中断服务函数中加入计步参数,测量50ms内霍尔传感器脉冲数量,用于计算转速

    void HALL_TIM_IRQHANDLER(void)
    {	
    	if(TIM_GetITStatus(HALL_TIMx,TIM_IT_Trigger)!=RESET)
    	{
    	  HALL_TIMx_Callback();  //换相函数
    	  bldc_dev.step_counter++;	//计步
    	  TIM_ClearITPendingBit (HALL_TIMx,TIM_IT_Trigger);  //清除触发中断标志
    	}	
    }
    

    测量转速

    通过串口调试助手查看转速信息。

    用的24V电机最高转速有33000rpm,这里在开环20%占空比下,有100rpm的波动。为什么是100?其实这就是这种计算方法的局限性,我们通过一段时间内霍尔变化次数计算转速,每次变化我们就加1,所以误差的原因就在这里,我们每次只能加1,误差1通过公式中系数100(2对极)进行了放大,就变成了误差100rpm.

    后续将尝试另一种通过两个霍尔状态之间时间差计算转速的方式。

  • 相关阅读:
    IIS 浏览aspx页面出现无法显示XML页的解决方法分享
    好看的导航菜单
    C# FileUpload使用过程遇到的问题
    javascript之数组操作
    浅谈.NET下的多线程
    项目分页通用页
    npoi
    react webpack.config.js的配置及注释
    JS 解析Json 方法
    json解析
  • 原文地址:https://www.cnblogs.com/ckk-blog/p/13866831.html
Copyright © 2011-2022 走看看