OpenEdv-开源电子网

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

请求吧里的大神讲一下无刷电机高频输入检测位置的方法

[复制链接]

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
发表于 2019-3-14 17:08:09 | 显示全部楼层 |阅读模式
50金钱
如题,小弟读了好多论文,然后实验出现问题,用三三的方式高频注入法定位,结果只有一个三三相是对的,其他的都不对,感觉自己可能理解错了,请求吧里的大神做一下指导,实际工程应用该怎样去做这个高频注入定位?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
 楼主| 发表于 2019-3-15 15:34:07 | 显示全部楼层
为什么没人看,没人回答吗,我自己顶一下吧
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2019-8-23 12:13:01 | 显示全部楼层
这些都是别人吃饭的家伙, 高手是不会讲的,只能自已一步一步的摸索
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2019-8-23 12:14:17 | 显示全部楼层
本帖最后由 likunxue 于 2019-8-23 12:17 编辑
likunxue 发表于 2019-8-23 12:13
这些都是别人吃饭的家伙, 高手是不会讲的,只能自已一步一步的摸索

我做了几个试验, 就是不是很准!
#ifdef WEIZHIDEBIANSHISHINENG                                  //使能了转子初始位置的辨识
void BLCD_WeiZhiDeBianShi(BLCD_BYTE * const s)
     {
     static uint8_t VecSector = 0;                             //转子位置区域编号                 
     static uint8_t XULIU_TIM = 0;                             //失量检测续流时间(25x10 = 250us)         
     static uint8_t SHILIANGKUANDU = 0;                        //失量检测电压脉冲宽度(12x10 = 120us)                          
     if(s->FsmStat != STATFORWARDSTART)Stop_Motor(STATIDLE);   //任务出错
     else{            
         s->Speed_PwmCount ++;                                 //计数值加1   
         switch(s->TaskState)
               {
               case 0x00:{ //初始化定位工作  
                    CtrlParm_BusRef = 0;                       //初始化电机力矩为零  
                    SHILIANGKUANDU = 10;                       //初始失量检测时间
                    s->TaskState = 1;                          //续流时间等待处理   
                    s->SI[0] = 0;  
                    s->SI[1] = 0;  
                    s->SI[2] = 0;  
                    s->SI[3] = 0;  
                    s->SI[4] = 0;
                    s->SI[5] = 0;                        
                    }break;  
               case 0x01:{ //初始化定位工作   
                    XULIU_TIM = SHILIANGKUANDU<<1;             //初始检测续流时间  
                    CCER_SETTING(s->PWM_OFF);                  //初始续流
                    VecSector = 0;                             //初始化失量编号为零   
                    s->Speed_PwmCount = 0;                     //计数器清零
                    s->TaskState = 2;                          //续流时间等待处理                        
                    }break;   
               case 0x02:{ //续流等待
                    if(s->Speed_PwmCount == XULIU_TIM)   
                      {//续流时间到
                      CCER_SETTING(s->SVPWM_E[VecSector]);     //设置输出
                      s->Speed_PwmCount = 0;                   //清零计数器
                      s->TaskState = 3;                        //下次中断读取失量电流   
                      }   
                    }break;         
               case 0x03:{ //读取失量电流      
                    if(ADC.BUS_ElectricCurrent > s->MaxLossCurrent)
                      {// 检测电流过大了,减小检测时间         
                      if(s->Speed_PwmCount < 3)Stop_Motor(STATDUANLU);//检测电流过大了可能是电机短路或时间过长了,关闭电机
                      else{
                          SHILIANGKUANDU --;                   //检测电流过大了失量检测时间减小10uS   
                          s->TaskState = 1;                    //重新开始         
                          }
                      }                     
                    else{ //读取失量电流     
                        if(s->Speed_PwmCount == SHILIANGKUANDU) //判断每个失量电流读取的次数是否达到
                          {        
                          CCER_SETTING(s->PWM_OFF);            //设置输出为下一个失量电压续流   
                          if(ADC.BUS_ElectricCurrent < s->MinLossCurrent)
                            { //检测电流过小了
                            if(s->Speed_PwmCount > 30)Stop_Motor(STATSTARTFAIL); //启动失败,关闭电机(可能没有电机)
                            SHILIANGKUANDU += 2;               //检测电流过小了失量检测时间增大20uS
                            s->TaskState = 1;                  //调整电流后重新开始检测   
                            }         
                          else{        
                              s->SI[VecSector] = ADC.BUS_ElectricCurrent;
                              VecSector ++;                    //失量编码加1     
                              if(VecSector < 6)s->TaskState = 2; //重复读取下一个失量状态
                              else s->TaskState = 4;           //转入计算转子位置
                              }        
                          s->Speed_PwmCount = 0;               //清零计数器
                          }        
                        }                          
                    }break;
               case 0x04:{ //计算条件
                    uint16_t tm1 = CDSK_ABS(s->SI[0],s->SI[3]); //计算V1与V4的失量误差绝对值
                    uint16_t tm2 = CDSK_ABS(s->SI[1],s->SI[4]); //计算V2与V5的失量误差绝对值
                    uint16_t tm3 = CDSK_ABS(s->SI[2],s->SI[5]); //计算V3与V6的失量误差绝对值
                    if(tm1 > tm2)VecSector = (tm1 > tm3)? 0: 2;                        
                    else VecSector = (tm2 > tm3)? 1: 2;   
                    s->TaskState = 5;     
                    }break;
               case 0x05:{//判断电机转子所处的区域        
                    if(VecSector == 0)
                      {            
                      if(s->SI[0] > s->SI[3])VecSector = (s->SI[1]>s->SI[5])? 1:6; //转子处于I区域或VI区域         
                      else VecSector = (s->SI[2] > s->SI[4])? 3: 4;       //转子处于 III区域IV区域         
                      }
                    else{
                        if(VecSector == 1)
                          {
                          if(s->SI[1] > s->SI[4])VecSector = (s->SI[2]>s->SI[0])?2:1;//转子处理 I区域或II区域   
                          else VecSector = (s->SI[3] > s->SI[5])? 4: 5;   //转子处理 IV区域或V区域               
                          }
                        else{  
                            if(s->SI[2] > s->SI[5])VecSector = (s->SI[3]>s->SI[1])?3:2;//转子处理 II区域或III区域
                            else VecSector = (s->SI[4] > s->SI[0])? 5:6;  //转子处理 V区域或VI区域   
                            }        
                        }
                    s->TaskState = 6;              
                    }break;                           
               case 0x06:{ //计算转子位置   
                    switch(VecSector)
                          {
                          case 1: s->BMF_Code = (BIT_Motor_CCW)? 0x02: 0x05; break;
                          case 2: s->BMF_Code = (BIT_Motor_CCW)? 0x03: 0x04; break;   
                          case 3: s->BMF_Code = (BIT_Motor_CCW)? 0x01: 0x06; break;  
                          case 4: s->BMF_Code = (BIT_Motor_CCW)? 0x05: 0x02; break;   
                          case 5: s->BMF_Code = (BIT_Motor_CCW)? 0x04: 0x03; break;
                          case 6: s->BMF_Code = (BIT_Motor_CCW)? 0x06: 0x01; break;                        
                          }  
                    s->TaskState = 7;                       //进入转子锁定   
                    }break;
               case 0x07:{ //起动锁定  
                    Query_CommutationData(s,s->BMF_Code);   //查询换相数据及下次过零检测数据  
                    CCER_SETTING(s->JIANCE[s->Buf_Number]); //设置输出     
                    s->YiXiangBuChang = 0;                  //查表得到移相补偿周期数  
                    s->TaskState = 8;         
                    }break;                          
               case 0x08:{  //起动电机                           
                    s->ucCommutOkCnt = 0;                   //起动过零检测稳定次数统计计数器
                    s->ErrCnt = 0;                          //统计出错次数清零                             
                    s->Period4 = s->Speed_RPM050 * 4;       //初始化240度过零时间原始值
                    s->MaiKuan = s->Period4/4;              //得到60度换相时间
                    s->XiaoCiShiJian = s->Period4/16;       //得到15的消磁时间
                    CtrlParm_BusRef = ADC.LOCATION_Curr;    //写入电机起动力矩
                    PIarmBUS.OutMax = s->Startup_Voltage;   //起动电压设置限制最大母线电压输出值                          
                    Motor_DDL = BLCD_QIDONG;                //开始起动电机
                    BIT_RunMotor  = 1;                      //开电机     
                    s->Speed_PwmCount = 0;                  //清零周期计数器
                    s->TaskState = 0;                       //从零开始                                    
                    }break;
               default:Stop_Motor(STATIDLE);break;          //置空闲状态           
               }
         }                  
     }
#endif      



回复

使用道具 举报

14

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
240
金钱
240
注册时间
2016-8-4
在线时间
71 小时
发表于 2019-11-16 22:08:47 | 显示全部楼层
高频脉冲注入法一般都是基于dq坐标系的,但NXP是基于定子坐标系的(咱也不懂)。但都是根据内嵌式电机的凸极性性质,Ld<Lq,定子的电感量对应角度一般呈正弦变化,也就是电感量包含角度信息。在低速时,电机阻抗和反电势都很小,先忽略不计,那么就剩包含角度信息的电感了,那么此时的电流就能反映电感信息。
但是基于转子坐标系,一般都是在d轴注入高频脉冲Ucos(wt),然后对于的Q轴就会产生d轴的高频分量电流,这个Iq电流里包含了定子的角度信息。但此时的Iq就包含高频电路信号和正常驱动电机的低频驱动电流信号,
这是需要用过滤波将高频信号滤出来,经过处理就可以得到转速和角度。这样就可以实现低速闭环启动。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-25 21:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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