⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 程序概述: 这是个具体产品程序
💻 C
📖 第 1 页 / 共 4 页
字号:
				{
					// 检查返回监视应答的门口机的地址是不是刚才要发出监视请求的门口机的地址
					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;      // 将计数器清零
						if (GetRouteInfoByRouteAddr(&RouteInfo))
						{
							// 将状态转移到监视状态
							SystemStatus.Status = Status_Viewing;
							ViewTimeCounter = MAX_VIEW_TIMES;
							InitDispBuffer(TRUE);
							// 设置当前监视的目的地址
							//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)            // 如果管理机已经取消了对门口机的监视请求,则发送断开连接的命令
				{
					RS485AckCancelCommand();
				}
				break;
			}
			case (Command_ViewRequest | Command_Busy):   // 门口机返回忙信号
			{
				if (SystemStatus.Status == Status_ViewSendingRequest)
				{
					// 检查返回监视应答的门口机的地址是不是刚才要发出监视请求的门口机地址
					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;      // 将计数器清零
						// 显示对方忙
						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:                       // 门口机应答管理机发出的开锁命令
			{
				if (SystemStatus.Status == Status_UnlockSendingRequest)
				{
					if ((pRxFrame->Frame.Addr[1] == TxFrame.Frame.Addr[1])
					 && (pRxFrame->Frame.Addr[2] == TxFrame.Frame.Addr[2]))
					{
						RS485SendWaitTimer = 0x00;  // 将计数器清零
						// 显示对方忙
						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                            // 门口机发来的命令帧
		{
			switch (pRxFrame->Frame.aData[0])
			{
			// 判断数据类型
			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; // 返回的数据返回位置1
				TxFrameLength = 6;										// 发送数据帧的长度为6个字节,不包括校验和停止字节
				if ((pRxFrame->Frame.Addr[0] == ConnectingAddr[0])		// 如果当前正在连接,再发来呼叫请求则认为是重复发送的请求,返回应答信号
				 && (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)		// 正在监视
					  || (SystemStatus.Status == Status_Calling)		// 正在呼叫室内分机
					  || (SystemStatus.Status == Status_Alarming_F)		// 分机报警
					  || (SystemStatus.Status == Status_Alarming_M)		// 门口机报警
					  || (SystemStatus.Status == Status_bCallingIn_M)	// 正在被门口机呼叫
					  || (SystemStatus.Status == Status_bCallingIn_F))	// 正在被室内机呼叫
				{
					// 如果管理机正忙,则返回忙信号
					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)	// 报警状态,不理睬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();
					// 系统状态回到初始状态
					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卡号的时候帧数据长度为5个字节
				{
					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)      // 如果找到这张卡号,但是已经过期了,则删除这张卡
						{
							I2CWriteString(0x00, temp, NullString, sizeof(t_RFCardUser));
							TxFrame.Frame.aData[0] |= Command_Busy;
						}
						else                    // 如果卡没有过期,则判断该卡是否可以打开当前的单元门口的电控锁
						{
							// 判断发送请求的单元地址与该卡所允许的单元地址是否相同
							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:     // 门口机发来的心跳信号,表示该门口机目前正常
			{
/*
				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;   // 返回的数据返回位置1
				TxFrameLength = 6;                                      // 发送数据帧的长度为6个字节,不包括校验和停止字节
				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 + -