|
发表于 2017-2-20 22:52:18
|
显示全部楼层
本帖最后由 zlf66778899 于 2017-2-20 22:56 编辑
对定位函数分析了一下,请高手斧正
//*********************************************************************
//* This function detects the rotor position. It's input parameter is
//* the previous rotor position. It returns the current rotor position
//*********************************************************************
/*
!!!注意!!!
!>HallPatt数组的值是8进制数字
!>steady = 1时, 不产生变化的相未进行电流比较,但x和z的移位还是执行了
steady 为0时,顺次通过对ACB三相加以正反向脉冲电流的比较结果组合生产相应的位置
steady 为1时,则
a> 先取得对应sense位置的下一预期位置与sense位置比较会产生变化的一相,
b> 并对该相加以正反向脉冲电流取得比较结果
c> 根据比较结果来判断是当前位置是sense位置还是sense的下一预期位置
对steady为1时举例,调用zerostart_sensor(2, 1)的情况如下
a> y = ((HallPatt[2] & 7) ^ 2) & 7 = ((023 & 7) ^ 2) & 7 = 1
如果当前位置是位置2的下一预期位置(位置3),B相的电流比较结果应该是1,
b> 取得B相正反电流比较结果,有三种情况:
1> 正向明显大于反向 x = 1, z = 0,已经进入位置3
2> 正向明显小于反向 x = 0, z = 0,未进入位置3
3> 正向接近反向 x = 1 或 x = 0, z = 1,处于位置2和位置3的临界点
c> 判断,
如果是b>步的比较结果是情况3>则if(z & y) x = HallPatt[sense] & 7;得以执行,x被赋值3;
如果是b>步的比较结果是情况2>则if(!(x ^ (sense & y))) x = sense;得以执行,x被赋值2;
如果是b>步的比较结果是情况1>则else x = HallPatt[sense] & 7;得以执行,x被赋值3;
调用zerostart_sensor(4, 1)的情况如下
a> y = ((HallPatt[4] & 7) ^ 4) & 7 = ((046 & 7) ^ 4) & 7 = 2
如果当前位置是位置4的下一预期位置(位置6)C相的电流比较结果应该是1,
b> 取得C相正反电流比较结果,有三种情况:
1> 正向明显大于反向 x = 2, z = 0,已经进入位置3
2> 正向明显小于反向 x = 0, z = 0,未进入位置3
3> 正向接近反向 x = 2 或 x = 0, z = 2,处于位置2和位置3的临界点
c> 判断,
如果是b>步的比较结果是情况3>则if(z & y) x = HallPatt[sense] & 7;得以执行,x被赋值6;
如果是b>步的比较结果是情况2>则if(!(x ^ (sense & y))) x = sense;得以执行,x被赋值4;
如果是b>步的比较结果是情况1>则else x = HallPatt[sense] & 7;得以执行,x被赋值6;
*/
unsigned char zerostart_sensor(unsigned char sense, bit steady)
{
unsigned char x;
unsigned char y;
unsigned char z;
unsigned char resultfor,resultrev;
x=0; //x is the rotor position
z=0; //to indicate that there is no significant difference between 2 current peaks
y = HallPatt[sense] & 7; //y is the expected commutation state
y ^= sense; //y is now the bit that should change if the expected state is now the current state
y &= 0x07;
CC6_vLoadChannelShadowRegister_CC6_CHANNEL_3(0x20);
CC6_vEnableShadowTransfer_CC6_TIMER_13();
//取得A相正反电流比较结果
if(!steady || (steady && y == 0x04))
{
resultfor = currentcompare(0x16); //retrieve ADC conversion result of first current peak due to forward magnetic field in phase A
resultrev = currentcompare(0x29); //retrieve ADC conversion result of second current peak due to reverse magnetic field in phase A
if(resultfor > resultrev++) x++;
if //if there is no significant difference between the 2 current peaks from phase A
(
resultfor == resultrev ||
resultfor == (resultrev - 1) ||
resultfor == (resultrev - 2)
)
{
z++;
};
}
z<<=1;
x<<=1;
//取得C相正反电流比较结果
if(!steady || (steady && y == 0x02))
{
resultfor=currentcompare(0x25); //retrieve ADC conversion result of first current peak due to forward magnetic field in phase C
resultrev=currentcompare(0x1A); //retrieve ADC conversion result of second current peak due to reverse magnetic field in phase C
if(resultfor>resultrev++)x++;
if //if there is no significant difference between the 2 current peaks from phase C
(
resultfor==resultrev ||
resultfor==(resultrev-1) ||
resultfor==(resultrev-2)
)
{
z++;
}
}
z<<=1;
x<<=1;
//取得B相正反电流比较结果
if(!steady || (steady && y == 0x01))
{
resultfor=currentcompare(0x19); //retrieve ADC conversion result of first current peak due to forward magnetic field in phase B
resultrev=currentcompare(0x26); //retrieve ADC conversion result of second current peak due to reverse magnetic field in phase B
if(resultfor>resultrev++)x++;
if(resultfor==resultrev || resultfor==(resultrev-1) || resultfor==(resultrev-2))z++; //if there is no significant difference between the 2 current peaks from phase B
}
if(steady)
{
if(z & y) x = HallPatt[sense] & 7; //if the bit that is supposed to change(y) corresponds to the bit
//where the current peaks are almost the same(z), then the expected state is now the current state
else
{
if (!(x ^ (sense & y))) x = sense;
else x = HallPatt[sense] & 7;
}
}
return x;
}
|
|