📄 c51jh.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 + -