📄 turncontrol.c
字号:
//根据 ucTurnType 切换的方式 判断是否暂停返回
if ( (ucTurnType != 2) & (ucTurnType != 3))
{
//暂停切换 或 正常切换
//保存上时段的运行数据
//1. 保存上时段的时间量
uc5_SystemTurnTimeSaved[0] = uc5_TurnTime[0];
uc5_SystemTurnTimeSaved[1] = uc5_TurnTime[1];
uc5_SystemTurnTimeSaved[2] = uc5_TurnTime[2];
uc5_SystemTurnTimeSaved[3] = uc5_TurnTime[3];
uc5_SystemTurnTimeSaved[4] = uc5_TurnTime[4];
//2. 保存上时段的控制量。
uc2_SystemTurnConSaved[0] = uc2_SystemTurnCon[0];
uc2_SystemTurnConSaved[1] = uc2_SystemTurnCon[1];
//3. 保存上时段的时段量。
ucSystemTurnNumSaved = ucSystemTurnNum;
}
//掉电复位,控制量已经读入了,不能清除!
if(ucTurnType != 3)
{
//公共关闭流程
uc2_SystemTurnCon[0] = 0;
uc2_SystemTurnCon[1] = 0;
fnCONoutput();
}
//上一个时段的自有关闭流程
//!!注意:如果是暂停切换,ucTurnType=1;则不调用上时段的End函数。
if(ucTurnType != 1)
{
pfnFunc = TurnList[ucSystemTurnNum].pfnEnd_TurnN;
if(pfnFunc != NULL)
(*pfnFunc)(); //执行操作
}
//d) 时段工作状态LED1-5,清除不显示。
for(i=1;i++;i<6)
fnSet_DisplayLED(i,0,1); //设置第i位LED不显示不闪烁 1-5
//---------时段切换---------//
//根据 ucTurnType 切换的方式 判断是否暂停返回
if(ucTurnType == 2)
{
//暂停返回
ucSystemTurnNum = ucSystemTurnNumSaved;
}
else
{
//正常切换/暂停切换
ucSystemTurnNum = ucTurnNum;
}
//---------下时段开始流程---------//
//公共开始流程
//i. 系统设置刷新
//1. 读入系统设置BUF函数:
fnRead_SystemSetToBuf();
//2. 外部4路输入检测量设置BUF数据刷新。
fnReadBuf_SystemInputFlagPermitData();
//根据 ucTurnType 切换的方式 判断是否暂停返回
if(ucTurnType == 2)
{
//暂停返回
//读入暂存的时间量
uc5_TurnTime[0] = uc5_SystemTurnTimeSaved[0];
uc5_TurnTime[1] = uc5_SystemTurnTimeSaved[1];
uc5_TurnTime[2] = uc5_SystemTurnTimeSaved[2];
uc5_TurnTime[3] = uc5_SystemTurnTimeSaved[3];
uc5_TurnTime[4] = uc5_SystemTurnTimeSaved[4];
//读入暂存的控制量
uc2_SystemTurnCon[0] = uc2_SystemTurnConSaved[0];
uc2_SystemTurnCon[1] = uc2_SystemTurnConSaved[1];
//计时顺序
bTurnTimeSortState = TurnList[ucSystemTurnNum].ucTurnTimeSortState &0x01;
//下一个时段的自有初始化流程
//注意:如果是暂停返回,ucTurnType=2;则不调用下时段的Init函数。
//pfnFunc = TurnList[ucSystemTurnNum].pfnInit_TurnN;
//if(pfnFunc != NULL)
// (*pfnFunc)(); //执行操作
//时段运行开始
bSystemTurnRunEnable = 1;
//ii. 根据时段工作状态ucTurnState,LED1-5显示。
if(TurnList[ucSystemTurnNum].ucTurnState<5)
fnSet_DisplayLED(TurnList[ucSystemTurnNum].ucTurnState+1,1,1); //设置第i位LED显示不闪烁 1-5
}
else
if(ucTurnType == 3)
{
//调电复位
//跳过时间载入
//跳过控制量载入
//计时顺序设置
bTurnTimeSortState = TurnList[ucSystemTurnNum].ucTurnTimeSortState &0x01;
//下一个时段的自有初始化流程
pfnFunc = TurnList[ucSystemTurnNum].pfnInit_TurnN;
if(pfnFunc != NULL)
(*pfnFunc)(); //执行操作
//ii. 根据时段工作状态ucTurnState,LED1-5显示。
if(TurnList[ucSystemTurnNum].ucTurnState<5)
fnSet_DisplayLED(TurnList[ucSystemTurnNum].ucTurnState+1,1,1); //设置第i位LED显示不闪烁 1-5
//时段运行开始
bSystemTurnRunEnable = 1;
}
else
if( (ucTurnType == 1) | (ucTurnType == 0))
{
//正常切换/暂停切换
//读入指定地址,大小的时段时间量:
//CAT24WC64P (N<=8192)(地址:0-8191)
//CAT24WC16P (N<=2048)(地址:0-2047)
fnRead_Eeprom(TurnList[ucSystemTurnNum].uiTurnTimeAddress,
4,uc4_SystemTurnTime);
//检查数据,如果有问题,则全部设为0,并储存。报警,Beep
if ( (uc4_SystemTurnTime[0] > 9) | //百小时>9
(uc4_SystemTurnTime[1] > 99) | //小时>99
(uc4_SystemTurnTime[2] > 59) | //分钟>59
(uc4_SystemTurnTime[3] > 59) ) //秒>59
{
//全部设为0
uc4_SystemTurnTime[0] = 0;
uc4_SystemTurnTime[1] = 0;
uc4_SystemTurnTime[2] = 0;
uc4_SystemTurnTime[3] = 0;
//并储存
//写入相应地址的数据--4字节的时间量
//写入指定地址,4字节大小的数据:
//CAT24WC64P (N<=8192)(地址:0-8191)
//CAT24WC16P (N<=2048)(地址:0-2047)
fnWrite_Eeprom(TurnList[ucSystemTurnNum].uiTurnTimeAddress,
4,uc4_SystemTurnTime);
//报警,Beep!
}
//如果为正计时,则初始时间预设为0
if( TurnList[ucSystemTurnNum].ucTurnTimeSortState )
{
//全部设为0
uc4_SystemTurnTime[0] = 0;
uc4_SystemTurnTime[1] = 0;
uc4_SystemTurnTime[2] = 0;
uc4_SystemTurnTime[3] = 0;
}
//判断是否当前时间段时间为0且为倒计时
if( (uc4_SystemTurnTime[0] == 0) & (uc4_SystemTurnTime[1] == 0) &
(uc4_SystemTurnTime[2] == 0) & (uc4_SystemTurnTime[3] == 0) &
TurnList[ucSystemTurnNum].ucTurnTimeSortState == 0)
{
//控制量无效,为0。!!继承位也同时设为无效!!
uc2_SystemTurnCon[0] = 0;
uc2_SystemTurnCon[1] = 0;
//发现时段为空,确定跳过标记。
ucTurnSkip = 1;
}
else
{
//读入指定地址,大小的时段控制量:
//CAT24WC64P (N<=8192)(地址:0-8191)
//CAT24WC16P (N<=2048)(地址:0-2047)
fnRead_Eeprom(TurnList[ucSystemTurnNum].uiTurnCONAddress,
2,uc2_SystemTurnCon);
//当继承位有效,且为暂停切换
if(fnBitTest(uc2_SystemTurnCon[1],7))
{
//读入暂存的控制量
uc2_SystemTurnCon[0] = uc2_SystemTurnConSaved[0];
uc2_SystemTurnCon[1] = uc2_SystemTurnConSaved[1];
}
}
//计时顺序设置
if(TurnList[ucSystemTurnNum].ucTurnTimeSortState == 0)
fnSet_TurnTime(uc4_SystemTurnTime,0); //设置时段定时器时间,倒计时
else
fnSet_TurnTime(uc4_SystemTurnTime,1); //设置时段定时器时间,正计时
//下一个时段的自有初始化流程
pfnFunc = TurnList[ucSystemTurnNum].pfnInit_TurnN;
if(pfnFunc != NULL)
(*pfnFunc)(); //执行操作
//ii. 根据时段工作状态ucTurnState,LED1-5显示。暂停-闪烁
if(TurnList[ucSystemTurnNum].ucTurnState<5)
if(ucTurnType == 0)
fnSet_DisplayLED(TurnList[ucSystemTurnNum].ucTurnState+1,1,1); //设置第i位LED显示不闪烁 1-5
else
fnSet_DisplayLED(TurnList[ucSystemTurnNumSaved].ucTurnState+1,1,0); //设置第i位LED显示闪烁 1-5
//时段运行开始
bSystemTurnRunEnable = 1;
}
fnCONoutput(); //输出时段控制量(格式转换)
fnStart_TurnTime(); //开始时段定时器
//根据调电记忆标志 PP1-4 4 是否采用掉电记忆功能 0-关闭 1-打开
if ( ucBuf_AdvanceSet[PPAD_PP1_4] )
{
//刷新系统记忆RAM数据
fnWrite_SystemZRAM();
}
//网络部分
if( bCANState )
{
//根据节点地址,分别处理主节点(0)、普通节点的时段信息发送。
if( ucCANAddress_Local == 0)
{
//主节点
//向主节点发送节点的时段切换信息。(空时段则跳过!)
if( ucTurnSkip == 0 )
{
//向消息队列加入主节点消息
//?需要屏蔽中断吗?
//函数使用了信号量,保证不同时操作FIFO
EX0=0; //外部中断0使能禁止
MsgListAdd(0x00,ucSystemTurnNum,ucSystemTurnNumSaved);
EX0=1; //外部中断0使能
}
}
else
{
//普通节点
//向主节点发送节点的时段切换信息。(空时段则跳过!)
if( ucTurnSkip == 0 )
{
//CAN
while(CAN_SendToMaster_Turn(ucSystemTurnNum,uc4_SystemTurnTime,uc2_SystemTurnCon,ucSystemTurnNumSaved)!=0)
{
if(ucSystemCANErrorState)
{
//错误报警!
fnAlarm(1);
fnBeep(1);
//防止节点在网络出错的时候死机!
//网络关闭!
bCANState = 0;
//清除错误标志
ucSystemCANErrorState = 0;
//退出循环,防止死机!
break;
}
}
//CAN_SendToMaster_Turn(ucSystemTurnNum,uc4_SystemTurnTime,uc2_SystemTurnCon,ucSystemTurnNumSaved);
}
}
}
}
/*******************************************************************
系统主循环网络处理函数
函数原型: void RUN_network()
功能: 系统主循环网络处理函数
涉及变量:
********************************************************************/
void RUN_network()
{
idata MsgStruct Msg;
uchar tempi;
//主节点消息处理
if( bCANState )
if( ucCANAddress_Local == 0)
{
//主节点
if(MsgListGet(&Msg)==0)
{
//有消息需要处理
//CAN_Master_ListTest0(253);
//while(CAN_Master_ListTest(129,Msg.ucNodeAdd,Msg.ucTurnN,Msg.ucTurnOld) != 0)
// ;
//CAN_Master_ListTest(129,Msg.ucNodeAdd,Msg.ucTurnN,Msg.ucTurnOld);
//节点状态是否改变
if(TurnList[Msg.ucTurnN].ucTurnState != TurnList[Msg.ucTurnOld].ucTurnState)
{
//节点状态改变了
//删除节点的旧状态
tempi = ListGetTheNode(TurnList[Msg.ucTurnOld].ucTurnState,Msg.ucNodeAdd);
//当状态删除出错的时候,在其它状态列表中删除,
//这样可以避免其它的子节点异常复位的结果!
if(tempi == 0xFF)
{
//循环遍历所有状态表,删除可能的所有
//State_X0 - 1.工作列表
if(TurnList[Msg.ucTurnOld].ucTurnState != State_X0)
ListGetTheNode(State_X0,Msg.ucNodeAdd);
//State_X1 - 2.等待列表
if(TurnList[Msg.ucTurnOld].ucTurnState != State_X1)
ListGetTheNode(State_X1,Msg.ucNodeAdd);
//State_X2/State_X4 - 3.还原列表
if(TurnList[Msg.ucTurnOld].ucTurnState != State_X2)
if(TurnList[Msg.ucTurnOld].ucTurnState != State_X4)
ListGetTheNode(State_X2,Msg.ucNodeAdd);
//State_X3 - 4.备用列表
if(TurnList[Msg.ucTurnOld].ucTurnState != State_X3)
ListGetTheNode(State_X3,Msg.ucNodeAdd);
//State_XX - 5.准备列表
if(TurnList[Msg.ucTurnOld].ucTurnState != State_XX)
ListGetTheNode(State_XX,Msg.ucNodeAdd);
}
//加入节点的新状态
ListAddNode(TurnList[Msg.ucTurnN].ucTurnState,Msg.ucNodeAdd);
//测试地址254!!(!!!无错误检测!!!)
CAN_Master_ListTest(254,Msg.ucNodeAdd,TurnList[Msg.ucTurnN].ucTurnState,TurnList[Msg.ucTurnOld].ucTurnState);
//还原数小于MAX ucBuf_AdvanceSet[PPAD_PP1_7]
if(List_Return.ucListN < ucBuf_AdvanceSet[PPAD_PP1_7])
{
//发送还原许可
tempi = ListGetFirstNode(State_X1);
if(tempi !=0xFF)
{
if(tempi == 0x00)
{
//重要,防止因为上一数据未发送完,发送失败!
while(CAN_SendToSlave_Allow01(tempi)!=0)
{
if(ucSystemCANErrorState)
{
//错误报警!
fnAlarm(1);
fnBeep(1);
//退出循环,防止死机!
//清除错误标志
//ucSystemCANErrorState = 0;
break;
}
}
ucTurnAllow01 = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -