?? main.c
字號:
{
// 檢查返回監(jiān)視應答的門口機的地址是不是剛才要發(fā)出監(jiān)視請求的門口機的地址
if ((pRxFrame->Frame.Addr[0] == TxFrame.Frame.Addr[0])
&& (pRxFrame->Frame.Addr[1] == TxFrame.Frame.Addr[1])
&& (pRxFrame->Frame.Addr[2] == TxFrame.Frame.Addr[2])
&& (pRxFrame->Frame.Addr[3] == TxFrame.Frame.Addr[3]))
{
RS485SendWaitTimer = 0x00; // 將計數(shù)器清零
if (GetRouteInfoByRouteAddr(&RouteInfo))
{
// 將狀態(tài)轉移到監(jiān)視狀態(tài)
SystemStatus.Status = Status_Viewing;
ViewTimeCounter = MAX_VIEW_TIMES;
InitDispBuffer(TRUE);
// 設置當前監(jiān)視的目的地址
//SetConnectingAddr();
ConnectingAddr[0] = pRxFrame->Frame.Addr[0];
ConnectingAddr[1] = pRxFrame->Frame.Addr[1];
ConnectingAddr[2] = pRxFrame->Frame.Addr[2];
ConnectingAddr[3] = pRxFrame->Frame.Addr[3];
// 將檢索到的單元地址填入LCD顯示緩沖
DispBuffer[1][7] = (RouteInfo.House >> 4) | 0x30;
DispBuffer[1][8] = (RouteInfo.House&0x0F) | 0x30;
DispBuffer[1][11] = (RouteInfo.Door >> 4) | 0x30;
DispBuffer[1][12] = (RouteInfo.Door&0x0F) | 0x30;
UpdateDisp(TRUE);
P_VIDEO = P_ON;//打開視頻
}
}
}
else //if (SystemStatus.Status == Status_Idle) // 如果管理機已經(jīng)取消了對門口機的監(jiān)視請求,則發(fā)送斷開連接的命令
{
RS485AckCancelCommand();
}
break;
}
case (Command_ViewRequest | Command_Busy): // 門口機返回忙信號
{
if (SystemStatus.Status == Status_ViewSendingRequest)
{
// 檢查返回監(jiān)視應答的門口機的地址是不是剛才要發(fā)出監(jiān)視請求的門口機地址
if ((pRxFrame->Frame.Addr[0] == TxFrame.Frame.Addr[0])
&& (pRxFrame->Frame.Addr[1] == TxFrame.Frame.Addr[1])
&& (pRxFrame->Frame.Addr[2] == TxFrame.Frame.Addr[2])
&& (pRxFrame->Frame.Addr[3] == TxFrame.Frame.Addr[3]))
{
RS485SendWaitTimer = 0x00; // 將計數(shù)器清零
// 顯示對方忙
memcpy(&DispBuffer[0][1], &DispBuffer[1][1], DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], "對方忙,請返回!", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
MessageShowTimer = 300; // 消息顯示時間為3s
SystemStatus.PreStatus = Status_Idle;
SystemStatus.Status = Status_ShowingMessage;
UpdateDisp(FALSE);
}
}
break;
}
case Command_Unlock: // 門口機應答管理機發(fā)出的開鎖命令
{
if (SystemStatus.Status == Status_UnlockSendingRequest)
{
if ((pRxFrame->Frame.Addr[1] == TxFrame.Frame.Addr[1])
&& (pRxFrame->Frame.Addr[2] == TxFrame.Frame.Addr[2]))
{
RS485SendWaitTimer = 0x00; // 將計數(shù)器清零
// 顯示對方忙
memcpy(&DispBuffer[0][1], &DispBuffer[1][1], DISP_BUF_LENGTH);
DispBuffer[0][0] = 0x01;
memcpy(&DispBuffer[1][1], "開鎖成功! ", DISP_BUF_LENGTH);
DispBuffer[1][0] = 0x01;
MessageShowTimer = 100; // 消息顯示時間為1s
// 設置當前連接的目的地址為無效地址
ClearConnectingAddr();
// 關閉音頻、視頻電源
// SW_B = P_OFF; // 高端
// SW_A = P_OFF; // 低端
// P_VIDEO = P_OFF; //關斷視頻
SystemStatus.PreStatus = Status_Idle;
SystemStatus.Status = Status_ShowingMessage;
UpdateDisp(FALSE);
}
}
break;
}
case Command_HandUp: // 門口機返回管理機的摘機命令
{
if ((pRxFrame->Frame.Addr[1] == ConnectingAddr[1])
&& (pRxFrame->Frame.Addr[2] == ConnectingAddr[2])
&& (pRxFrame->Frame.Addr[3] == ConnectingAddr[3]))
{
RS485SendWaitTimer = 0;
SystemStatus.Status = Status_Talking;
InitDispBuffer(TRUE);
DispBuffer[1][7] = (RouteInfo.House >> 4) | 0x30;
DispBuffer[1][8] = (RouteInfo.House&0xFF) | 0x30;
//
DispBuffer[1][11] = (RouteInfo.Door >> 4) | 0x30;
DispBuffer[1][12] = (RouteInfo.Door&0xFF) | 0x30;
UpdateDisp(TRUE);
}
break;
}
case Command_Disconnect: // 門口機應答斷開連接的命令
{
if ((pRxFrame->Frame.Addr[1] == ConnectingAddr[1])
&& (pRxFrame->Frame.Addr[2] == ConnectingAddr[2])
&& (pRxFrame->Frame.Addr[3] == ConnectingAddr[3]))
{
RS485SendWaitTimer = 0;
// 設置當前連接的目的地址為無效地址
ClearConnectingAddr();
// 關閉音頻、視頻電源
ClosePower();
SystemStatus.Status = Status_Idle;
InitDispBuffer(TRUE);
UpdateDisp(FALSE);
}
break;
}
default:
break;
}
}
else // 門口機發(fā)來的命令幀
{
switch (pRxFrame->Frame.aData[0])
{
// 判斷數(shù)據(jù)類型
case Command_CallRequest: // 門口機呼叫請求
{
TxFrame.Frame.Addr[0] = pRxFrame->Frame.Addr[0];
TxFrame.Frame.Addr[1] = pRxFrame->Frame.Addr[1];
TxFrame.Frame.Addr[2] = pRxFrame->Frame.Addr[2];
TxFrame.Frame.Addr[3] = pRxFrame->Frame.Addr[3];
TxFrame.Frame.nLength = 1;
TxFrame.Frame.aData[0] = Command_CallRequest | Command_Ack; // 返回的數(shù)據(jù)返回位置1
TxFrameLength = 6; // 發(fā)送數(shù)據(jù)幀的長度為6個字節(jié),不包括校驗和停止字節(jié)
if ((pRxFrame->Frame.Addr[0] == ConnectingAddr[0]) // 如果當前正在連接,再發(fā)來呼叫請求則認為是重復發(fā)送的請求,返回應答信號
&& (pRxFrame->Frame.Addr[1] == ConnectingAddr[1])
&& (pRxFrame->Frame.Addr[2] == ConnectingAddr[2])
&& (pRxFrame->Frame.Addr[3] == ConnectingAddr[3]))
{
}
else if ((SystemStatus.Status == Status_Talking) // 正在通話
|| (SystemStatus.Status == Status_Viewing) // 正在監(jiān)視
|| (SystemStatus.Status == Status_Calling) // 正在呼叫室內(nèi)分機
|| (SystemStatus.Status == Status_Alarming_F) // 分機報警
|| (SystemStatus.Status == Status_Alarming_M) // 門口機報警
|| (SystemStatus.Status == Status_bCallingIn_M) // 正在被門口機呼叫
|| (SystemStatus.Status == Status_bCallingIn_F)) // 正在被室內(nèi)機呼叫
{
// 如果管理機正忙,則返回忙信號
TxFrame.Frame.aData[0] |= Command_Busy;
}
else if (bHandleUp == TRUE) // 門口機呼叫的時候管理機的手柄拿起來了表示管理機正忙
{
// 如果管理機正忙,則返回忙信號
TxFrame.Frame.aData[0] |= Command_Busy;
}
else if (GetRouteInfoByRouteAddr(&RouteInfo))
{
// 設置當前正在連接的目標地址
ConnectingAddr[0] = pRxFrame->Frame.Addr[0];
ConnectingAddr[1] = pRxFrame->Frame.Addr[1];
ConnectingAddr[2] = pRxFrame->Frame.Addr[2];
ConnectingAddr[3] = pRxFrame->Frame.Addr[3];
RingTimeCounter = MAX_RING_TIMES;
KeyBuffer[0] = 0;
SystemStatus.Status = Status_bCallingIn_M;
InitDispBuffer(TRUE);
DispBuffer[1][7] = (RouteInfo.House >> 4) | 0x30;//如果門口機多與9個需要改編碼
DispBuffer[1][8] = (RouteInfo.House&0xFF) | 0x30;
if (DispBuffer[1][7] == 0x30)
{
DispBuffer[1][7] = ' '; // 最前面的'0'不顯示
}
DispBuffer[1][11] = (RouteInfo.Door >> 4) | 0x30;
DispBuffer[1][12] = (RouteInfo.Door&0xFF) | 0x30;
UpdateDisp(TRUE);
OpenRingPower(); // 打開音頻
P_VIDEO = P_ON; //打開視頻
}
// 返回應答信號
RS485SendTxFrame();
break;
}
case Command_Disconnect: // 門口機斷開連接請求
{
// CommandDisconnect();
if (SystemStatus.Status == Status_Alarming_F) // 報警狀態(tài),不理睬Disconnect請求
{
break;
}
// 如果是當前連接的門口機或該門口機所在的分機
if ((pRxFrame->Frame.Addr[0] == ConnectingAddr[0])
&& (pRxFrame->Frame.Addr[1] == ConnectingAddr[1])
&& (pRxFrame->Frame.Addr[2] == ConnectingAddr[2]))
{
// 返回應答
TxFrame.Frame.Addr[0] = pRxFrame->Frame.Addr[0];
TxFrame.Frame.Addr[1] = pRxFrame->Frame.Addr[1];
TxFrame.Frame.Addr[2] = pRxFrame->Frame.Addr[2];
TxFrame.Frame.Addr[3] = pRxFrame->Frame.Addr[3];
TxFrame.Frame.nLength = 1;
TxFrame.Frame.aData[0] = Command_Disconnect | Command_Ack;// 返回門口機的斷開連接的請求
TxFrameLength = 6;
RS485SendTxFrame(); // 返回應答
// 關閉音頻、視頻電源
ClosePower();
// 將連接地址置為無效的地址
ClearConnectingAddr();
// 系統(tǒng)狀態(tài)回到初始狀態(tài)
SystemStatus.PreStatus = Status_Idle;
SystemStatus.Status = Status_Idle;
InitDispBuffer(TRUE);
UpdateDisp(FALSE);
}
else if ((SystemStatus.Status == Status_Idle) // 如果當前管理機空閑
|| (SystemStatus.Status == Status_ShowingMessage)) // 或者管理機只是在顯示消息
{
// 返回一個應答
TxFrame.Frame.Addr[0] = pRxFrame->Frame.Addr[0];
TxFrame.Frame.Addr[1] = pRxFrame->Frame.Addr[1];
TxFrame.Frame.Addr[2] = pRxFrame->Frame.Addr[2];
TxFrame.Frame.Addr[3] = pRxFrame->Frame.Addr[3];
TxFrame.Frame.nLength = 1;
TxFrame.Frame.aData[0] = Command_Disconnect | Command_Ack;// 返回門口機的斷開連接的請求
TxFrameLength = 6;
RS485SendTxFrame(); // 返回應答
}
break;
}
case Command_CheckRFCard:
{
if (pRxFrame->Frame.nLength == 0x05) // Check卡號的時候幀數(shù)據(jù)長度為5個字節(jié)
{
TxFrame.Frame.Addr[0] = pRxFrame->Frame.Addr[0];
TxFrame.Frame.Addr[1] = pRxFrame->Frame.Addr[1];
TxFrame.Frame.Addr[2] = pRxFrame->Frame.Addr[2];
TxFrame.Frame.Addr[3] = pRxFrame->Frame.Addr[3];
TxFrame.Frame.nLength = 0x01;
TxFrame.Frame.aData[0] = pRxFrame->Frame.aData[0] | Command_Ack;
temp = FindRFCardByNum((BYTE *)(&(pRxFrame->Frame.aData[1])), RFCardTabStartAddr, RFCardTabLength);
if ((temp >= RFCardTabStartAddr) && (temp < (RFCardTabStartAddr+RFCardTabLength))) // 找到這張卡
{
I2CReadString(0x00, temp, I2CBuffer, sizeof(t_RFCardUser));
p_RFCardUser = (t_RFCardUser *)(I2CBuffer);
// 判斷當前時間和卡的期限,看是否超過卡的使用期限
bTemp = FALSE; // bTemp在這兒表示卡的使用期限是否過期
if (p_RFCardUser->EndTime.Year == Time.Year) // 判斷卡是否過期
{
if (p_RFCardUser->EndTime.Month == Time.Month)
{
if (p_RFCardUser->EndTime.Date == Time.Date)
{
if (p_RFCardUser->EndTime.Date == Time.Date)
{
if (p_RFCardUser->EndTime.Hour == Time.Hour)
{
if (p_RFCardUser->EndTime.Minute < Time.Minute)
{
bTemp = TRUE;
}
}
else if (p_RFCardUser->EndTime.Hour < Time.Hour)
{
bTemp = TRUE;
}
}
else if (p_RFCardUser->EndTime.Date < Time.Date)
{
bTemp = TRUE;
}
}
else if (p_RFCardUser->EndTime.Month < Time.Month)
{
bTemp = TRUE;
}
}
else if (p_RFCardUser->EndTime.Month < Time.Month)
{
bTemp = TRUE;
}
}
else if (p_RFCardUser->EndTime.Year < Time.Year)
{
bTemp = TRUE;
}
if (bTemp == TRUE) // 如果找到這張卡號,但是已經(jīng)過期了,則刪除這張卡
{
I2CWriteString(0x00, temp, NullString, sizeof(t_RFCardUser));
TxFrame.Frame.aData[0] |= Command_Busy;
}
else // 如果卡沒有過期,則判斷該卡是否可以打開當前的單元門口的電控鎖
{
// 判斷發(fā)送請求的單元地址與該卡所允許的單元地址是否相同
if ((p_RFCardUser->CardAddr[0] == 0x00) && (p_RFCardUser->CardAddr[1] == 0x00)) // 如果所適用的地址為00表示可以打開任何單元門口
{
}
else // 如果該卡只適用于某個特定的單元
{
GetRouteInfoByRouteAddr(&RouteInfo);
if ((p_RFCardUser->CardAddr[0] == RouteInfo.House)
&& (p_RFCardUser->CardAddr[1] == RouteInfo.Door))
{
}
else // 地址不符,拒絕開鎖
{
TxFrame.Frame.aData[0] |= Command_Busy;
}
}
}
}
else
{
TxFrame.Frame.aData[0] |= Command_Busy;
}
TxFrameLength = 0x06;
RS485SendTxFrame();
}
break;
}
case Command_Heartbeat: // 門口機發(fā)來的心跳信號,表示該門口機目前正常
{
/*
TxFrame.Frame.Addr[0] = pRxFrame->Frame.Addr[0];
TxFrame.Frame.Addr[1] = pRxFrame->Frame.Addr[1];
TxFrame.Frame.Addr[2] = pRxFrame->Frame.Addr[2];
TxFrame.Frame.Addr[3] = pRxFrame->Frame.Addr[3];
TxFrame.Frame.nLength = 1;
TxFrame.Frame.aData[0] = Command_Heartbeat | Command_Ack; // 返回的數(shù)據(jù)返回位置1
TxFrameLength = 6; // 發(fā)送數(shù)據(jù)幀的長度為6個字節(jié),不包括校驗和停止字節(jié)
RS485SendWaitTimer = 0; // 不等待返回信號
// 返回應答信號
RS485SendTxFrame();
*/
/*
// 重置相應的門口機的心跳變量
if (GetRouteInfoByRouteAddr(&RouteInfo))
{
bTemp = FALSE;
// 找到該單元在CheckDoorIntervalArray[]中對應的位置,然后重置這個單元的心跳變量
k = 0;
for (temp=0; temp<RouteInfoLength; )
{
if ((RouteInfoLength-temp) > sizeof(I2CBuffer))
{
i = sizeof(I2CBuffer);
}
else
{
i = RouteInfoLength-temp;
}
I2CReadString(0x00, RouteInfoStartAddr+temp, I2CBuffer, i);
for (j=0; j<i; )
{
p_temp = (t_RouteInfo *)(&I2CBuffer[j]);
if ((p_temp->RouteAddr == RouteInfo.RouteAddr)
&& (p_temp->DoorAddr == RouteInfo.DoorAddr))
{
bTemp = TRUE;
break;
}
k ++; // k每加1,表示該單元對應單元心跳表的位置往后移1
j += sizeof(t_RouteInfo);
temp += sizeof(t_RouteInfo);
}
if (bTemp == TRUE)
{
break;
}
}
if (bTemp == TRUE) // 如果找到了這個單元對應的單元心跳表的位置
{
if (CheckDoorIntervalArray[k] == 0) // 如果之前該門口機不存在,則將其更新為存在
{
// 將I2C存儲器中該單元的路由信息更新為該門口機存在
I2CWriteString(0x00, RouteInfoStartAddr+temp+7, '\x01', 1);
}
CheckDoorIntervalArray[k] = CheckDoorIntervalTimer;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -