📄 366c.c
字号:
//----------------------------------------晶振480K 波特率7500--------------------------------------------//
//---- ----------------简化版,不在24C02存储数据,仅仅简单收发;重庆高新区特别版,等待386回应时间延长--------//
//-----------------------------------------2006年3月6日 董凯宁------------------------------------------//
#include "string.h"
#include <reg52.h>
#include <intrins.h>
#include <math.h>
//---------------------------------------定义部分----------------------------------------------
//P1
sbit MT8880_D0= P1^4; //OUT/IN 双向数据总线 5脚
sbit MT8880_D1= P1^5; //OUT/IN 双向数据总线 6脚
sbit MT8880_D2= P1^6; //OUT/IN 双向数据总线 7脚
sbit MT8880_D3= P1^7; //OUT/IN 双向数据总线 8脚
//P3
sbit MT8880_RW= P3^2; //OUT 读写选择控制 12脚
sbit MT8880_CP2= P3^3; //OUT 8880的系统时钟 13脚
sbit MT8880_CS= P3^4; //OUT 14脚
sbit MT8880_RS0= P3^5; //OUT 变低时,进入现场监听状态 15脚
//P2
sbit ToneTest= P2^2; //IN 峰值为3.5V的铃流脉冲信号检测 23脚
sbit J_LineToPhone= P2^3; //OUT 报警时,驱动继电器切断本地电话和外线的联系,同时模拟摘机 24脚
int JISHU;
unsigned char i;
typedef unsigned char Number[10]; //定义一个10字节长的数组类型,用来放6组电话,一组密码,次数振铃,报警延迟时间
//--------------------------------------函数部分-----------------------------------------------
void DELAY_50ms()
{
EA=0;
TMOD=0; //13位不重装定时器方式
TL0=48;
TH0=24;
TCON=0;
TR0=1; //定时器0启动,定时器1不启动
wait: if(TF0==0)
{
_nop_();
goto wait;
}
TCON=0;//停动定时器0
}
void MT8880_StatusRegister_READ()
{
MT8880_CP2=0;
MT8880_RW=1; //读状态寄存器
MT8880_RS0=1;
MT8880_CS=0;
MT8880_D0=1;
MT8880_D1=1;
MT8880_D2=1;
MT8880_D3=1;
MT8880_CP2=1;
}
void MT8880_DataRegister_READ()
{
MT8880_CP2=0;
MT8880_RW=1; //读接收数据寄存器
MT8880_RS0=0;
MT8880_CS=0; //给时钟信号
MT8880_D0=1;
MT8880_D1=1;
MT8880_D2=1;
MT8880_D3=1;
MT8880_CP2=1; //读状态寄存器值到D0-D3口
}
void MT8880_ControlRegister_Initialize()
{
MT8880_CP2=0;
MT8880_RS0=1; //du 1
MT8880_RW=1;
MT8880_CS=0;
MT8880_D0=1;
MT8880_D1=1;
MT8880_D2=1;
MT8880_D3=1;
MT8880_CP2=1;
MT8880_CP2=0;
MT8880_CS=1;
MT8880_RS0=1; //xie 1
MT8880_RW=0;
MT8880_CS=0;
MT8880_D0=0;
MT8880_D1=0;
MT8880_D2=0;
MT8880_D3=0;
MT8880_CP2=1;
MT8880_CP2=0;
MT8880_CS=1;
MT8880_RS0=1; //xie2
MT8880_RW=0;
MT8880_CS=0;
MT8880_D0=0;
MT8880_D1=0;
MT8880_D2=0;
MT8880_D3=0;
MT8880_CP2=1;
MT8880_CP2=0;
MT8880_CS=1;
MT8880_RS0=1; //xie3
MT8880_RW=0;
MT8880_CS=0;
MT8880_D0=0;
MT8880_D1=0;
MT8880_D2=0;
MT8880_D3=1;
MT8880_CP2=1;
MT8880_CP2=0;
MT8880_CS=1;
MT8880_RS0=1; //xie4
MT8880_RW=0;
MT8880_CS=0;
MT8880_D0=0;
MT8880_D1=0;
MT8880_D2=0;
MT8880_D3=0;
MT8880_CP2=1;
MT8880_CP2=0;
MT8880_CS=1;
MT8880_RS0=1; //du 2
MT8880_RW=1;
MT8880_CS=0;
MT8880_D0=1;
MT8880_D1=1;
MT8880_D2=1;
MT8880_D3=1;
MT8880_CP2=1;
MT8880_CP2=0;
MT8880_CS=1;
MT8880_D0=1; //总线复位
MT8880_D1=1;
MT8880_D2=1;
MT8880_D3=1;
}
void MT8880_ControlRegister_Write()
{
MT8880_CS=1;
MT8880_RW=0; //写控制寄存器
MT8880_RS0=1;
MT8880_D0=1; //使能tone输出
MT8880_D1=0; //选用双音多频方式,不用CP方式
MT8880_D2=0; //此脚在实际电路中未接,不管
MT8880_D3=1; //本次操作CRA,下一个写操作选择CRB
MT8880_CS=0;
MT8880_CP2=1;//给时钟信号,写D0-D3口值到控制寄存器
MT8880_CP2=0;
MT8880_CS=1;
MT8880_RW=0; //写控制寄存器
MT8880_RS0=1;
MT8880_D0=0;
MT8880_D1=0;
MT8880_D2=0;
MT8880_D3=0;
MT8880_CS=0;
MT8880_CP2=1; //给时钟信号,写D0-D3口值到控制寄存器
MT8880_CP2=0;
MT8880_CS=1;
MT8880_D0=1; //总线复位
MT8880_D1=1;
MT8880_D2=1;
MT8880_D3=1;
}
void MT8880_WriteOne(unsigned char SendData) //使用入口参数,即要发送的数
{
MT8880_CS=1;
MT8880_CP2=0;
MT8880_RW=0; //写传输数据寄存器
MT8880_RS0=0;
switch(SendData)
{
case 10: MT8880_D0=0; MT8880_D1=1; MT8880_D2=0; MT8880_D3=1;break;
case 1: MT8880_D0=1; MT8880_D1=0; MT8880_D2=0; MT8880_D3=0;break;
case 2: MT8880_D0=0; MT8880_D1=1; MT8880_D2=0; MT8880_D3=0;break;
case 3: MT8880_D0=1; MT8880_D1=1; MT8880_D2=0; MT8880_D3=0;break;
case 4: MT8880_D0=0; MT8880_D1=0; MT8880_D2=1; MT8880_D3=0;break;
case 5: MT8880_D0=1; MT8880_D1=0; MT8880_D2=1; MT8880_D3=0;break;
case 6: MT8880_D0=0; MT8880_D1=1; MT8880_D2=1; MT8880_D3=0;break;
case 7: MT8880_D0=1; MT8880_D1=1; MT8880_D2=1; MT8880_D3=0;break;
case 8: MT8880_D0=0; MT8880_D1=0; MT8880_D2=0; MT8880_D3=1;break;
case 9: MT8880_D0=1; MT8880_D1=0; MT8880_D2=0; MT8880_D3=1;break;
case 11: MT8880_D0=1; MT8880_D1=1; MT8880_D2=0; MT8880_D3=1;break; // *
case 12: MT8880_D0=0; MT8880_D1=0; MT8880_D2=1; MT8880_D3=1;break; // #
}
MT8880_CS=0; //给时钟信号,写D0-D3口值到控制寄存器
MT8880_CP2=1;
MT8880_CP2=0;
MT8880_CS=1;
MT8880_D0=1; //写操作完后一定要总线复位
MT8880_D1=1;
MT8880_D2=1;
MT8880_D3=1;
}
//------------------------------处理在一次下位机发送报警信息来过程中的读取 ,存储----------------------------------//
void READ_MESSAGE()
{
unsigned char Number_Note=1; //记录是第几个“下位机输入信号”
unsigned char Number_Key; //存储“电话机输入键值”的中间变量
Number NUMBER; //生成记录一次摘机过程的数组
JISHU=25000; //配合晶振,等待4秒
ReadStatus: MT8880_StatusRegister_READ();
if(MT8880_D2==1) //是否有键值生成
{
MT8880_CP2=0; //停动8880总线
MT8880_CS=1; //停动8880总线
MT8880_DataRegister_READ(); //读入的一个值出现在MT8880_D0-D3
if(MT8880_D3==0 & MT8880_D2==0 & MT8880_D1==0 & MT8880_D0==1) //输入“1”
{Number_Key=1; }
if(MT8880_D3==0 & MT8880_D2==0 & MT8880_D1==1 & MT8880_D0==0) //输入“2”
{Number_Key=2; }
if(MT8880_D3==0 & MT8880_D2==0 & MT8880_D1==1 & MT8880_D0==1) //输入“3”
{Number_Key=3; }
if(MT8880_D3==0 & MT8880_D2==1 & MT8880_D1==0 & MT8880_D0==0) //输入“4”
{Number_Key=4; }
if(MT8880_D3==0 & MT8880_D2==1 & MT8880_D1==0 & MT8880_D0==1) //输入“5”
{Number_Key=5; }
if(MT8880_D3==0 & MT8880_D2==1 & MT8880_D1==1 & MT8880_D0==0) //输入“6”
{Number_Key=6; }
if(MT8880_D3==0 & MT8880_D2==1 & MT8880_D1==1 & MT8880_D0==1) //输入“7”
{Number_Key=7;}
if(MT8880_D3==1 & MT8880_D2==0 & MT8880_D1==0 & MT8880_D0==0) //输入“8”
{Number_Key=8;}
if(MT8880_D3==1 & MT8880_D2==0 & MT8880_D1==0 & MT8880_D0==1) //输入“9”
{Number_Key=9; }
if(MT8880_D3==1 & MT8880_D2==0 & MT8880_D1==1 & MT8880_D0==0) //输入“0”
{Number_Key=0; }
if(MT8880_D3==1 & MT8880_D2==0 & MT8880_D1==1 & MT8880_D0==1) //输入“*”
{Number_Key=11;}
if(MT8880_D3==1 & MT8880_D2==1 & MT8880_D1==0 & MT8880_D0==0) //输入“#”
{Number_Key=12;}
MT8880_CP2=0; //停动8880总线
MT8880_CS=1; //停动8880总线
if(Number_Note>=7) // 已经处理了6次数据
{
J_LineToPhone=1; //模拟挂机
goto SERIAL; //通过串口发送给上位机
}
else
{
if(Number_Key==11)//收到自己发送的握手信号'*'
{JISHU=25000;goto ReadStatus;} //丢弃误读的366自己发的握手信号'*',并跳回继续监听
NUMBER[Number_Note-1]=Number_Key; //把键值写入数组
Number_Note=Number_Note+1;
JISHU=3800;
goto ReadStatus;
}
}
else //没有生成键值时
{
MT8880_CP2=0; //停动8880总线
MT8880_CS=1; //停动8880总线
JISHU=JISHU-1;
if(JISHU!=0)
{
goto ReadStatus;
}
else
{
J_LineToPhone=1; //模拟挂机
return;
}
}//读键值过程结束
SERIAL:
TCLK=0; //T2CON中的位 表示发送器波特率由定时器1决定
RCLK=0; //T2CON中的位 表示接收器波特率由定时器1决定
//SCON=80; //串行控制 0101,0000,SM0,SM1,SM2,REN,TB8,RB8,TI,RI 工作于串行方式1(8位异步)
SCON=0x88; //1000,1000,串口方式2,禁止接收,9位固定频率,TB8=1,即第9位为1,f/64
//TMOD=32; //定时器1工作于方式2,自动重装
PCON=0; //使SMOD=0
IE=0; //禁止中断
SBUF=170; //发送握手信息 1010,1010
JISHU=4000;
check_serial_send:
if(TI!=1)
{
JISHU=JISHU-1;
if(JISHU!=0)
{
_nop_();_nop_();
goto check_serial_send;
}
else
{
_nop_(); _nop_();
return;
}
}
TI=0; //清发送完成兼中断标志
REN=1; //启动一次接收过程
JISHU=4000;
check_serial_receive:
if(RI!=1) //如果SBUF中没有接收到数据,等待
{
JISHU=JISHU-1;
if(JISHU!=0)
{
_nop_();_nop_();
goto check_serial_receive;
}
else
{
_nop_(); _nop_();
return;
}
}
RI=0;
REN=0;
// if(SBUF!=0xaa)
// goto begin_serial;
for(i=0;i<6;i++) //发送6字节信息
{
SBUF=NUMBER[i];
JISHU=4000;
check_serial_sendmessage:
if(TI!=1)
{
JISHU=JISHU-1;
if(JISHU!=0)
{
_nop_();_nop_();
goto check_serial_sendmessage;
}
else
{
_nop_(); _nop_();
return;
}
}
TI=0; //清发送完成兼中断标志
}
//发送数据到上位机结束
}
//-------------处理在一次下位机发送报警信息来过程中的读取 ,存储void READ_MESSAGE()子程序结束----------------//
//--------------------------------------主程序开始--------------------------------------//
void main(void)
{
P2=0xff;
P0=0xff;
P1=0xff;
P3=0xff;
MT8880_ControlRegister_Initialize();
DELAY_50ms();DELAY_50ms();DELAY_50ms();
while(1)
{
if(ToneTest==0) //检测到铃流脉冲低周期,23脚
{ _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_(); //每行0.2ms
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_();
if(ToneTest==0)
{
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_(); //每行0.2ms
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_(); //每行0.2ms
if(ToneTest==0)
{
J_LineToPhone=0; //模拟摘机 ,24脚
DELAY_50ms();DELAY_50ms();DELAY_50ms();DELAY_50ms();DELAY_50ms();DELAY_50ms(); //摘机之后等待电路稳定
MT8880_ControlRegister_Write(); //令8880处于输出,BURST,双音状态
MT8880_WriteOne(11); //发送握手信号'*'
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
MT8880_WriteOne(11); //再次发送握手信号'*'
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();
READ_MESSAGE();
}
}
} // if(ToneTest==0) 结束
}//while(1)的反括号
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -