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

📄 c51jh.c

📁 /*此程序完成4路用户话机的摘挂机检测、号码接收、显示及各种信号音的输出。*/
💻 C
字号:
  /* 现代交换综合实验c51程序v.08*/
/*此程序完成4路用户话机的摘挂机检测、号码接收、显示及各种信号音的输出。*/
#include <Absacc.h>
#include <reg51.h>  
#define uchar unsigned char
#define NUMLONG 0x07  /*定义号码长度为7*/
/*
uchar xdata NUM2、1 _at_ 0xdfff;
uchar xdata NUM4、3 _at_ 0xbfff;
uchar xdata TONE _at_ 0xefff;
uchar xdata DTMF2、1 _at_ 0x7F01(8155PA);
uchar xdata DTMF4、3 _at_ 0x7F02(8155PB);
uchar xdata cid(4) _at_ 0x7F03(8155PC);
sub1~4 _at_ 89c51-P1.0~P1.3);*/

uchar code TAB[]={0x05,0x03,0x09,0x13,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
		0x05,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
		0x05,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
		0x05,0x03,0x09,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
        	0x05,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
		0x05,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
		0x05,0x03,0x09,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
		0x05,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,
		0x05,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03,0x01,0x03};
uchar bdata busytab=0x00,toneword=0x00,cid=0x00;
uchar bdata num1=0x0f,num2=0xf0,num3=0x0f,num4=0xf0,num=0x0f;
uchar bdata buf;
uchar data m;
/* busytab :用户忙闲表,低4位存储,每路占一位,第0位对应第一路用户。1-用户忙,0-用户闲;
toneword :信号音控制字,低4位存储,每路占一位,第0位对应第一路用户。1-送信号音,0-停送信号音;
cid:低4位存储4路用户的CID值,每路占一位,第0位对应第一路用户;
num1~num4:4个数码管数据显示存储单元
buf:缓冲单元
m:0x01*/
   
struct subscrib {
	uchar  status;
	uchar  timer;
	uchar  dailed;
	uchar  dail[NUMLONG];
	}subs[4]={
		{0x00,0x00,0x00,{0x0f}},
		{0x00,0x00,0x00,{0x0f}},
		{0x00,0x00,0x00,{0x0f}},
		{0x00,0x00,0x00,{0x0f}}};
/* status:摘挂机状态存储单元。0—空闲;1—刚刚摘机,未拨号,送拨号音;2—收号。拨首位号后,停送拨号音;3—摘机,在规定的时间内(4s),不拨号,送催挂音;4—号码收全,不再收号,送回铃音;5—刚刚挂机。
timer:时间计数器,一次记录时间为16ms。用于记录摘机后不拨号的持续时间。规定超过4s(255x16=4s)时送催挂音,此处用忙音替代催挂音。
dailed:收号位数计数器, <NUMLONG。
dail[NUMLONG]:号码存储单元组。*/

struct subscrib *p;
void run16ms();
void run96ms() ;
void run350ms();
void run1s();
void display();
void main()
{
TMOD=0x01;
TL0=0xc0;
TH0=0xe0;
TR0=1;
ET0=1;
EA=1;
SP=0x60;
XBYTE[0xdfff]=0xff;
XBYTE[0xbfff]=0xff;
P1=0x0f;

while(1);		
}
	
/*---------------------------------------------------------------------------*/

void run16ms() /*状态1:收号并显示;2:收号停送拨号音并显示;5:挂机,复位;无新号码时计时;设置状态2、3、4。信号音部分放到了其他函数中了*/
{
uchar i;
cid=(cid<<4)|(XBYTE[0x7F03]&0x0f);
for(p=subs,buf=cid,i=1;p<subs+4;p++,buf>>=1,i++)
	{
	switch(buf&0x11)
		{
		case 0x00: 
			{
			switch(p->status)
				{
				case 1: 
				case 2: {
					if(++(p->timer)==250)
						{
						p->status=3;
						}
					}break;
                                case 5: p->status=0;
                                        switch(i)
						{
						case 1: num1=0x0f; break;
						case 2: num2=0xf0; break;
						case 3: num3=0x0f; break;
						case 4: num4=0xf0; break;
						} 
				}
			}break; 
		case 0x01:
			{
			switch(p->status)
				{
				case 1: p->status=2;
				case 2: p->timer=0;
					switch(i)
						{
						case 1: p->dail[p->dailed++]=XBYTE[0x7F01]&0x0f; num1=XBYTE[0x7F01]&0x0f; break;
						case 2: p->dail[p->dailed++]=(XBYTE[0x7F01]>>4)&0x0f; num2=XBYTE[0x7F01]&0xf0; break;
						case 3: p->dail[p->dailed++]=XBYTE[0x7F02]&0x0f; num3=XBYTE[0x7F02]&0x0f; break;
						case 4: p->dail[p->dailed++]=(XBYTE[0x7F02]>>4)&0x0f; num4=XBYTE[0x7F02]&0xf0; break;
						}
				}
			}break;  /*cid上跳沿收号*/
		case 0x10:
			{
			if(p->dailed==NUMLONG)p->status=4;
			p->timer=0;
			}break;
		default: ;
		}
	}
 display();
}

void run96ms()      /*4路用户的摘挂机检测。读P1口,修改busytab、status单元(设置0,1,5状态)。*/
{
busytab=(busytab<<4)|(~P1&0x0f);	/*1摘机,0挂机*/
P1=~(P1<<4)|0x0f;
for(p=subs,buf=busytab;p<subs+4;p++,buf>>=1)
	{
	switch(buf&0x11)
		{
		case 0x00: p->status=0x00; break;	/* 00 */ 
		case 0x01: p->status=0x01; break;	/* 01,摘机,送拨号音*/
		case 0x10: p->status=0x05;
				p->dailed=0;
				p->timer=0;
				break;			/* 10 ,挂机 ,复位*/
		default:   ;				/* 11,  保持原状态 */
		}
	}
}

void run350ms()  /*状态1:送拨号音  2:停送拨号音  3:送催挂音(此处用忙音替代):350MS送,350MS断*/              
	{	
		m=0x01;
		buf=toneword;		/* 入口参数 */
		for(p=&subs[0];p<=subs+3;p++)
		 {	switch(p->status)
			 {  case 0x01:  buf=buf|m; break;	/* 状态01:送拨号音(置1)*/ 
			    case 0x02:  buf=buf&~m; break;	/* 状态02:已拨号,停拨号音(清0)*/
			    case 0x03:  buf=(buf&~m)|(~buf&m); break; 										/* 状态03:久不拨号,送催挂音 (取反)*/
			    default:    break;		/* 其它:保持原状态 */
		  	 }
			m=m<<1;
		 }  
		toneword=buf;
		XBYTE[0xefff]=toneword;
	}  
 
uchar j=0;  
void run1s() /*状态4送回铃音,1S送,4S断*/
	{   
		m=0x01;
		buf=toneword;		/* 入口参数 */
		for(p=&subs[0];p<=subs+3;p++)
		 { 	if(p->status==4)	/* 状态04: 拨号位数已够,送回铃音*/	  
			 { if (j==0) buf=buf|m;   /*(置1)*/
			   else     buf=buf&~m;	  /* (清0)*/
			 }  
			m=m<<1;
		 }  
		toneword=buf;
		XBYTE[0xefff]=toneword;
		j++;
		if (j==5)	{j=0;}
	}			

int1() interrupt 1
{
static uchar TAB_i=0;
TL0=0xc0;
TH0=0xe0;	

if (TAB[TAB_i]&0x02)
	run16ms(); 
if (TAB[TAB_i]&0x04)
	run96ms(); 
if (TAB[TAB_i]&0x08)
	run350ms();
if (TAB[TAB_i]&0x10)
	run1s(); 
TAB_i++;	
if (TAB_i==108)	
TAB_i=0x00;
}
void display() /*显示用户号码*/
{
XBYTE[0xdfff]=num2|num1;
XBYTE[0xbfff]=num4|num3;
}


⌨️ 快捷键说明

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