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

📄 teloperate.c.bak

📁 一个完整的用用AVR单片机开发的电话交换机程序 希望对想学习AVR开发人有帮助
💻 BAK
字号:
/***************************************************************************
//Actpro International (SZ) Ltd
//Project :
//File		:TelOperate.c												Compiler:Keil
//Editor: LIUYI
//Data:		25-12-28										 				Ver:
//General Function
	1、void	ExtTelRing(UCHAR RingTel);					//分机振铃
	2、void	ExtTelStopRing(UCHAR StopRingTel); 	//停止分机振铃
*/
#include <switch.h>

void	TelOperateInit();
void	TelOperateLoop();
void 	ExtTelCheck();
char	ExtTelRing(UCHAR RingTel);
void	RingTimeTick();
char	ExtTelStopRing(UCHAR StopRingTel);
//void  ResourceWatch();
void 	OutsideTelRingCheck();
void	TakeOutsideLine(UCHAR OutsideLineNum);
void	HoldOutsideLine(UCHAR OutsideLineNum);
void ReleaseOutsideTelRingCheckRes(UCHAR linenum);


bit		State_Flag;
bit		Store_Flag;

idata	int		ExtTelHoldState;
idata	int		ExtTelHoldStateStore;

idata	UCHAR	OutsideTelRingState;
idata UCHAR	OutsideTelRingStateStore;
idata UCHAR	OutsideTelRingNum[OUTSIDETELNUM][3];//记忆存储外部振铃次数
														//2: step(2)	num(1)
idata	UCHAR	OutsideTelLineState;
														
idata	int		ExtTelRingState;
idata	UCHAR	RingGroup[MaxNumAtRing][6];//振铃控制资源,MaxNumAtRing为可同时振铃数
				 		//6:state(1) telphonenummber(1) ringtime(2) quiettime(2)
																
void	TelOperateInit()
{
	idata	UCHAR i,j;
	
	State_Flag=1;
	Store_Flag=1;
	ExtTelHoldState			=0xff;
	ExtTelHoldStateStore=0xff;
	
	ExtTelRingState=0x0;
	for(i=0;i<MaxNumAtRing;i++)
		{
			for(j=0;j<6;j++)
				{RingGroup[i][j]=0;}
		}

	OutsideTelRingState=0xff;
	OutsideTelRingStateStore=0xff;
	for(i=0;i<OUTSIDETELNUM;i++)
		{
			for(j=0;j<3;j++)
				{OutsideTelRingNum[i][j]=0;}			
		}
	OutsideTelLineState=0;	
	ReleaseOutsideTelRingCheckRes(0);
	ReleaseOutsideTelRingCheckRes(2);
}

void	TelOperateLoop()
{
	 ExtTelCheck();								//分机摘机检测
	 RingTimeTick();							//振铃控制过程
	 OutsideTelRingCheck();				//外线振铃检测
	 DTMFSend();	 
}

void ExtTelCheck()
{
	idata	UCHAR i;
	
	EnDetectHold=0;							//扩展选择
	PORT=0xff;
	ExtTelHoldState=PORT;
	EnDetectHold=1;
	
	if(ExtTelHoldStateStore!=ExtTelHoldState)
		{
			rs232write(0x4);
			for(i=0;i<3;i++)//延时去抖动
				{
					EnDetectHold=0;							//扩展选择
					PORT=0xff;
					ExtTelHoldState=PORT;
					EnDetectHold=1;
					
					if(ExtTelHoldStateStore==ExtTelHoldState){return;} 
				}	 
			rs232write(0x5);					
			for(i=0;i<ExtTelNum;i++)
			 	{
					State_Flag=(bit)((ExtTelHoldState>>i)&0x01);
					Store_Flag=(bit)((ExtTelHoldStateStore>>i)&0x01);
					
					if(State_Flag)
						{
							if(Store_Flag)
								{//正常状态
									//rs232write(0x );
								}
							else
								{//挂机动作****************
									rs232write(0x6);
									SendHoldMessage(i);									
										//发送挂机消息
									//rs232write(0xAA);rs232write(0x02);rs232write(i+1);rs232write(0xBB);
								}	
						}
					else
						{
							if(Store_Flag)
								{//摘机动作****************
									rs232write(0x7);
									SendUnholdMessage(i);//发送摘机消息								
									//rs232write(0xAA);rs232write(0x01);rs232write(i+1);rs232write(0xBB);
								}
							else
								{//摘机状态
									//rs232write(0x );
								}								
						}		
				}
			ExtTelHoldStateStore=ExtTelHoldState;	//更新寄存值
		}			
}

char	ExtTelRing(UCHAR RingTel)
{
	idata  UCHAR i;
	idata	WORD	temp;
	if(RingTel>=ExtTelNum)
		{
			return 0xff;		//超出分机范围出错
		}
											//检查该分机是否已经处于振铃状态
											
	for(i=0;i<MaxNumAtRing;i++)
		{
			if(RingGroup[i][0]==0)				//查询资源
				{//首次配置资源
					
					RingGroup[i][0]=0x01;				//可以振铃
					RingGroup[i][1]=RingTel;	//设置振铃分机号
					temp=RINGTIMELENGTH;
					RingGroup[i][2]=temp>>8;	
					RingGroup[i][3]=temp;			//设置振铃时间
					temp=RINGQUIETTIMELENGTH;
					RingGroup[i][4]=temp>>8;	
					RingGroup[i][5]=temp;			//设置振铃间隔时间					
									
					return	1;		//设置振铃成功
				}
		}	
	return 0x2;				//振铃忙,请等待	
}

char	ExtTelStopRing(UCHAR StopRingTel)
{
	idata	UCHAR i,j;
	
	if(StopRingTel>ExtTelNum)
		{	
			return 0xfe;		//超出分机范围出错
		}	
	for(i=0;i<MaxNumAtRing;i++)
		{
			if(RingGroup[i][1]==StopRingTel)//查找分机
				{
					
					j=0x01;
					j=(j<<(StopRingTel));	
					j=j^0xff;										//停止分机振铃	
					ExtTelRingState=ExtTelRingState&j;									
					
					RingGroup[i][0]=0;				//停止振铃
					RingGroup[i][1]=0;				//释放资源
					RingGroup[i][2]=0;
					RingGroup[i][3]=0;
					RingGroup[i][4]=0;
					RingGroup[i][5]=0;							
					return	1;		//设置停止振铃成功
				}
		}	
	return 0x2;				//分机已经停止振铃			
}

void	RingTimeTick()
{
	data	UCHAR i,j;
	idata	WORD temp;

	for(i=0;i<MaxNumAtRing;i++)
		{//循环配置
			if(RingGroup[i][0]==0)
				{//没有振铃任务
					continue;				
				}
			else if(RingGroup[i][0]>RingTime)
				{//振铃超时结束

					j=0x01;
					j=(j<<(RingGroup[i][1]));	
					j=j^0xff;										//停止分机振铃	
					ExtTelRingState=ExtTelRingState&j;	
				
					LED=1;								
					RingGroup[i][0]=0;				//释放资源
					RingGroup[i][1]=0;
					RingGroup[i][2]=0;
					RingGroup[i][3]=0;
					RingGroup[i][4]=0;
					RingGroup[i][5]=0;
				}	
			else
				{//振铃过程中配置
					temp=RingGroup[i][2];
					temp=(temp<<8)+RingGroup[i][3];
					
					if(temp==0)
						{												
							temp=RingGroup[i][4];
							temp=(temp<<8)+RingGroup[i][5];
							
							if(temp==0)
								{//完成一次响铃过程
									RingGroup[i][0]++;				//响铃次数加一
									
									temp=RINGTIMELENGTH;
									RingGroup[i][2]=temp>>8;	
									RingGroup[i][3]=temp;			//设置振铃时间	
									temp=RINGQUIETTIMELENGTH;
									RingGroup[i][4]=temp>>8;	
									RingGroup[i][5]=temp;			//设置振铃间隔时间																			
								}
							else
								{//间隔过程中
									temp--;
									LED=1;
									RingGroup[i][4]=temp>>8;	
									RingGroup[i][5]=temp;		 //间隔时间递减	
									
									j=0x01;
									j=(j<<(RingGroup[i][1]));	
									j=j^0xff;										//将对应的位清零,产生间隔		
									ExtTelRingState=ExtTelRingState&j;																							
								}
						}
					else
						{//响铃过程中
							temp=temp-1;
							RingGroup[i][2]=temp>>8;	
							RingGroup[i][3]=temp;			//振铃时间递减
																																							
							LED=0;
							
							j=0x01;
							j=(j<<(RingGroup[i][1]));	//将对应的位置一,产生振铃
							ExtTelRingState=ExtTelRingState|j;							
						}	
				}				
		}	
		PORT=ExtTelRingState;
		EnRingPort=0;
		EnRingPort=1;
		EnRingPort=0;							//动作实现			
}			   

/*
void ResourceWatch()
{
	idata UCHAR i,j;
	
	rs232write(0x11);
	
	for(i=0;i<MaxNumAtRing;i++)
		{
			for(j=0;j<6;j++)
				{
					rs232write(RingGroup[i][j]);
				}
			rs232write(0xAA);	
		}
	rs232write(0x22);	
}
*/
void OutsideTelRingCheck()
{
	idata UCHAR i,j;
	idata	temp;

	for(i=0;i<OUTSIDETELNUM;i++)
		{//振铃检测(时间检测)
			temp=OutsideTelRingNum[i][0];
			temp=(temp<<8)+OutsideTelRingNum[i][1];
			if(temp!=0)
				{
					if(temp<1000)
						{
							if(temp==50)	//去抖动 150
								{
									OutsideTelRingNum[i][2]++;
									
									//发送外线呼入消息
									SendOutsideCallInMessage(i,OutsideTelRingNum[i][2]);
								}
							temp++;	
							OutsideTelRingNum[i][0]=temp>>8;
							OutsideTelRingNum[i][1]=temp;	
						}
					else
						{
							OutsideTelRingNum[i][0]=0;
							OutsideTelRingNum[i][1]=0;
							OutsideTelRingNum[i][2]=0;							
						}	
				}
		}				
					
	EnDetectRing=0;
	PORT=0xff;
	OutsideTelRingState=PORT;
	EnDetectRing=1;
	
	for(i=0;i<OUTSIDETELNUM;i++)
		{//检测外部是否有振铃信号
			State_Flag=(bit)((OutsideTelRingState>>i)&0x01);
			Store_Flag=(bit)((OutsideTelRingStateStore>>i)&0x01);			
			
			if(State_Flag!=Store_Flag){break;}
		}
	if(State_Flag==Store_Flag){return;}	//无振铃信号 则返回	

	for(i=0;i<2;i++)//去抖动
		{
				EnDetectRing=0;
				PORT=0xff;
				OutsideTelRingState=PORT;
				EnDetectRing=1;		
					
				for(j=0;j<OUTSIDETELNUM;j++)	
					{//检测外部是否有振铃信号
						State_Flag=(bit)((OutsideTelRingState>>j)&0x01);
						Store_Flag=(bit)((OutsideTelRingStateStore>>j)&0x01);			
						if(State_Flag!=Store_Flag){break;}
					}	
				if(State_Flag==Store_Flag){return;}			
																					//如果为干扰则返回	
		}
			
	EnDetectRing=0;
	PORT=0xff;
	OutsideTelRingState=PORT;
	EnDetectRing=1;		
	
	for(i=0;i<OUTSIDETELNUM;i++)	//振铃记数
		{
			State_Flag=(bit)((OutsideTelRingState>>i)&0x01);
			Store_Flag=(bit)((OutsideTelRingStateStore>>i)&0x01);			
			
			if(State_Flag)
				{
					if(Store_Flag)
						{//高电平
							;
						}
					else
						{//上升沿
							OutsideTelRingNum[i][0]=0;
							OutsideTelRingNum[i][1]=0;
						}	
				}
			else
				{
					if(Store_Flag)
						{//振铃信号下降沿
							OutsideTelRingNum[i][0]=0; //初始化记时
							OutsideTelRingNum[i][1]=1;
						}
					else
						{//底电平						
	
						}					
				}	
		}
	OutsideTelRingStateStore=OutsideTelRingState;	
}

void ReleaseOutsideTelRingCheckRes(UCHAR linenum)
{
	OutsideTelRingNum[linenum][0]=0;
	OutsideTelRingNum[linenum][1]=0;
	OutsideTelRingNum[linenum][2]=0;	
}

void	TakeOutsideLine(UCHAR OutsideLineNum)
{
	idata UCHAR i,j;
	for(i=0;i<OUTSIDETELNUM;i++)
		{
			if(i==OutsideLineNum)
				{					
					j=0x01;
					j=(j<<i);	//将对应的位置一,摘机
					OutsideTelLineState=OutsideTelLineState|j;							
					break;				
				}
		}
	if(i>=OUTSIDETELNUM)	
		{
			return;
		}
	else
		{
			//rs232write(OutsideTelLineState);
			PORT=OutsideTelLineState;
			EnTakeLine=0;
			EnTakeLine=1;
			EnTakeLine=0;		
			PORT=0xff;									
			return;		
		}		
}

void	HoldOutsideLine(UCHAR OutsideLineNum)
{
	idata UCHAR i,j;
	for(i=0;i<OUTSIDETELNUM;i++)
		{
			if(i==OutsideLineNum)
				{
					j=0x01;
					j=(j<<i);
					j=(j^0xff);	//将对应的位置零,挂机
					OutsideTelLineState=OutsideTelLineState&j;		
					break;				
				}
		}
	if(i>=OUTSIDETELNUM)	
		{
			return;
		}
	else
		{
			//rs232write(OutsideTelLineState);
			PORT=OutsideTelLineState;
			EnTakeLine=0;
			EnTakeLine=1;
			EnTakeLine=0;			
				
			PORT=0xff;
			return;				
		}		
}

⌨️ 快捷键说明

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