1、一、 总体设计分析1二、模块单元设计22.1 模拟摘机电路22.2 振铃检测电路22.3 控制部分电路3三、结束语5一、 总体设计分析电话远程遥控电器系统由单片机构成主控部分,进行主要的信息处理,接收外部操作指令形成各种控制信号,并完成对于各种信息的记录;接口电路提供单片机与电话外线的接口。其中包括铃流检测、摘挂机控制、忙音检测及双音频DTMF识别。本装置并联于电话机的两端,不会影响到电话机的正常使用。用户通过异地的电话机拨通本装置所连接外线的电话号码,通过市局交换机向电话机发出振铃信号,振铃检测电路将检测到的振铃信号送至系统的中央控制单元,如果本装置检测到振铃来的时间超过15s后无人接,自动
2、摘机,进入密码检测,输入正确后选择被控制电器,然后输入开或关进行遥控电器,完成后返回。 根据电话机和交换机发出的不同信号音以及电话线各种状态的不同要求,结合实际情况对具体的单元功能模块作出软件或硬件上的不同分工,具体如下:1、理论上交换机所发出的各种信号音都可以通过软件编程而识别,即通过单片机发出的脉冲信号来检测信号音单位时间内的脉冲个数计算出其频率,从而完成信号音识别。但是从系统的可靠性和程序的结构设计上分析,选择了硬件来解决振铃音检测、忙音检测、双音频信号解码等功能模块。2、 自动摘挂机和电器的控制必须使用具体硬件电路来实现。3、振铃音计数、忙音计数、密码校验、在线修改密码、输入信息分析等
3、功能模块使用软件编程方式要比硬件电路简单的多,实现也很容易。综上所述,本设计的信号音检测、自动摘挂机、控制电器、双音频解码等功能模块使用硬件电路实现。而信号音计数、密码校验、在线修改密码、信息分析等功能模块使用软件编程完成。二、模块单元设计2.1 模拟摘机电路因为程控电话交换机对电话摘机的响应是电话线回路电流突然变大为约30mA的电流,交换机检测到回路电流变大就认为电话机已经摘机。当用户摘机时,电话机通过叉簧接上约250的负载,使整个电话线回路流过约30mA的电流。交换机检测到该电流后便停止铃流发送,并将线路电压变为十几伏的直流,完成接续。如图所示,当单片机检测到电话有八次振铃后给P0.7口一
4、个低电平,三极管9012和9013均导通发光二极管发亮,250电阻接入,线路上电流约为30mA,模拟摘机成功。2.2 振铃检测电路当没有振铃信号时,线路上的供电电压为48V(老式交换机为60V),经过整流桥整流后不足以使稳压管V5导通,振铃信号输出端电压接近0V,当振铃信号到来时,线路上的90V交流信号经过整流桥变换成为峰值90V的脉动直流电,其峰值足以击穿稳压管V5,经R1对C1充电,振铃输出端电压升高,单片机可以通过P3.0口根据振铃信号的高低检测有无振铃。电路中的稳压管V6限制振铃信号的幅度不超过CPU端口的允许电压,保护CPU。2.3 控制部分电路当单片机89S52没接收信号,ULN输
5、出低电平,电磁继电器常闭开关闭合,常开开关断开,系统没有接入220V交流电压,家电无法正常工作。当80C52的P2接口输出低电平,经过ULN2003芯片由其输出端输出高电压,电磁继电器的常闭开关断开,常开开关闭合,将220V的交流家庭用电接入系统,接入插头的家用电器开始正常工作。从而达到控制家电的目的。 2.4 双音解码电路此部分是整个系统的关键,它的工作情况直接决定了系统的可靠性。经过翻阅大量的文献资料,发现使用电话专用的双音频编解码芯片进行输入双音频信号的解码,是比较常用的一种方法。使用集成电路不但外围电路简单,而且可靠性强。经过专用集成电路的解码,信号转换成为不同的码制信号,可以直接被单
6、片机读取。一般常用的电话双音频编解码集成电路有MT8870、MT8880、MT8888等,经过反复论证比较,决定采用双音频解码集成片MT8870来完成此功能模块。有关MT8870的详细介绍请参阅本报告的后面附录C部分。远程用户通过电话按键发送的DTMF信号,经耦合电容的隔直、滤波后,由MT8870接收并进行硬件译码,输出的四位二进制数据直接与AT89C51单片机的P1.0P1.3口连接, MT8870接收到有效的DTMF信号并解出正确的BCD数据时,会使CID端置高电平,通知CPU取走数据。CPU从P1口读入数据,去掉高四位后将数据保存于内部R7寄存器单元,并对读入的数值进行判断,从而得到远程
7、控制者的输入命令。 解码电路MT8870解码表三、结束语在这次的电子设计竞赛中,虽然我们这个小组没有完成整个设计,但是我们都有努力过,并且学到了很多东西,对protel、keil等软件更加熟悉,为今后设计作品打下了坚实的基础。没完成作品很遗憾,但是我们不会放弃,为了学到更多的东西,我们会坚持把这个系统做完的。NNYYNN延时开电器1YNYY开电器1N延时开电器1延时开电器2开电器2YY开电器1延时开电器1开电器2关电器2输入要设的密码Y延时关电器2N延时开电器2N控制电器2YNN开电器1修改密码NN延时关电器1YY挂机输入密码输错2次密码输入错误计数关电器1延时开电器1开电器1设置成功控制电器
8、NY控制电器1Y密码正确摘机Y15秒时间到延时有振铃吗初始化N程序流程图:附: 程序/*用户头文件*/#include #include #include #include/*宏定义*/#define uchar unsigned char#define uint unsigned int#define I2CReadAdr 0xA1 /写地址,格式为:(命令1010+器件3位地址+读/写)。#define I2CWriteAdr 0xA0 /AT24C02读地址/*管脚定义*/sbit I2CSCK =P16; /24C02时钟信号sbit I2CSDA =P17; /24C02数据信号sb
9、it HoldOn =P07; /模拟摘机控制端,为0时摘机sbit Control1 =P24; /继电器1控制端,低电平有效sbit Control2 =P25; /继电器2控制端,低电平有效sbit RingInt =P30; /振铃信号检测端/*全局变量*/uchar allow;uchar GRingCount;uchar shumima;uchar dat;uchar dat1;uchar open;uchar close;uchar a;uint dlycount;uint dlyGRingCount;uint openGRingCount1;uint openGRingCoun
10、t2;uint closeGRingCount1;uint closeGRingCount2; / 延时计数值uchar ucGPassward6=0x00,0x00,0x00,0x00,0x00,0x00; /初始密码为123456,存储在24C02中uchar data16=0x00,0x00,0x00,0x00,0x00,0x00;/输入密码暂存/*Function name:延时函数,共三个*/void Delay1ms() /1ms定时 uint s=0; for (s=150;s0;s-); void Delay20ms() /延时20ms uchar m=0; uchar n=0
11、; for(m=50;m0;m-) for(n=200;n0;n-); void Delay1s(uchar ucdly)/延时1s uchar i=0; uchar j=0; uchar k=0; for(;ucdly0;ucdly-) for(i=10;i0;i-) for(j=200;j0;j-) for(k=250;k0;k-); /*Function name: I2C读写子程序*/void I2CStart(void) /I2C开始 I2CSDA=1;/SCK为高电平时,SDA由高电平向低电平跳变,开始传送数据 I2CSCK=1; _nop_();/时序要求600ns,保证正确起始
12、 _nop_(); I2CSDA=0; I2CSCK=0; void I2CStop(void)/I2C停止 I2CSCK=0; /SCK为低电平时,SDA由低电平向高电平跳变,结束传送数据 I2CSDA=0; I2CSCK=1; I2CSDA=1; /*从24C02中读数据*/ uchar I2CRead(void) uchar i=0; uchar ucReadDat=0; for(i=8;i0;i-) /8位,先读最高位 I2CSCK=1; /获得总线操作 ucReadDat=ucReadDat0;i-)/8位,先读最高位 if(ucWriteDat&0x80)/发送数据到数据总线上 I
13、2CSDA=1; else I2CSDA=0; I2CSCK=1; /获得总线操作 _nop_(); /适当延时,等待对方接收完毕 _nop_(); I2CSCK=0; /释放总线 ucWriteDat=ucWriteDat1)&(i1)&(i4)dlycount=dlycount*10+dat1;else if(i=4) dlycount=dlycount*10+dat1;/输入三位数后延时关计时 if(close=1) closeGRingCount1=dlycount; dlycount=0; else closeGRingCount2=dlycount; dlycount=0; TR0
14、=1; i=0; delayclose=0; close=0; if(laws) i+; if(i7) data1i-1=dat1; else if(dat=0x0c) EX0=0; TR0=0; for(a=0;a6;a+) I2CStart(); I2CWrite(I2CWriteAdr); I2CWrite(data1a); I2CStop(); Delay1ms(); TR0=1; EX0=1; i=0; laws=0; else laws=0; i=0; /*/*定时中断子程序*/ void timer0() interrupt 1 using 0 TL0=0xb0; TH0=0x3
15、c; dlyGRingCount=1199; do if(openGRingCount1!=0) openGRingCount1-; if(openGRingCount1=0) Control1=0; if(openGRingCount2!=0) openGRingCount2-; if(openGRingCount2=0) Control2=0; if(closeGRingCount1!=0) closeGRingCount1-; if(closeGRingCount1=0) Control1=1; if(closeGRingCount2!=0) closeGRingCount2-; if(
16、closeGRingCount2=0) Control2=1; if(!(openGRingCount1|openGRingCount2|closeGRingCount1|closeGRingCount2) TR0=0; while(dlyGRingCount-); /*MT8870中断子程序*/ void int0(void) interrupt 0 using 1 uchar i,j,k; k=0; GRingCount=0; dat=P1; dat=dat&0x0f; if(allow=0) lcdset(); display(2,2,请输入密码); Delay1s(2); lcdset
17、(); lcdset(); shumima=1; GRingCount+; /按键的次数加1 if(GRingCount7) data1GRingCount-1=0; /将输入的数存入数组,并与数组中的密码一一比较 else data1GRingCount-1=dat; if(dat=0x0c) for(i=0;i6;i+)if(ucGPasswardi=data1i) k+;_nop_(); if(k=6)allow=1;GRingCount=0;i=0;k=0;j=0;function();shumima=0; display(1,1,开1按1关1按2); display(2,1,开2按3
18、关2按4); display(3,1,延开按5延关按6); display(4,1,改密按9挂机按*); Delay1s(2); lcdset(); lcdset(); elseallow=0; j+; i=0; k=0; GRingCount=0; if(j=1) Delay1ms(); lcdset(); display(2,2,密码错误); display(3,2,请重新输入); Delay1s(2); lcdset(); lcdset(); GRingCount+; /按键的次数加1 shumima=1; if(GRingCount7) data1GRingCount-1=0; /将输
19、入的数存入数组,并与数组中的密码一一比较 else data1GRingCount-1=dat; if(dat=0x0c) for(i=0;i=2) HoldOn=1;shumima=0;j=0; /密码输入错误两次则挂机 /*主程序*/ void main() uchar ucHoldFlag=1; /摘机标志,为0时标志为摘机 uchar ucRingCount=0; /振铃次数 uchar i; /用于计数 TMOD=0x01; /使用定时器0 TL0=0xb0; /50ms定时 TH0=0x3c; EA=1; /开中断 dlyGRingCount=1199; dlycount=0; o
20、penGRingCount1=0; openGRingCount2=0; closeGRingCount1=0; closeGRingCount2=0; while(1) if(RingInt=1) Delay1s(15); /检测到一个高电平时延时15秒 HoldOn=0; /摘机 Delay20ms(); /适当延时等待电话线上信号稳定 ucHoldFlag=0; /标志为已摘机状态 for(i=0;i6;i+) /从24C02中读取密码,密码为6位 ucGPasswardi=I2CByteRead(i);/从24C02的0-5地址中读取 EX0=1; /允许中断0(MT8870中断)if(HoldOn=0) /检测摘机状态 ucHoldFlag=0; /摘机状态 if(allow=1) function(); else ucHoldFlag=1; if(shumima=1) _nop_(); EX0=1; else HoldOn=1; /挂机标示为未摘机状态 ucHoldFlag=1;