📄 arithmetics.c
字号:
}
else
{
if(APlusPeriod==1) //处于正半周
{//锁定频率开始
//由于已经确认了正半周,只要找到一些负点,即认为过零,此处的过零误差由算法决定,应该控制在1%
if(Voltage<=0)
AMinusNum++;
else
if(AMinusNum>0)
AMinusNum--;
else
AMinusNum=0;
if(AMinusNum==4) //零点找到
{
AMinusNum=0;
APlusPeriod=0;
return 1;
}
else
return 0;
}
else
return 0;
}
return 0;
}
//B相
int16 LockBZero(int16 Voltage)
{
/*
int16 PlusPeriod=0; //正半周标志位0为不处于,1为处于正半周
int16 PlusNum=0;
int16 MinusNum=0; ///????????????????????????
*/
//找到正半周
if(BPlusPeriod==0)
{
if(Voltage>=0)
BPlusNum++;
else
BPlusNum=0;
if(BPlusNum==100) //一定处于正半周
{
BPlusPeriod=1;
BPlusNum=0;
}
}
else
{
if(BPlusPeriod==1) //处于正半周
{//锁定频率开始
if(Voltage<=0)
BMinusNum++;
else
if(BMinusNum>0)
BMinusNum--;
else
BMinusNum=0;
if(BMinusNum==4) //零点找到
{
BMinusNum=0;
BPlusPeriod=0;
return 1;
}
else
return 0;
}
else
return 0;
}
return 0;
}
//C相
int16 LockCZero(int16 Voltage)
{
/*
int16 PlusPeriod=0; //正半周标志位0为不处于,1为处于正半周
int16 PlusNum=0;
int16 MinusNum=0; ///????????????????????????
*/
//找到正半周
if(CPlusPeriod==0)
{
if(Voltage>=0)
CPlusNum++;
else
CPlusNum=0;
if(CPlusNum==100) //一定处于正半周
{
CPlusPeriod=1;
CPlusNum=0;
}
}
else
{
if(CPlusPeriod==1) //处于正半周
{//锁定频率开始
if(Voltage<=0)
CMinusNum++;
else
if(CMinusNum>0)
CMinusNum--;
else
CMinusNum=0;
if(CMinusNum==4) //零点找到
{
CMinusNum=0;
CPlusPeriod=0;
return 1;
}
else
return 0;
}
else
return 0;
}
return 0;
}
/*====================================================================================================
二、锁定参考正弦零点(从正到负)
=====================================================================================================*/
//输入:1. 参考正弦周期点数,2当前计数点数
//输出:是否锁定到零点1为锁定零点
int16 LockRefZero(int16 Period, int16 NowPoint)
{
if(NowPoint<Period)
return 0;
else
return 1;
}
/*====================================================================================================
三、检测直流母线: 是否高于参考值,使用滞环,开关逆变
=====================================================================================================*/
//要求:每个载波周期都要调用一次
//输入:直流母线的采样电压
//改变vollinestart的值:是否开逆变:1为直流母线高于参考设定,可以开逆变
void LockVolLine(int16 VolLine)
{
if(VolLineStart==0) //未开逆变
{
if(VolLineCount<10) //10次连续高于开启逆变阀值
{
if(VolLine>=RetifyVol)
VolLineCount++;
else
VolLineCount=0;
}
else
{
VolLineCount=0; //重设
VolLineStart=1; //开逆变
}
}
/*
else if(VolLineStart==1) //已开逆变
{
if(VolLineCount<10) //10次连续低于(参考-滞环)
{
if(VolLine<(VoltageRef-VoltageDelay))
VolLineCount++;
else
VolLineCount=0;
}
else
{
VolLineCount=0; //重设
VolLineStart=0; //关逆变
}
}
else //vollinestart不为1不为0
{
VolLineCount=0;
VolLineStart=0;
}
*/
}
/*====================================================================================================
三、检测三相电压: 是否过低,过低认为三相丢失,封锁pwm
//PS: 此处相电压
=====================================================================================================*/
//要求:每个载波周期都要调用一次
//输入:三相电压的采样电压
//改变Issina,issinb,issinc的值,1为三相电压正常,0为相电压丢失
void LockVolSine(int16 AVol)//int16 BVol, int16 CVol)
{
if(IsSinA==0) //三相电压低时,检测到连续20个高,认为合格
{
if(SinAcount<20) ////20次连续高于标准
{
if(AVol>SineLow)
SinAcount++;
else
SinAcount=0;
}
else
{
SinAcount=0;
IsSinA=1; //正常
}
}
else //三相电压高时,检测到连续350个低,认为不合格
{
if(SinAcount<350)
{
if(AVol<=SineLow)
SinAcount++;
else
SinAcount=0;
}
else
{
SinAcount=0;
IsSinA=0;
}
}
/*
if(IsSinB==0) //三相电压低时,检测到连续20个高,认为合格
{
if(SinBcount<20) ////20次连续高于标准
{
if(BVol>SineLow)
SinBcount++;
else
SinBcount=0;
}
else
{
SinBcount=0;
IsSinB=1; //正常
}
}
else //三相电压高时,检测到连续350个低,认为不合格
{
if(SinBcount<350)
{
if(BVol<=SineLow)
SinBcount++;
else
SinBcount=0;
}
else
{
SinBcount=0;
IsSinB=0;
}
}
if(IsSinC==0) //三相电压低时,检测到连续20个高,认为合格
{
if(SinCcount<20) ////20次连续高于标准
{
if(CVol>SineLow)
SinCcount++;
else
SinCcount=0;
}
else
{
SinCcount=0;
IsSinC=1; //正常
}
}
else //三相电压高时,检测到连续350个低,认为不合格
{
if(SinCcount<350)
{
if(CVol<=SineLow)
SinCcount++;
else
SinCcount=0;
}
else
{
SinCcount=0;
IsSinC=0;
}
}
*/
}
/*====================================================================================================
正弦波发生器
=====================================================================================================*/
//产生从-3.14到3.14的正弦波
//输入:1. 一个周期的总点数,2.当前计算的点
//返回:当前点对应的正弦波值Q15格式
int16 SinProduce(int16 PeriodNum, int16 Point)
{
int16 Interval; //间距
int16 PointValue; //当前点对应的弧度
if(Point>PeriodNum) // 以超过一个周期,则重新回到负半周
{
Point=Point-PeriodNum;
}
if(Point<0) //由于sine偏置的存在,可能会有<0的情况
{
Point=Point+PeriodNum;
}
Interval=(qinv2(PeriodNum))<<1; // 2/PeriodNum Q15格式
PointValue=-32768+Interval*Point; //从-1开始递增 Q15
return qsin(PointValue); //Q15格式
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -