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

📄 main.c

📁 程序概述: 这是个具体产品程序
💻 C
📖 第 1 页 / 共 4 页
字号:
					}
				}
*/
				break;
			}
			default:
				break;
			}
		}
	}
/* ---------------------- 数据是从室内分机发来的 ---------------------------- */
	else								// 数据是从室内分机发来的
	{
		if (pRxFrame->Frame.aData[0] & Command_Ack)		// 应答帧
		{
			pRxFrame->Frame.aData[0] &= ~Command_Ack;
			// 判断帧数据类型
			switch (pRxFrame->Frame.aData[0])
			{
			case Command_CallRequest:					// 室内分机返回呼叫请求应答帧
			{
				if (SystemStatus.Status == Status_CallSendingRequest)   // 呼叫请求的命令已经发出,
				{
					// 检查返回呼叫应答的室内分机的地址是不是刚才要发出呼叫请求的室内分机的地址
					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))
						{
							// 将状态转移到呼叫状态
							RingTimeCounter = MAX_RING_TIMES;
							SystemStatus.Status = Status_Calling;
							// 设置当前呼叫的目的地址
							// 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显示缓冲
							InitDispBuffer(TRUE);
							DispBuffer[1][7]  = (RouteInfo.House >> 4) | 0x30;
							DispBuffer[1][8]  = (RouteInfo.House&0x0F) | 0x30;
							DispBuffer[1][11] = (RouteInfo.Floor / 10) | 0x30;//	>> 4
							DispBuffer[1][12] = (RouteInfo.Floor % 10) | 0x30;//	    &0x0F
							DispBuffer[1][13] = (RouteInfo.User / 10) | 0x30;
							DispBuffer[1][14] = (RouteInfo.User % 10) | 0x30;
							UpdateDisp(TRUE);
							// 通过分机地址解析出该分机的楼层号和房间号
							OpenRingPower();// 打开铃声音频电路
						}
					}
				}
				else
				{
					RS485AckCancelCommand();
				}
				break;
			}
			case (Command_CallRequest | Command_Busy):   //室内分机返回忙信号
			{
				if (SystemStatus.Status == Status_CallSendingRequest)
				{
					// 检查返回呼叫应答的室内分机的地址是不是刚才要发出呼叫请求的室内机地址
					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;     // 消息显示时间为3ms
						SystemStatus.PreStatus = Status_Idle;
						SystemStatus.Status = Status_ShowingMessage;
						UpdateDisp(FALSE);
					}
				}
				break;
			}
			case Command_HandUp:        // 分机应答管理机的摘机信号
			{
				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])
				 && (GetRouteInfoByRouteAddr(&RouteInfo)))
				{
					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.Floor / 10) | 0x30;  // 楼层号
					DispBuffer[1][12] = (RouteInfo.Floor % 10)| 0x30;//	  
					DispBuffer[1][13] = (RouteInfo.User / 10) | 0x30;
					DispBuffer[1][14] = (RouteInfo.User % 10) | 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);
				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))
				{
					// 设置正在通话的分机地址
					// 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];

					RingTimeCounter = MAX_RING_TIMES;
					KeyBuffer[0] = 0;
					SystemStatus.Status = Status_bCallingIn_F;
					InitDispBuffer(TRUE);
					DispBuffer[1][7] = (RouteInfo.House >> 4) | 0x30;
					DispBuffer[1][8] = (RouteInfo.House&0xFF) | 0x30;
					if (DispBuffer[1][7] == 0x30)
					{
						DispBuffer[1][7] = ' ';     // 最前面的'0'不显示
					}
					DispBuffer[1][11] = (RouteInfo.Floor / 10) | 0x30;
					DispBuffer[1][12] = (RouteInfo.Floor % 10) | 0x30;
					DispBuffer[1][13] = (RouteInfo.User / 10) | 0x30;
					DispBuffer[1][14] = (RouteInfo.User % 10) | 0x30;
					UpdateDisp(TRUE);

					OpenRingPower();    // 打开振铃音频电路
				}
				// 返回应答信号
				RS485SendTxFrame();
				break;
			}
			case Command_HandUp:                // 分机发送摘机命令
			{
				// 返回呼叫应答信号
				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);
				TxFrameLength = 6;      // 发送数据帧的长度为6个字节,不包括校验和停止字节
				if (SystemStatus.Status == Status_Calling)    // 如果管理机正在呼叫分机
				{
					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])
					 && (GetRouteInfoByRouteAddr(&RouteInfo)))
					{
						// 分机摘机之后,关闭振铃信号,切换到通话的通道
						ChangeToTalkChannel();
						SystemStatus.Status = Status_Talking;
						InitDispBuffer(TRUE);
						DispBuffer[1][7] = (RouteInfo.House >> 4) | 0x30;// 楼栋号
						DispBuffer[1][8] = (RouteInfo.House&0xFF) | 0x30;
						DispBuffer[1][11] = (RouteInfo.Floor / 10 ) | 0x30;// 楼层号>> 4
						DispBuffer[1][12] = (RouteInfo.Floor % 10) | 0x30;//	  &0xFF
						DispBuffer[1][13] = (RouteInfo.User / 10) | 0x30;
						DispBuffer[1][14] = (RouteInfo.User % 10) | 0x30;
						UpdateDisp(FALSE);
					}
				}
				else
				{
					TxFrame.Frame.aData[0] = Command_Disconnect;
				}
				RS485SendTxFrame();                 // 发送应答帧
				break;
			}
			case Command_Disconnect:                // 分机断开连接请求
			{
				// CommandDisconnect();
				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]))
				{
					// 返回应答
					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);
				}
				break;
			}
			case Command_Alarm:                     // 分机报警
			{
				if (GetRouteInfoByRouteAddr(&RouteInfo))
				{
					if ((SystemStatus.Status == Status_Viewing) // 如果系统正忙,则先关闭当前连接并切换到报警状态
					 || (SystemStatus.Status == Status_Calling)
					 || (SystemStatus.Status == Status_Talking)
					 || (SystemStatus.Status == Status_CallSendingRequest)
					 || (SystemStatus.Status == Status_ViewSendingRequest)
					 || (SystemStatus.Status == Status_bCallingIn_M)
					 || (SystemStatus.Status == Status_bCallingIn_F))
					{
						RS485SendCancelCommand();	// 先取消当前连接
						// 将连接地址置为无效的地址
						ClearConnectingAddr();
						// 关闭音频、视频电源
						ClosePower();
						SystemStatus.Status = Status_Idle;
						KeyBuffer[0] = 0;
					}
					// 返回报警应答信号
					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] = (Command_Alarm | Command_Ack);
					TxFrameLength = 6;
					RS485SendTxFrame();

					if ((SystemStatus.Status != Status_Alarming_F)
					 && (SystemStatus.Status != Status_Alarming_M))
					{
						SystemStatus.PreStatus = SystemStatus.Status;
					}
					SystemStatus.Status = Status_Alarming_F;
					InitDispBuffer(TRUE);
					AlarmRecord.Addr[0] = 0x00;
					AlarmRecord.Addr[1] = RouteInfo.House;
					DispBuffer[1][5] = (RouteInfo.House >> 4) | 0x30;
					if (DispBuffer[1][5] == 0x30)
					{
						DispBuffer[1][5] = ' ';     // 最前面的'0'不显示
					}
					DispBuffer[1][6] = (RouteInfo.House&0x0F) | 0x30;
					// 由分机地址得到分机的房间号码
					i = RouteInfo.Floor;            // 楼层号
					j = RouteInfo.User;             // 分机号
					AlarmRecord.Addr[2] = i;
					DispBuffer[1][9] =  (i / 10) | 0x30;//(i >> 4) | 0x30;
					DispBuffer[1][10] = (i % 10) | 0x30;//(i&0x0F) | 0x30;
					AlarmRecord.Addr[3] = j;
					DispBuffer[1][11] = (j / 10) | 0x30;
					DispBuffer[1][12] = (j % 10) | 0x30;
					UpdateDisp(FALSE);

					AlarmTimeCounter = MAX_ALARM_TIMES; // 设定最长报警时间
					OpenAlarmPower();                   // 打开报警音频电路

					// 保存报警记录
					memcpy((BYTE *)(&(AlarmRecord.Time)), (BYTE *)(&Time), sizeof(t_Time));// 保存时间
					SaveAlarmRecord(&AlarmRecord);      // 将报警记录AlarmRecord结构体写入到I2C存储器中
				}
				break;
			}
			case Command_CancelAlarm:       // 取消报警
			{
				KeyBuffer[0] = 0x00;
				CancelKeyPress();
				break;
			}
			default:
				break;
			}
		}
	}
	if (pRxFrame != NULL)
	{
		MsgPutBuf((BYTE *)pRxFrame);
	}
}

//
// 从RS232模拟串口接收到单个数据字节
/*void RS232RxHandler(PMSG msg)
{
	BYTE RxData = msg->Param;
} */

//
// 等待与门口主机通信的线路空闲下来
// 通过设置Timer 0定时器等待一个特定的时间, 在这段时间当中如果没有检测到线路上有数据则认为线路空闲
void WaitForLineIdle(void)
{
	LineIdle = FALSE;

	// Init timer0 counter
	TH0 = LineIdleWaitTime >> 8;
	TL0 = LineIdleWaitTime & 0xFF;

	TR0 = ENABLE;                       // timer0 run
	EX0 = ENABLE;                       // 开INT0中断,检测Rx线上是否有数据(低电平)

	while ( !LineIdle ) ;               // wait for Timer2 interrupt

	EX0 = DISABLE;                      // 关INT0中断
	TR0 = DISABLE;                      // timer0 stop
}

/*---------------------------------------------------------------------------*/

// 将正在连接的目的地址清空为无效地址
void ClearConnectingAddr(void)
{
	ConnectingAddr[0] = 0xFF;
	ConnectingAddr[1] = 0xFF;
	ConnectingAddr[2] = 0xFF;
	ConnectingAddr[3] = 0xFF;
}

/*----------------------------------------------------------------------------+
| End of source file                                                          |
+----------------------------------------------------------------------------*/
/*------------------------ Nothing Below This Line --------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -