论坛元老
 
- 积分
- 3347
- 金钱
- 3347
- 注册时间
- 2013-4-10
- 在线时间
- 333 小时
|
发表于 2019-8-23 12:14:17
|
显示全部楼层
本帖最后由 likunxue 于 2019-8-23 12:17 编辑
我做了几个试验, 就是不是很准!
#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
|
|