精华内容
下载资源
问答
  • TI的PMSM电机FOC控制的各个所有模块程序算法分析,挺详细的。
  • 最新版TI官方电机驱动资料 ,不下后悔,新技术,内部开发资料
  • TI永磁同步电机讲解

    2015-03-06 14:51:03
    TI永磁同步电机讲解,对永磁同步电机进行简单的介绍。希望能有帮助。
  • FOC中的Clarke变换_TI和ST电机控制的源码实现 FOC中的PARK变换_TI和ST电机控制的源码实现 FOC中的反PARK变换_TI和ST电机控制的源码实现 park变换 该变换将平衡两相正交平稳系统中的矢量变换为正交旋转坐标系。...

    FOC中的Clarke变换_TI和ST电机控制库的源码实现
    FOC中的PARK变换_TI和ST电机控制库的源码实现
    FOC中的反PARK变换_TI和ST电机控制库的源码实现

    park变换

    该变换将平衡两相正交平稳系统中的矢量变换为正交旋转坐标系。
    参考框架_TI文档
    数学公式:

    { I D = I α × cos ⁡ θ + I β × sin ⁡ θ I Q = − I α × sin ⁡ θ + I β × cos ⁡ θ \left\{ \begin{array}{l} I_D=I_{\alpha}\times \cos \theta +I_{\beta}\times \sin \theta\\ I_Q=-I_{\alpha}\times \sin \theta +I_{\beta}\times \cos \theta\\ \end{array} \right. {ID=Iα×cosθ+Iβ×sinθIQ=Iα×sinθ+Iβ×cosθ
    跟着转子旋转的“d-q”坐标系成功把cos,sin正余弦信号转化线性的了。
    theta角度是由位置传感器得到的已知变量。
    在这里插入图片描述在这里插入图片描述

    TI的实现

    也是很简单的两句计算,cos和sin(theta)是外部计算传入参数。对于三角函数,TI有自己的库去计算。
    而cos和sin(theta)不止只有在park中使用,其他地方也会使用,在这函数中再计算一次,未免多花时间了。st的库即比较麻烦。

    typedef struct {  _iq  Alpha;  		// Input: stationary d-axis stator variable 
    				  _iq  Beta;	 	// Input: stationary q-axis stator variable 
    				  _iq  Angle;		// Input: rotating angle (pu) 
    				  _iq  Ds;			// Output: rotating d-axis stator variable 
    				  _iq  Qs;			// Output: rotating q-axis stator variable
    				  _iq  Sine;
    				  _iq  Cosine; 	 
    		 	 	} PARK;	            
    
    /*------------------------------------------------------------------------------
    	PARK Transformation Macro Definition
    ------------------------------------------------------------------------------*/
    #define PARK_MACRO(v)											\
    																\
    	v.Ds = _IQmpy(v.Alpha,v.Cosine) + _IQmpy(v.Beta,v.Sine);	\
        v.Qs = _IQmpy(v.Beta,v.Cosine) - _IQmpy(v.Alpha,v.Sine);
    

    ST的库:

    ST的代码写很“规矩”,一步一步的。有很多限幅检测。
    在对theta求角度的查表法也绕了一下。解决浮点计算,统一后,全使用int型的。

    typedef struct
    {
      int16_t hCos;
      int16_t hSin;
    } Trig_Components;
    
    typedef struct
    {
      int16_t alpha;
      int16_t beta;
    } alphabeta_t;
    
    typedef struct
    {
      int16_t q;
      int16_t d;
    } qd_t;
    
    __weak qd_t MCM_Park( alphabeta_t Input, int16_t Theta )
    {
      qd_t Output;
      int32_t d_tmp_1, d_tmp_2, q_tmp_1, q_tmp_2;
      Trig_Components Local_Vector_Components;
      int32_t wqd_tmp;
      int16_t hqd_tmp;
    
      // 传入theta 查表计算得到 cos和sin的值
      Local_Vector_Components = MCM_Trig_Functions( Theta );
    
      // 不保证溢出,先计算一次,然后各种限幅判断,最后再做IQ的赋值
      /*No overflow guaranteed*/
      // 计算 alpha*cos(theta)
      q_tmp_1 = Input.alpha * ( int32_t )Local_Vector_Components.hCos;
    
      /*No overflow guaranteed*/
      // 计算 beta*sin(theta)
      q_tmp_2 = Input.beta * ( int32_t )Local_Vector_Components.hSin;
    
      /*Iq component in Q1.15 Format */
    #ifdef FULL_MISRA_C_COMPLIANCY
      wqd_tmp = ( q_tmp_1 - q_tmp_2 ) / 32768;
    #else
      /* WARNING: the below instruction is not MISRA compliant, user should verify
        that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
        the compiler to perform the shift (instead of LSR logical shift right) */
        
      // IQ的计算,计算完了,去各种限幅。 右移15是sin和cos/32768得到真正的值,又回到16位以内
      wqd_tmp = ( q_tmp_1 - q_tmp_2 ) >> 15;
    #endif
    
      /* Check saturation of Iq */
      if ( wqd_tmp > INT16_MAX )
        hqd_tmp = INT16_MAX;
      else if ( wqd_tmp < ( -32768 ) )
        hqd_tmp = ( -32768 );
      else
        hqd_tmp = ( int16_t )( wqd_tmp );
    
      Output.q = hqd_tmp;
    
      if ( Output.q == ( int16_t )( -32768 ) )
      {
        Output.q = -32767;
      }
    
      /*No overflow guaranteed*/
      d_tmp_1 = Input.alpha * ( int32_t )Local_Vector_Components.hSin;
    
      /*No overflow guaranteed*/
      d_tmp_2 = Input.beta * ( int32_t )Local_Vector_Components.hCos;
    
      /*Id component in Q1.15 Format */
    #ifdef FULL_MISRA_C_COMPLIANCY
      wqd_tmp = ( d_tmp_1 + d_tmp_2 ) / 32768;
    #else
      /* WARNING: the below instruction is not MISRA compliant, user should verify
        that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
        the compiler to perform the shift (instead of LSR logical shift right) */
      wqd_tmp = ( d_tmp_1 + d_tmp_2 ) >> 15;
    #endif
    
      /* Check saturation of Id */
      if ( wqd_tmp > INT16_MAX )
      {
        hqd_tmp = INT16_MAX;
      }
      else if ( wqd_tmp < ( -32768 ) )
      {
        hqd_tmp = ( -32768 );
      }
      else
      {
        hqd_tmp = ( int16_t )( wqd_tmp );
      }
    
      Output.d = hqd_tmp;
    
      if ( Output.d == ( int16_t )( -32768 ) )
      {
        Output.d = -32767;
      }
    
      return ( Output );
    }
    

    参考:
    TI DMC MATH_13.1pdf
    STM32 FOC 软件培训库pdf


    被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫
    在这里插入图片描述

    展开全文
  • FOC中的Clarke变换_TI和ST电机控制的源码实现 FOC中的PARK变换_TI和ST电机控制的源码实现 FOC中的反PARK变换_TI和ST电机控制的源码实现 1.位置信息 无刷电机的控制不可脱离转子的位置信息。知道转子的位置反馈...

    FOC中的Clarke变换_TI和ST电机控制库的源码实现
    FOC中的PARK变换_TI和ST电机控制库的源码实现
    FOC中的反PARK变换_TI和ST电机控制库的源码实现

    1.位置信息

    无刷电机的控制不可脱离转子的位置信息。知道转子的位置反馈是对无刷电机控制的前提。通常分为有感和无感。

    有感:即为有位置传感器,像霍尔、光电增量式编码器、旋转变压器、磁编等等。

    无感:则是电机不需要位置传感器,通过电机自身的信息计算或则估计转子的位置。

    2.无感的方法

    基于模型法的位置/转速观测器有三部分,反电动势、磁链信息观测、位置误差信号解耦位置/转速观测。反电动势或磁链信息观测方法的不同,模型有自适应法、扩展卡尔曼滤波器法、磁链观测法、状态观测法、滑膜观测法。

    反电动势过零检测法应用广泛,实现简单、技术成熟。

    3.反电动势过零检测

    3.1反电动势过零检测法基本原理:

    忽略电动机电枢反应,无刷直流电动机在稳态运行过程中,通过检测关断相的反电动势过零点获得转子的位置信号,进行对逆变器开关导通顺序切换,控制电机运动。

    3.2缺点:

    电机静止和低速时,反电动势很小或者为0,无法获取转子位置信号,电机低速时性能较差,启动时需要开环启动。

    3.3硬件电路

    在这里插入图片描述
    反电动势图:
    在这里插入图片描述
    正向反电动势过零点变化:

    反电动势零点变化趋势
    C-C相反电动势又正到负
    B+B相反电动势又负到正
    A-A相反电动势又正到负
    C+C相反电动势又负到正
    B-B相反电动势又正到负
    A+A相反电动势又负到正

    3.4电路计算:

    在这里插入图片描述
    可以直接得到电机端的电压方程:
    { U A = R i A + L d i A d t + e A + U N U B = R i B + L d i B d t + e B + U N U C = R i C + L d i C d t + e C + U N ① \left\{ \begin{array}{l} U_A=Ri_A+L\frac{di_A}{dt}+e_A+U_N\\ U_B=Ri_B+L\frac{di_B}{dt}+e_B+U_N\\ U_C=Ri_C+L\frac{di_C}{dt}+e_C+U_N\\ \end{array} \right. ① UA=RiA+LdtdiA+eA+UNUB=RiB+LdtdiB+eB+UNUC=RiC+LdtdiC+eC+UN

    假设c相不导通时有:
    { U C = e C + U N i A + i B = 0 e A + e B = 0 ② \left\{ \begin{array}{l} U_C=e_C+U_N\\ i_A+i_B=0\\ e_A+e_B=0\\ \end{array} \right. ② UC=eC+UNiA+iB=0eA+eB=0
    可以得到反电动势:
    e C = U C − 1 2 ( U A + U B ) e_C=U_C-\frac{1}{2}\left( U_A+U_B \right) eC=UC21(UA+UB)
    同理可以得到A、B相的的反电动势
    { e A = U A − 1 2 ( U C + U B ) e B = U B − 1 2 ( U A + U C ) e C = U C − 1 2 ( U A + U B ) \left\{ \begin{array}{l} e_A=U_A-\frac{1}{2}\left( U_C+U_B \right)\\ e_B=U_B-\frac{1}{2}\left( U_A+U_C \right)\\ e_C=U_C-\frac{1}{2}\left( U_A+U_B \right)\\ \end{array} \right. eA=UA21(UC+UB)eB=UB21(UA+UC)eC=UC21(UA+UB)
    通过这三个方差去判断反电动势的正负变化得到零点。但是还可以优化一下,方便编程。
    ①和②重新组合一下合一得到:
    U A + U B + U C = e C + 3 U N U_A+U_B+U_C=e_C+3U_N UA+UB+UC=eC+3UN
    当Ec=0时候满足:
    U A + U B + U C = 3 U N ③ U_A+U_B+U_C=3U_N ③ UA+UB+UC=3UN
    可以得到:
    { 3 e A = 3 U A − 3 U N 3 e B = 3 U B − 3 U N 3 e C = 3 U C − 3 U N \left\{ \begin{array}{l} 3e_A=3U_A-3U_N\\ 3e_B=3U_B-3U_N\\ 3e_C=3U_C-3U_N\\ \end{array} \right. 3eA=3UA3UN3eB=3UB3UN3eC=3UC3UN

    4.TI程序:

    4.1换向点电气行为

    **因为在在相位换向的瞬间,由于直流电平或电源板的寄生电感和电容,可能会出现高dV /dt和dI/dt毛刺。可能会对计算的中性点电压有错误。**通过丢弃前几次扫描来克服这问题。(比如从负到正,先一直为负,检测到4次为正时,标志到了过零点检测,算是滤波)

    在代码中,这是通过名为“NOISE_WIN”的功能实现的。持续时间取决于电源开关,电源板设计,相电感和驱动的直流电。此参数取决于系统,并且在电动机的低速范围内设置为较大的值。随着速度的增加,由于Bemf零交叉点也以更高的速度变得越来越近,所以逐渐降低了该持续时间。

    4.2换向30度延迟

    在有效的传感控制中,Bemf的零交叉点从相位换向时刻偏移了30º。因此,在借助六个过零事件来运行无传感器BLDC电动机之前,有必要计算与该30º延迟角相对应的时间延迟获得精确的换向点。这是通过实现位置插值功能来实现的。
    相应的时间延迟以采样时间段的数量表示,并存储在变量CmtnDelay中。

    Time delay = CmtnDelay .Ts = T(a/360) = VirtualTimer.Ts(a/360) = VirtualTimer . Ts/12

    其中,Ts是采样时间段,VirtualTimer是计时器,用于对转子上一圈旋转期间的采样周期数进行计数。

    4.3TI代码实现

    
    typedef  struct { Uint32 CmtnTrig;       	// Output: Commutation trigger output (0 or 0x00007FFF)       
                      _iq Va;                 	// Input: Motor phase a voltage referenced to GND (pu)  
                      _iq Vb;                 	// Input: Motor phase b voltage referenced to GND (pu)  
                      _iq Vc;                 	// Input: Motor phase c voltage referenced to GND (pu) 
                      _iq Neutral;            	// Variable: 3*Motor netural voltage (pu) 
                      Uint32 RevPeriod;      	 // Variable: revolution time counter (Q0)        
                      Uint32 ZcTrig;         	// Variable: Zero-Crossing trig flag (0 or 0x00007FFF)  
                      Uint32 CmtnPointer;     	// Input: Commutation state pointer input (0,1,2,3,4,5)
                      _iq DebugBemf;         	// Variable: 3*Back EMF = 3*(vx=vn), x=a,b,c (pu)
                      Uint32 NoiseWindowCounter;// Variable: Noise windows counter (Q0) 
                      Uint32 Delay30DoneFlag;   // Variable: 30 Deg delay flag (0 or 0x0000000F) 
                      Uint32 NewTimeStamp;  	// Variable: Time stamp (Q0) 
                      Uint32 OldTimeStamp;  	// History: Previous time stamp (Q0) 
    	              Uint32 VirtualTimer;    	// Input: Virtual timer (Q0) 
                      Uint32 CmtnDelay;      	// Variable: Time delay in terms of number of sampling time periods (Q0)    
                      Uint32 DelayTaskPointer; 	// Variable: Delay task pointer, see note below (0 or 1)
                      Uint32 NoiseWindowMax;  	// Variable: Maximum noise windows counter (Q0)
                      Uint32 CmtnDelayCounter; 	// Variable: Time delay counter (Q0) 
                      Uint32 NWDelta;      		// Variable: Noise windows delta (Q0)
                      Uint32 NWDelayThres;    	// Variable: Noise windows dynamic threshold (Q0)
    		 	 	   int32 GPR1_COM_TRIG;		// Variable: Division reminder
    		 	 	   int32 Tmp;				// Variable: Temp. variable
                    } CMTN;
    
    /*
    Note: 
    DelayTaskPointer = 0, branch for #COUNT_DWN
    DelayTaskPointer = 1, branch for #CHK_TRIGGER
    */
    
    /*-----------------------------------------------------------------------------
    Default initalizer for the CMTN object.
    -----------------------------------------------------------------------------*/                     
    #define CMTN_DEFAULTS { 0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            1, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                            0, \
                  		   }
    /*----------------------------------------------------------------------------------------------
    	 CMTN_TRIG Macro Definition
    ----------------------------------------------------------------------------------------------*/
    
    #define CMTN_TRIG_MACRO(v)																\
    																						\
    /* Always clear flags on entry*/														\
        v.CmtnTrig = 0;																		\
        v.ZcTrig = 0;																		\
            																				\
    /* Neutral voltage calculation (3*motor Neutral voltage)*/								\
    	v.Neutral = v.Va + v.Vb + v.Vc;														\
    																						\
    /* Commutation State table Tasks*/														\
    /* State s1: current flows to motor windings from phase A->B, de-energized phase = C*/	\
       if (v.CmtnPointer == 0)																\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vc) - v.Neutral;									\
    	  if (v.DebugBemf > 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s1*/ 														\
    																						\
    /* State s2: current flows to motor windings from phase A->C, de-energized phase = B*/ 	\
        else if (v.CmtnPointer == 1)  														\
    	{																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vb) - v.Neutral;									\
    	  if (v.DebugBemf < 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s2*/														\
    																						\
    /* State s3: current flows to motor windings from phase B->C, de-energized phase = A*/ 	\
        else if (v.CmtnPointer == 2)  														\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Va) - v.Neutral;									\
    	  if (v.DebugBemf > 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else  /*  Zero crossing Noise window processing*/									\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s3*/														\
    																						\
    /* State s4: current flows to motor windings from phase B->A, de-energized phase = C*/	\
        else if (v.CmtnPointer == 3)  														\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vc) - v.Neutral;									\
    	  if (v.DebugBemf < 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s4*/														\
    																						\
    /* State s5: current flows to motor windings from phase C->A, de-energized phase = B*/	\
        else if (v.CmtnPointer == 4)														\
        {	
            /*计算三十度延迟的flag置位*/													\
    	  v.Delay30DoneFlag = 0;	       /* clear flag for delay calc in State 5*/		\
    	  																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Vb) - v.Neutral;									\
    	  if (v.DebugBemf > 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing */								\
               NOISE_WINDOW_CNT_MACRO(v);													\
        }   /* else if-end: State s5	 */													\
    																						\
    /* State s6: current flows to motor windings from phase C->B, de-energized phase = A*/	\
        else if (v.CmtnPointer == 5)  														\
        {																					\
    	  v.DebugBemf = _IQmpy(_IQ(3),v.Va) - v.Neutral;									\
    	  if (v.DebugBemf < 0)																\
    	       v.NoiseWindowCounter = 0;													\
    	  else   /*  Zero crossing Noise window processing*/								\
               NOISE_WINDOW_CNT_MACRO(v);													\
          /*计算三十度延迟*/
          DELAY_30DEG_MACRO(v);																\
        }   /* else if-end: State s6*/														\
    																						\
    /* Zero crossing to Commutation trigger delay*/											\
       v.CmtnTrig = 0;     /* Always clear flag on entry */									\
    	
       /* 得到过零点后,进行30度延迟 */												     	\
       if (v.DelayTaskPointer > 0)     /* v.DelayTaskPointer = 1 for #CHK_TRIGGER*/			\
       { 																					\
          if (v.ZcTrig != 0)																\
          {																					\
    /* Substract NoiseWindowMax to compensate the advanced zero-crossing validation point */\
              v.CmtnDelayCounter = v.CmtnDelay - v.NoiseWindowMax;							\
              v.DelayTaskPointer = 0;     /* v.DelayTaskPointer = 0 for #COUNT_DWN*/		\
          }																					\
       }																					\
       else     /* v.DelayTaskPointer = 0 for #COUNT_DWN */									\
       {
          /* 计数减到0,得到换向点*/  										            	\
           v.CmtnDelayCounter -= 1;															\
           if (v.CmtnDelayCounter == 0) 													\
           {																				\
              v.CmtnTrig = 0x00007FFF; /* Yes!- Set trigger. This is used */				\
    /* as an input to "MOD6_CNTR" module that changes the commutation sequence.*/			\
    						             													\
              v.DelayTaskPointer = 1;       /* v.DelayTaskPointer = 1 for #CHK_TRIGGER*/	\
           }    																			\
       }
    
    /*----------------------------------------------------------------------------------------------
    	 NOISE_WINDOW_CNT Macro Definition
    ----------------------------------------------------------------------------------------------*/
    // 滤噪窗口,认为过了NoiseWindowMax个计数才算过零点
    #define NOISE_WINDOW_CNT_MACRO(v)															\
       if (v.CmtnDelay >= v.NWDelayThres)      /* noise window is fixed Value*/					\
          v.NoiseWindowMax = v.NWDelayThres - v.NWDelta;										\
       else                                       /* noise window adjusted dynamically*/		\
          v.NoiseWindowMax = v.CmtnDelay - v.NWDelta;											\
    																							\
       v.NoiseWindowCounter += 1;																\
    																							\
       if (v.NoiseWindowCounter == v.NoiseWindowMax)  /* zc must occur max_noise_window times*/	\
       {																						\
         v.ZcTrig = 0x00007FFF;       /* Yes! Set trigger */									\
         v.NoiseWindowCounter = 0;																\
       }								
    
    /*----------------------------------------------------------------------------------------------
    	DELAY_30DEG Macro Definition
    ----------------------------------------------------------------------------------------------*/
    // 30度角的延迟计算
    #define DELAY_30DEG_MACRO(v)																\
    /* Delay 30 deg calculator*/																\
       if (v.Delay30DoneFlag == 0)																\
       { 
          /*更新时间计数、计算上一圈花了多少时间*/ 								         		\
          v.OldTimeStamp = v.NewTimeStamp; 														\
          v.NewTimeStamp = v.VirtualTimer; 														\
          v.Tmp = v.NewTimeStamp - v.OldTimeStamp; 												\
          																						\
          if (v.Tmp > 0) /* Period = NewTimeStamp - OldTimeStamp*/								\
              v.RevPeriod = v.Tmp;																\
          else       /* If Period is negative, allow "wrapping"  */								\
              v.RevPeriod = 0x00007FFF + v.Tmp;													\
    																							\
          v.RevPeriod &= 0x0000FFFF;															\
    		 /* T/12算下一圈30度角延迟计数*/					         		            	\
          v.CmtnDelay = v.RevPeriod/12;                  /* Division quotient*/					\
          /* 算余数,大于6则再+1*/	
          v.GPR1_COM_TRIG = v.RevPeriod - v.CmtnDelay*12;  /* Division reminder*/				\
          if (v.GPR1_COM_TRIG >= 6) 															\
               v.CmtnDelay += 1;     /* if Division reminder >= 6, rounding division quotient*/	\
          v.Delay30DoneFlag = 0x0000000F;  /* flag indicates "gone through" once*/				\
       }   /* if-end: v.Delay30DoneFlag == 0*/    
    
    

    参考学习:
    TI Digital Motor Control,DMC MATH_V13.1
    [1]李伟.无位置传感器 BLDC 电机控制器研究[D].吉林:吉林大学.2014:7
    [2]韩芳.双模型无刷直流电动机控制器设计与实现[D].成都.电子科技大学.2015.4
    [3]刘雨锋.无刷直流电机无位置传感器关键控制技术研究[D].江西.江西理工大学.2019.5
    [4]童小健.无位置传感器永磁无刷直流电机控制策略研究[D].深圳.深圳大学.2015.4
    [5]李自成.无刷直流电机无位置传感器控制关键技术研究[D].武汉.华中科技大学.2010.3


    被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫
    在这里插入图片描述

    展开全文
  • 电机库电机库2.0

    2018-05-07 22:37:09
    电机库电机库,目前在做电机控制的,分享一下,希望有用
  • TI 电机控制讲解

    千次阅读 2019-10-22 16:39:30
    https://e2e.ti.com/blogs_/b/industrial_strength/archive/2013/04/30/teaching-your-pi-controller-to-behave-part-ix@TOC 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果...

    https://e2e.ti.com/blogs_/b/industrial_strength/archive/2013/04/30/teaching-your-pi-controller-to-behave-part-ix@TOC

    欢迎使用Markdown编辑器

    你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

    新的改变

    我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

    1. 全新的界面设计 ,将会带来全新的写作体验;
    2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
    3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
    4. 全新的 KaTeX数学公式 语法;
    5. 增加了支持甘特图的mermaid语法1 功能;
    6. 增加了 多屏幕编辑 Markdown文章功能;
    7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
    8. 增加了 检查列表 功能。

    功能快捷键

    撤销:Ctrl/Command + Z
    重做:Ctrl/Command + Y
    加粗:Ctrl/Command + B
    斜体:Ctrl/Command + I
    标题:Ctrl/Command + Shift + H
    无序列表:Ctrl/Command + Shift + U
    有序列表:Ctrl/Command + Shift + O
    检查列表:Ctrl/Command + Shift + C
    插入代码:Ctrl/Command + Shift + K
    插入链接:Ctrl/Command + Shift + L
    插入图片:Ctrl/Command + Shift + G
    查找:Ctrl/Command + F
    替换:Ctrl/Command + G

    合理的创建标题,有助于目录的生成

    直接输入1次#,并按下space后,将生成1级标题。
    输入2次#,并按下space后,将生成2级标题。
    以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

    如何改变文本的样式

    强调文本 强调文本

    加粗文本 加粗文本

    标记文本

    删除文本

    引用文本

    H2O is是液体。

    210 运算结果是 1024.

    插入链接与图片

    链接: link.

    图片: Alt

    带尺寸的图片: Alt

    居中的图片: Alt

    居中并且带尺寸的图片: Alt

    当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

    如何插入一段漂亮的代码片

    博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

    // An highlighted block
    var foo = 'bar';
    

    生成一个适合你的列表

    • 项目
      • 项目
        • 项目
    1. 项目1
    2. 项目2
    3. 项目3
    • 计划任务
    • 完成任务

    创建一个表格

    一个简单的表格是这么创建的:

    项目Value
    电脑$1600
    手机$12
    导管$1

    设定内容居中、居左、居右

    使用:---------:居中
    使用:----------居左
    使用----------:居右

    第一列第二列第三列
    第一列文本居中第二列文本居右第三列文本居左

    SmartyPants

    SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

    TYPEASCIIHTML
    Single backticks'Isn't this fun?'‘Isn’t this fun?’
    Quotes"Isn't this fun?"“Isn’t this fun?”
    Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

    创建一个自定义列表

    Markdown
    Text-to- HTML conversion tool
    Authors
    John
    Luke

    如何创建一个注脚

    一个具有注脚的文本。2

    注释也是必不可少的

    Markdown将文本转换为 HTML

    KaTeX数学公式

    您可以使用渲染LaTeX数学表达式 KaTeX:

    Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

    Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

    你可以找到更多关于的信息 LaTeX 数学表达式here.

    新的甘特图功能,丰富你的文章

    Mon 06 Mon 13 Mon 20 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
    • 关于 甘特图 语法,参考 这儿,

    UML 图表

    可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

    张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

    这将产生一个流程图。:

    链接
    长方形
    圆角长方形
    菱形
    • 关于 Mermaid 语法,参考 这儿,

    FLowchart流程图

    我们依旧会支持flowchart的流程图:

    Created with Raphaël 2.2.0 开始 我的操作 确认? 结束 yes no
    • 关于 Flowchart流程图 语法,参考 这儿.

    导出与导入

    导出

    如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

    导入

    如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
    继续你的创作。


    1. mermaid语法说明 ↩︎

    2. 注脚的解释 ↩︎

    展开全文
  • ST的电机库的实现函数: st库只使用了两相电流,一堆限幅检测猛如虎。 typedef struct { int16_t a; int16_t b; } ab_t; #define divSQRT_3 (int32_t)0x49E6 /* 1/sqrt(3) in q1.15 format=0.5773315*/ /** * @...

    FOC中的Clarke变换_TI和ST电机控制库的源码实现
    FOC中的PARK变换_TI和ST电机控制库的源码实现
    FOC中的反PARK变换_TI和ST电机控制库的源码实现

    Clarke变换

    这个变换的目的是将平衡的三相量转换为平衡的两相正交量。

    这三相电流理论上是相位相差120度的正弦波:

    { I a = I × cos ⁡ ( w t ) I b = I × cos ⁡ ( w t − 2 π / 3 ) I c = I × cos ⁡ ( w t − 4 π / 3 ) \left\{ \begin{array}{l} Ia=I\times \cos \left( wt \right)\\ Ib=I\times \cos \left( wt-2\pi /3 \right)\\ Ic=I\times \cos \left( wt-4\pi /3 \right)\\ \end{array} \right. Ia=I×cos(wt)Ib=I×cos(wt2π/3)Ic=I×cos(wt4π/3)

    在这里插入图片描述

    空间矢量表示这a,b,c三相电流。
    在这里插入图片描述

    我们更习惯于二维平面图中的直角坐标系。可以把这(Ia,Ib,Ic)三个基向量做一个很简单的正交化。

    α − β 坐 标 系 \alpha -\beta 坐标系 αβ
    变换公式:

    { I α = I a − cos ⁡ ( π 3 ) I b − cos ⁡ ( π 3 ) I c I β = sin ⁡ ( π 3 ) I b − sin ⁡ ( π 3 ) I c \left\{ \begin{array}{l} I\alpha =Ia-\cos \left( \frac{\pi}{3} \right) Ib-\cos \left( \frac{\pi}{3} \right) Ic\\ I\beta =\sin \left( \frac{\pi}{3} \right) Ib-\sin \left( \frac{\pi}{3} \right) Ic\\ \end{array} \right. {Iα=Iacos(3π)Ibcos(3π)IcIβ=sin(3π)Ibsin(3π)Ic
    基尔霍夫电流定律(KCL):

    I a + I b + I c = 0 Ia+Ib+Ic=0 Ia+Ib+Ic=0
    所以我们可以得到

    { I α = I a I β = ( 2 I b + I a 3 ) \left\{ \begin{array}{l} I\alpha =Ia\\ I\beta =\left( \frac{2Ib+Ia}{\sqrt{3}} \right)\\ \end{array} \right. {Iα=IaIβ=(3 2Ib+Ia)

    { I α = I × cos ⁡ ( w t ) I β = I × sin ⁡ ( w t ) \left\{ \begin{array}{l} I\alpha =I\times \cos \left( wt \right)\\ I\beta =I\times \sin \left( wt \right)\\ \end{array} \right. {Iα=I×cos(wt)Iβ=I×sin(wt)
    完成转换成了两相正交量。
    在这里插入图片描述

    TI的Digital Motor Control库中的实现:

    使用了IQmath的库:把运算浮点数速度提高。定点DSP实现精确的浮点运算。

    typedef struct {  _iq  As;  		// Input: phase-a stator variable
    				  _iq  Bs;			// Input: phase-b stator variable
    				  _iq  Cs;			// Input: phase-c stator variable  
    				  _iq  Alpha;		// Output: stationary d-axis stator variable 
    				  _iq  Beta;		// Output: stationary q-axis stator variable
    		 	 	} CLARKE;	            
    /*-----------------------------------------------------------------------------
    	Default initalizer for the CLARKE object.
    -----------------------------------------------------------------------------*/  
    #define CLARKE_DEFAULTS { 0, \
                              0, \
                              0, \
                              0, \
                              0, \
                  			} 
    
    //  1/sqrt(3) = 0.57735026918963
    #define  ONEbySQRT3   0.57735026918963    /* 1/sqrt(3) */
    	
    // Clarke transform macro (with 2 currents)
    // 只采用两相电流,另一相Ia+Ib+Ic=0得到
    // beta = (2*b+a)/sqrt(3)
    //==========================================
    #define CLARKE_MACRO(v)										\
    v.Alpha = v.As;												\
    v.Beta = _IQmpy((v.As +_IQmpy2(v.Bs)),_IQ(ONEbySQRT3));
    
    // Clarke transform macro (with 3 currents)
    // 三相电流时beta = (b-c)/sqrt(3)
    //==========================================
    #define CLARKE1_MACRO(v)									\
    v.Alpha = v.As;											    \
    v.Beta  = _IQmpy((v.Bs - v.Cs),_IQ(ONEbySQRT3));
    
    

    ST的电机库的实现函数:

    st库只使用了两相电流,一堆限幅检测猛如虎。

    typedef struct
    {
      int16_t a;
      int16_t b;
    } ab_t;
    
    #define divSQRT_3 (int32_t)0x49E6    /* 1/sqrt(3) in q1.15 format=0.5773315*/
    
    /**
      * @brief  This function transforms stator values a and b (which are
      *         directed along axes each displaced by 120 degrees) into values
      *         alpha and beta in a stationary qd reference frame.
      *                               alpha = a
      *                       beta = -(2*b+a)/sqrt(3)
      * @param  Input: stator values a and b in ab_t format
      * @retval Stator values alpha and beta in alphabeta_t format
      */
    __weak alphabeta_t MCM_Clarke( ab_t Input  )
    {
      alphabeta_t Output;
    
      int32_t a_divSQRT3_tmp, b_divSQRT3_tmp ;
      int32_t wbeta_tmp;
      int16_t hbeta_tmp;
    
      /* qIalpha = qIas*/
      Output.alpha = Input.a;
    
      a_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.a;
    
      b_divSQRT3_tmp = divSQRT_3 * ( int32_t )Input.b;
    
      /*qIbeta = -(2*qIbs+qIas)/sqrt(3)*/
      // 这里的右移15位,除以32768。
      // divSQRT_3  = 0x49E6 / 32768 = 0.5773315
    #ifdef FULL_MISRA_C_COMPLIANCY
      wbeta_tmp = ( -( a_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) -
                     ( b_divSQRT3_tmp ) ) / 32768;
    #else
      /* WARNING: the below instruction is not MISRA compliant, user should verify
        that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by
        the compiler to perform the shift (instead of LSR logical shift right) */
    
      wbeta_tmp = ( -( a_divSQRT3_tmp ) - ( b_divSQRT3_tmp ) -
                     ( b_divSQRT3_tmp ) ) >> 15;
    #endif
    
      /* Check saturation of Ibeta */
      if ( wbeta_tmp > INT16_MAX )
      {
        hbeta_tmp = INT16_MAX;
      }
      else if ( wbeta_tmp < ( -32768 ) )
      {
        hbeta_tmp = ( -32768 );
      }
      else
      {
        hbeta_tmp = ( int16_t )( wbeta_tmp );
      }
    
      Output.beta = hbeta_tmp;
    
      if ( Output.beta == ( int16_t )( -32768 ) )
      {
        Output.beta = -32767;
      }
    
      return ( Output );
    }
    

    __weak 前缀的函数称这个函数为“弱函数”。

    若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak属性,则这些全局符号不会引发重定义错误。链接器会忽略弱符号,去使用普通的全局符号来解析所有对这些符号的引用,但当普通的全局符号不可用时,链接器会使用弱符号

    当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号。

    参考:
    稚晖大佬:
    http://www.pengzhihui.xyz/2020/07/02/foc/#more
    STM32 FOC 软件培训库pdf
    TI DMC MATH_13.1pdf


    被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫
    在这里插入图片描述

    展开全文
  • FOC中的Clarke变换_TI和ST电机控制的源码实现 FOC中的PARK变换_TI和ST电机控制的源码实现 PARK的反变换 此变换将正交旋转坐标系中的矢量投影到两相正交固定框架。 ①经过clarke变换将三相电流变换为了固定的...
  • TI电机库,学电机驱动和矢量控制,新手必备利器
  • TI 公司电机控制程序说明文档,希望对大家有帮助
  • TI的Hercules系列单片机的电机控制的源码,包括FOC和BLDC。
  • 采用DRV8305栅极驱动器的FOC电机驱动板,用AD绘制的。
  • TI 电机控制解决方案

    2011-12-29 14:44:09
    TI电机选型及相关控制器的资料,方便大家选型,希望对大家能有所帮助
  • ti有感交流感应电机FOC控制代码,PI控制,可以使用。用来控制3KW左右的交流感应电机,很强大。
  • TI电机驱动方案

    2012-11-09 10:34:29
    TI官方提供的技术方案。英文版。详细说明了芯片的应用法。
  • ti电机控制实验室

    2017-10-07 19:17:39
    ti电机控制策略,使用timotorware的必看文档,适合快速入门和技能提高
  • TI 无刷 无感 电机 学习应用资料 及算法 超级好用 有感 无感均有详细描述 学习电机控制
  • 永磁同步电机TI滑模观测器算法源文件
  • TI官方提供的DMC控制例程,很难找的资源,对DMC电机控制仿真又较好的参考价值,值得一看。
  • 高频注入的ST的源码,找的好辛苦啊,
  • TI 335 永磁同步电机 PMSM FOC 矢量控制算法调试流程

    万次阅读 多人点赞 2018-12-26 15:45:10
    矢量控制又称磁场导向控制(Field Oriented ...TI提供了一个用于支持各种电机控制算法的DMC,其中包含很多矢量控制中用得到的功能模块,与之配套的还有一份调试指南: Sensored Field Oriented Control of 3-P...
  • 电机控制系列文章 感应(异步)电机磁场定向控制MATLAB/Simulink建模 感应(异步)电机磁场定向控制电流环PI控制参数设计 ...在TI的controlSUITE里提供了一个叫digital motor control library的,路径
  • TI旋转电机解决方案

    2011-08-05 08:26:29
    凭借自身在高级电机驱动和控制领域的深厚历史积淀与门类宽泛的模拟和微控制器产品, 可提供完整的电机系统解决方案
  • 数字电机控制 (DMC) 使用 TI 的 IQ 数学,这个支持定点和浮点数学运算。 这使得浮点至定点器件的迁移变得十分容易。 这份应用报告涵盖了以下内容: • 磁场定向电机控制原理的理论背景 • 基于模块化软件块的...
  • TI FAST算法学习笔记之电机轻载启动

    千次阅读 2018-09-01 09:14:33
    前两天用InstaSPIN-FOC的FAST算法搞了下某永磁同步电机的轻载启动,波形如下图所示。程序中使能了强制角功能,启动波形还算平滑,多次启动也未出现启动失败的情况。 不大清楚目前有多少量产的产品中使用了该算法...
  • 之前国创项目做了相关的东西,也担任了课程助教,在此过程中对于TI的伺服控制软件框架有了一定的了解。由于不是之后的研究方向,理解也不够深入,仅记录中间容易遇到的一些坑。 【1】基于28035的永磁同步机控制(无...
  • 此示例使用来自德州仪器 (TI) C2000 处理器的嵌入式编码器支持包中的 C28x 外设块和 C28x DMC 块。 对于较新的版本和其他硬件设置,请在此页面上查看此示例的发货版本: ...
  • TI-Servo_Controler.rar

    2019-05-25 14:11:02
    伺服电机代码,TI框架基础上,采用DSP编写,在TI基础上加了一些代码
  • 上一节给大家分享几篇比较好的介绍无刷电机无传感控制的文章,不知大家学习得怎么样,其实很多芯片公司(比如TI,ST,MICROCHIP,SILICON)都有推出针对他们家控制或驱动芯片的无感无刷电机控制的软硬件方案(软硬件),...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 816
精华内容 326
关键字:

ti的电机库