core_com.c
来自「嵌入式开发 嵌入式开发 嵌入式开发」· C语言 代码 · 共 1,744 行 · 第 1/5 页
C
1,744 行
}
}
}
/******************************
描述: 当从单标记恢复到正常套色的时候 从下位机记录的命令中获取原来的标记排列设置
******************************/
void GetNormalTurns(const int iCNL, const unsigned char iDAT)
{
switch( iDAT&0x30 )
{
case 0x00: //整机正序
case 0x20: //本组正序
if( unit[iCNL].submenu1.unitworksnum.i==1 )
{ unit[iCNL].submenu1.bitTurns.turnsoflabsA=((iDAT&0x08)?4:1);}
else
{ unit[iCNL].submenu1.bitTurns.turnsoflabsB=((iDAT&0x08)?4:1);}
break;
case 0x10: //整机逆序
case 0x30: //本组逆序
if( unit[iCNL].submenu1.unitworksnum.i==1 )
{ unit[iCNL].submenu1.bitTurns.turnsoflabsA=((iDAT&0x08)?5:2);}
else
{ unit[iCNL].submenu1.bitTurns.turnsoflabsB=((iDAT&0x08)?5:2);}
break;
default:
break;
}
}
/******************************
描述: 重新设定和波形显示相关的各项参数值
参数: iCNL 通道号 , iHEADER 显示起点为0表示从波形区域最左端开始
******************************/
void ResetWavAttrib(const int iCNL, const int iHEADER)
{
long vLONG;
float vFLOAT;
unsigned int vUINT_C;
unsigned char vSTurns,vSErRec=unit[iCNL].submenu1.unitworksnum.i; //系属
if(vSErRec==1)
{ vUINT_C=SysSet.CofBanA; vSTurns=SysSet.bitTurns.TurnofLabsA;}
else
{ vUINT_C=SysSet.CofBanB; vSTurns=SysSet.bitTurns.TurnofLabsB;}
//___calculate [RulerLength]
vFLOAT=20*(20000.0/vUINT_C)+0.5;
vLONG =vFLOAT;
RulerLength=(unsigned int)(vLONG*MaxScale/2);
//___calculate [displaywidth]
vFLOAT=unit[iCNL].submenu2.ValueWidth*200000.0/vUINT_C+0.5;
vLONG =vFLOAT;
if(vUINT_C>=5000)
{ displaywidth[iCNL]=(int)(vLONG/5);}
else
{ displaywidth[iCNL]=(int)(vLONG/10);}
//___calculate [addrpoint]
addrpoint=unit[iCNL].submenu1.addressofwav*MaxScale/2;
//___calculate [displaybar]
if( iHEADER )
{
//究竟采用SysSet.bitTurns.TurnofLabsA 还是
//unit[iCNL].submenu1.bitTurns.turnsoflabsA 更合理一些 ???
if(vSTurns==2 || vSTurns==5)
{ lineheader[iCNL]=addrpoint-2*RulerLength;}
else
{ lineheader[iCNL]=addrpoint+2*RulerLength+displaywidth[iCNL]-1000*Scaling;}
}
else
{
if( (addrpoint>RulerLength) && (addrpoint<(1000*Scaling-RulerLength)) )
{ lineheader[iCNL]=0;}
else
{ lineheader[iCNL]=addrpoint-RulerLength;}
}
displaybar[iCNL]=12+(addrpoint-lineheader[iCNL])/Scaling;
if(lineheader[iCNL]<0)
{ lineheader[iCNL]+=1000*MaxScale;}
}
/******************************
描述: 设定指定通道是否做智能寻址
参数: iCNL检验的通道号; iVAL设定的值
******************************/
void SetwjrSearAddrFlags(const int iCNL, const unsigned char iVAL)
{
unsigned uVAL=((unsigned)0x0001<<iCNL);
int Bsuffix=((unit[iCNL].submenu1.unitworksnum.i==2) ? 1 : 0); // 不是B系的都作为A系看待
if( iVAL )
{ EntireStatus.EntireIntelligentFlags[Bsuffix]|=uVAL;}
else
{ uVAL^=0xffff; EntireStatus.EntireIntelligentFlags[Bsuffix]&=uVAL;}
}
/******************************
描述: 获得将要处理的首通道
参数: iSER系属
返回:
>0表示正常通道
=0表示没有需要做自动寻址的通道了
******************************/
int hjGetNextProc(const unsigned char iSER)
{
int t,iret=0;
unsigned uVAL=0x0001;
for(t=1; t<VarST3000.UnitCounts; t++)
{
if( EntireStatus.EntireIntelligentFlags[iSER-1]&(uVAL<<t) )
{ iret=t; break;}
}
return iret;
}
/******************************
描述: 获得纵横向的工作状态 即判断通道的工作属性是否属于自动方式
******************************/
unsigned char WhetherCUAuto(const int iCNL)
{
unsigned char iret=unit[iCNL].submenu1.bitfield.hand_auto;
if( unit[iCNL].submenu1.bitfield.hcontrol )
{ iret&=unit[iCNL].submenu1.bitfield.h_motorruning;}
return(iret);
}
/******************************
描述: 控制报警
******************************/
void ST3000AlarmCtrl(const unsigned char iSER)
{
//___只有当在波形显示界面报警是否开关仅和选中通道有关
if( (VarST3000.MenuIDSEL==2) && (VarST3000.SubIDSEL==3) )
{ //___波形界面
if( (VarST3000.AlarmCtrlOnOff) && GetEntireFlags(UnitSEL-1) )
{
if(iSER==1) { OUT7&=0x7f;}
else { OUT7&=0xbf;}
}
else
{
if(iSER==1) { OUT7|=0x80;}
else { OUT7|=0x40;}
}
outportb(0x302, OUT7);
}
else
{ //___除此之外其他任何界面
if( (VarST3000.AlarmCtrlOnOff) &&
(EntireStatus.EntireVAlarmFlags[iSER-1] || EntireStatus.EntireHAlarmFlags[iSER-1] || EntireStatus.EntireLapseFlags[iSER-1]) )
{ if(iSER==1) { OUT7&=0x7f;}
else { OUT7&=0xbf;}
}
else
{ if(iSER==1) { OUT7|=0x80;}
else { OUT7|=0x40;}
}
outportb(0x302, OUT7);
}
}
/******************************
Func: 查询单元上报属于复位还是属于修改单元号码
又或者是新安装的单元
Parameters:
-iCNL; 通道号
-rDAT; rDAT接收到的CAN信息数据
Return:
-0 新上报的通道
-1 修改单元号码
-2 单元复位
******************************/
int _GetTypeCmd0(const int iCNL, const unsigned char *rDAT)
{
int t;
for(t=1; t<=VarST3000.UnitActuals; t++)
{
if( rDAT[0]==checkbuffer[t].buffer[4] &&
rDAT[1]==checkbuffer[t].buffer[5] &&
rDAT[2]==checkbuffer[t].buffer[6] )
{ // 编号相同的通道
if( checkbuffer[t].buffer[3]==iCNL )
{ return 2;} // 连机组号都一致 表明是单元复位
else
{ return 1;} // 机组号出现不一致 表明是用户修改机组号
}
}
return 0;
}
/******************************
描述: 单元复位 或者上电 可以正常工作所需要的命令
参数: iCNL通道号; rDAT接收到的CAN信息数据
******************************/
extern const _tagMenuAttr MenuAttr;
extern const _tagSizeAttr SizeConfig;
void SyncRcvCmd0(const int iCNL, const unsigned char *rDAT)
{
int tCnl,iDelay=((VarST3000.MenuIDSEL==1) ? 10 : 100);
switch( _GetTypeCmd0(iCNL, rDAT) )
{
case 0:
if( VarST3000.UnitActuals>=(MAXCNL_3K-1) ) { return;}
checkbuffer[++VarST3000.UnitActuals].buffer[3] =iCNL; // 此时ReportNum已经改变
checkbuffer[VarST3000.UnitActuals].unitnumber=iCNL;
checkbuffer[VarST3000.UnitActuals].buffer[4]=rDAT[0];
checkbuffer[VarST3000.UnitActuals].buffer[5]=rDAT[1];
checkbuffer[VarST3000.UnitActuals].buffer[6]=rDAT[2];
ReSortCURecv();
break;
case 1: // 修改单元号 (不能和case 2:交换顺序 也不能在1后加break;
for(tCnl=1; tCnl<=VarST3000.UnitActuals; tCnl++)
{
if( checkbuffer[tCnl].buffer[4]==rDAT[0] &&
checkbuffer[tCnl].buffer[5]==rDAT[1] &&
checkbuffer[tCnl].buffer[6]==rDAT[2] )
{
checkbuffer[tCnl].buffer[3]=iCNL;
checkbuffer[tCnl].unitnumber=tCnl;
break;
}
}
ReSortCURecv();
case 2: // 单元复位
/*SendCnlData(iCNL, 0x08); delay(iDelay);
SendCnlData(iCNL, 0x09); delay(600);
SendCnlData(iCNL, 0x0A); delay(iDelay);
SendCnlData(iCNL, 0x0B); delay(iDelay);
SendCnlData(iCNL, 0x07); delay(650); //由于通道接收到6号工作命令 需要480ms(4000采样)初始化DMA
SendCnlData(iCNL, 0x06);*/
_Append_jzCmdList(iCNL,0x08);delay(iDelay);
_Append_jzCmdList(iCNL,0x09);delay(550);
_Append_jzCmdList(iCNL,0x0A);delay(iDelay);
_Append_jzCmdList(iCNL,0x0B);delay(iDelay);
_Append_jzCmdList(iCNL,0x07);delay(iDelay);
_Append_jzCmdList(iCNL,0x06);delay(600);
break;
default:
break;
}
//2007-3-9 16:10原来 if是在 case 2里
if( VarST3000.MenuIDSEL==7 && vNewPageSEL7==7 )
{
DrawCfgTable(MenuAttr.sX+MenuAttr.tW+(MenuAttr.bW-SizeConfig.w)/2, MenuAttr.sY+80);
// 清除输入缓冲区 屏蔽小数和符号输入 限定为2有效数长度
ClearKBuffer();
g_Kmask=0x03; g_Klength=2;
}
}
/******************************
描述: 处理误差接收命令 2005-11-25 最终更新
参数: iCNL通道号; rDAT接收到的CAN信息数据
******************************/
void SyncRcvCmd4(const int rCNL, const unsigned char *rDAT)
{
int hRCV,vRCV;
int i,StartHeader;
long vSum,hSum; // 用来统计需要平均的最近AVERAGE_TIMES次误差数据
unsigned char bFLAG=0,Bjob=unit[rCNL].submenu1.unitworksnum.i;
// 纵向误差
vRCV =rDAT[0]&0x7F;
vRCV<<=8;
vRCV+=rDAT[1];
if( rDAT[0]&0x80 ) { vRCV*=-1;}
if( abs(vRCV)>=abs(unit[rCNL].submenu1.v_alarm) )
{ bFLAG|=0x01;}
if( (bFLAG&0x01) && (unit[rCNL].submenu1.bitfield.hand_auto) )//纵向手动自动
{ SetEntireFlags(rCNL, ((Bjob==1) ? 0x10 : 0x11), 1);}//设置整机通道状态
else
{ SetEntireFlags(rCNL, ((Bjob==1) ? 0x10 : 0x11), 0);}
// 横向误差
if( unit[rCNL].submenu1.bitfield.hcontrol )
{
hRCV =rDAT[4]&0x7F;
hRCV<<=8;
hRCV+=rDAT[5];
if( rDAT[4]&0x80 ) { hRCV*=-1;}
if( abs(hRCV)>=abs(unit[rCNL].submenu1.h_alarm) )
{ bFLAG|=0x02;}
if( (bFLAG&0x02) && (unit[rCNL].submenu1.bitfield.h_motorruning) )// 横向马达开
{ SetEntireFlags(rCNL, ((Bjob==1) ? 0x20 : 0x21), 1);}//设置整机通道状态
else
{ SetEntireFlags(rCNL, ((Bjob==1) ? 0x20 : 0x21), 0);}//设置整机通道状态
}
// 记录实际的误差
vRealErr[rCNL]=vRCV;
vRealHisErr[rCNL][hjCurvHeader[rCNL]]=vRealErr[rCNL]; // 记录用于平均曲线的误差
hRealErr[rCNL]=hRCV;
hRealHisErr[rCNL][hjCurvHeader[rCNL]]=hRealErr[rCNL]; // 记录用于平均曲线的误差
//显示最大上限判断
if( vRealHisErr[rCNL][hjCurvHeader[rCNL]]>=100 )
{ vRealHisErr[rCNL][hjCurvHeader[rCNL]]=100;}
else if( vRealHisErr[rCNL][hjCurvHeader[rCNL]]<=-100 )
{ vRealHisErr[rCNL][hjCurvHeader[rCNL]]=-100;}
if(hRealHisErr[rCNL][hjCurvHeader[rCNL]]>=100)
{ hRealHisErr[rCNL][hjCurvHeader[rCNL]]=100;}
else if(hRealHisErr[rCNL][hjCurvHeader[rCNL]]<=-100)
{ hRealHisErr[rCNL][hjCurvHeader[rCNL]]=-100;}
// 对曲线上的误差进行平均处理
#ifdef AVERAGE_ERROR
StartHeader=hjCurvHeader[rCNL];
vSum=vRealHisErr[rCNL][StartHeader];
hSum=hRealHisErr[rCNL][StartHeader];
for(i=1; i<AVERAGE_TIMES; i++)
{
if( --StartHeader<0 ) { StartHeader=BOX34_W-1;}
vSum+=vRealHisErr[rCNL][StartHeader];
hSum+=hRealHisErr[rCNL][StartHeader];
}
// 此时使用 vRCV .&. hRCV 来临时保存计算出来的当前误差点
vRCV = (int)(vSum/AVERAGE_TIMES);
hRCV = (int)(hSum/AVERAGE_TIMES);
vCurvErr[rCNL][hjCurvHeader[rCNL]]=vRCV*(BOX34_H/2)/100;
hCurvErr[rCNL][hjCurvHeader[rCNL]]=hRCV*(BOX34_H/2)/100;
#else
vCurvErr[rCNL][hjCurvHeader[rCNL]]=vRealErr[rCNL]*(BOX34_H/2)/100;
hCurvErr[rCNL][hjCurvHeader[rCNL]]=hRealErr[rCNL]*(BOX34_H/2)/100;
#endif
if( ++hjCurvHeader[rCNL]==BOX34_W )
{ hjCurvHeader[rCNL]=0;}
// 报警喇叭控制
ST3000AlarmCtrl(Bjob);
// 界面刷新
switch( VarST3000.MenuIDSEL )
{
case 4: // 历史曲线
HideMouse();//2007-5-8 11:11:38
if( bFLAG&0x01 ) { SyncVEMark_M4(rCNL, 1);}
else { SyncVEMark_M4(rCNL, 0);}
if( unit[rCNL].submenu1.bitfield.hcontrol )
{
if( bFLAG&0x02 ) { SyncHEMark_M4(rCNL, 1);}
else { SyncHEMark_M4(rCNL, 0);}
}
DrawCurvLines_M4(rCNL);
ShowMouse();
break;
case 3: // 误差综合调节
if( unit[rCNL].submenu1.bitfield.hcontrol )
{ DispHErr_M3(rCNL, vRealErr[rCNL], hRealErr[rCNL]);}
else
{ DispVErr_M3(rCNL, vRealErr[rCNL]);}
break;
case 1: // 静止画面
if( !CtrlUnitFlags[rCNL].bits.bit1 )
{ // 误差显示
DispVErr_M1(rCNL, vRealErr[rCNL]);
if( unit[rCNL].submenu1.bitfield.hcontrol )
{ DispHErr_M1(rCNL, hRealErr[rCNL]);}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?