/*;-------------------------------------------------------------
忙音: 450Hz,350ms有,350ms无
700ms内156次,700ms内计数小于230次,认为忙音
;---------------------------------------------------------------
拨号音: 450Hz,持续
700ms内315次,700ms内计数大于230次,认为拨号音
;---------------------------------------------------------------
回铃音: 450Hz,1s有,4s无
;---------------------------------------------------------------
振铃音判断:25Hz,1s送,4s断
*INT1产生中断,开放T0,1s内INT1中断>10次,认为是振铃音
;---------------------------------------------------------------
50ms内无第2次INT1中断,延时400ms转入计数模式,探测拨号音(500ms超时)
有,返回B_OCCUPY=1,有人占用电话线
无,判断线上电平,1--正常返回,0--返回断线
回铃音判断:
拨本地电话: 拨号后200ms有回铃音,长1.6s(2段回铃音0.6s+1s)
拨移动电话: 拨号后8.5s有回铃音,长160ms,1.5s后出现第2个回铃音
拨号后立即计数脉冲,延时11s,一旦计数>50,跳出11s循环,等待2s后判断脉冲信号,延时1s,
若1s内无脉冲信号,确认电话拨通
若脉冲信号,确认电话忙音;同样,11s超时也确认为电话忙音. */
[CODE]#include <reg54.h>
#include <intrins.h>
/* MT8880C操作 */
sbit p_MTirq = P3 ^ 3;
sbit p_MTcs = P1 ^ 6;
sbit p_MTrw = P1 ^ 7;
sbit p_MTrs0 = P1 ^ 5;
sbit p_MTclk = P1 ^ 4;
sbit p_MTb0 = P1 ^ 3;
sbit p_MTb1 = P1 ^ 2;
sbit p_MTb2 = P1 ^ 1;
sbit p_MTb3 = P1 ^ 0;
uchar bdata MT8880Status;
sbit b_MTSRDIrq = MT8880Status ^ 0; // 低4位为状态位
sbit b_MTSRDTdre = MT8880Status ^ 1;
sbit b_MTSRDRdrf = MT8880Status ^ 2;
sbit b_MTSRDDs = MT8880Status ^ 3; //
sbit b_mtdial = MT8880Status ^ 4;
sbit b_mtburst = MT8880Status ^ 5;
uchar data MTDataTemp;
// 初始化,系统上电1s后调用
void Mt8880Ini (void) { p_MTrs0=1; p_MTrw=1; p_MTcs=0; _nop_ (); _nop_ (); p_MTclk=1; _nop_ (); _nop_ (); p_MTclk=0; p_MTcs=1; p_MTrs0=1; //;1 p_MTrw=0; //;0 p_MTcs=0; _nop_ (); _nop_ (); p_MTclk=1; _nop_ ();_nop_ (); p_MTclk=0; //;写CRA p_MTcs=1; p_MTrs0=1; //;1 p_MTrw=0; //;0 p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ ();_nop_ (); p_MTclk=0; //;写CRA p_MTcs=1; p_MTrs0=1; //;1 p_MTrw=0; //;0 p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; p_MTb3=1; _nop_ ();_nop_ (); p_MTclk=0; //;写CRA p_MTcs=1; p_MTrs0=1; //;1 p_MTrw=0; //;0 p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; p_MTb3=0; _nop_ ();_nop_ (); p_MTclk=0; //写CRB p_MTcs=1; p_MTrs0=1; //1 p_MTrw=1; //1 p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ ();_nop_ (); p_MTclk=0; //读状态寄存器 p_MTcs=1; MT8880Status=0;
}
// dtmf模式,接收信号,不允许发送
void MtDtmfMode ( void ) { p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(12&0x1) p_MTb0=1; else p_MTb0=0; if(12&0x2) p_MTb1=1; else p_MTb1=0; if(12&0x4) p_MTb2=1; else p_MTb2=0; if(12&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; //DTMF模式,无输出,IRQ开放, p_MTcs=1; p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(0&0x1) p_MTb0=1; else p_MTb0=0; if(0&0x2) p_MTb1=1; else p_MTb1=0; if(0&0x4) p_MTb2=1; else p_MTb2=0; if(0&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; //BURST模式 p_MTcs=1;
}
// burst模式,发50ms,停50ms,然后送出中断信号
void MtBurstMode ( void ) { p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(13&0x1) p_MTb0=1; else p_MTb0=0; if(13&0x2) p_MTb1=1; else p_MTb1=0; if(13&0x4) p_MTb2=1; else p_MTb2=0; if(13&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; p_MTcs=1; p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(0&0x1) p_MTb0=1; else p_MTb0=0; if(0&0x2) p_MTb1=1; else p_MTb1=0; if(0&0x4) p_MTb2=1; else p_MTb2=0; if(0&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; p_MTcs=1;
}
// cp模式,检测电话拨号音,回铃音
void MtCPMode ( void ) { p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(14&0x1) p_MTb0=1; else p_MTb0=0; if(14&0x2) p_MTb1=1; else p_MTb1=0; if(14&0x4) p_MTb2=1; else p_MTb2=0; if(14&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; p_MTcs=1; p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(1&0x1) p_MTb0=1; else p_MTb0=0; if(1&0x2) p_MTb1=1; else p_MTb1=0; if(1&0x4) p_MTb2=1; else p_MTb2=0; if(1&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; p_MTcs=1;
}
// 扩展burst模式,发送100ms,停100ms,没有中断输出
void MtEXBMode ( void ) { p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(15&0x1) p_MTb0=1; else p_MTb0=0; if(15&0x2) p_MTb1=1; else p_MTb1=0; if(15&0x4) p_MTb2=1; else p_MTb2=0; if(15&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; p_MTcs=1; p_MTrs0=1; p_MTrw=0; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); if(0&0x1) p_MTb0=1; else p_MTb0=0; if(0&0x2) p_MTb1=1; else p_MTb1=0; if(0&0x4) p_MTb2=1; else p_MTb2=0; if(0&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; p_MTcs=1;
}
// mt8880特殊寄存器读取函数
void MtSDRRead ( void ) { uchar mtbusreg; if(15&0x1) p_MTb0=1; else p_MTb0=0; if(15&0x2) p_MTb1=1; else p_MTb1=0; if(15&0x4) p_MTb2=1; else p_MTb2=0; if(15&0x8) p_MTb3=1; else p_MTb3=0; p_MTrs0=1; p_MTrw=1; p_MTcs=0; _nop_ ();_nop_ (); p_MTclk=1; _nop_ (); mtbusreg <<= 1; if(p_MTb3) mtbusreg++; mtbusreg <<= 1; if(p_MTb2) mtbusreg++; mtbusreg <<= 1; if(p_MTb1) mtbusreg++; mtbusreg <<=1; if(p_MTb0) mtbusreg++; _nop_ (); p_MTclk=0; p_MTcs=1; mtbusreg &= 0x0f; MT8880Status&=0xf0; MT8880Status+=mtbusreg;
}
// mt8880接收寄存器读取函数
void MtREGRead ( void ) { p_MTrs0=0; p_MTrw=1; p_MTcs=0; _nop_ (); _nop_ (); p_MTclk=1; _nop_ (); MTDataTemp <<= 1; if(p_MTb3) MTDataTemp++; MTDataTemp <<= 1; if(p_MTb2) MTDataTemp++; MTDataTemp <<= 1; if(p_MTb1) MTDataTemp++; MTDataTemp <<=1; if(p_MTb0) MTDataTemp++; _nop_ (); p_MTclk=0; p_MTcs=1; MTDataTemp &= 0x0f;
}
// 将数据送入mt8880的发送寄存器
void MtSend ( void ) { p_MTrs0=0; p_MTrw=0; p_MTcs=0; _nop_ (); _nop_ (); p_MTclk=1; if(MTDataTemp&0x1) p_MTb0=1; else p_MTb0=0; if(MTDataTemp&0x2) p_MTb1=1; else p_MTb1=0; if(MTDataTemp&0x4) p_MTb2=1; else p_MTb2=0; if(MTDataTemp&0x8) p_MTb3=1; else p_MTb3=0; _nop_ (); p_MTclk=0; p_MTcs=1;
}
我的思想是:
mt8880的irq脚接单片机中断,并且需要一个定时器配合。我是用int1,timer1
unsigned char cpdly; // 延时
unsigned int stcount; // 脉冲计数
bit b_mtirq;
void int1_dtmf (void) interrupt 2 using 2 { stcount++; b_mtirq=1;
}
#define TL1_VALUE 0x78 // 0xec78=60536 -- 10ms,6MHz晶振
#define TH1_VALUE 0xec
void timer0 (void) interrupt 3 using 2 { if(cpdly) cpdly--; TL1 += TL1_VALUE; TH1 += TH1_VALUE;
}
// 拨号音检测
bit judgestone (void) { unsigned char i; MtCPMode(); stcount=0; cpdly=(1000ms); b_cpdly=0; while (cpdly) { // 等待第一个脉冲,1s延时 if(b_mtirq) { cpdly=(700ms); // 接收到第一个脉冲,700ms检测时间 break; } } if(b_mtirq) { while(cpdly); // 等待延时结束 if(stcount>200) return (1); // 正确 } else return (0); // 没有中断,无拨号音
}
// 回铃音检测
bit judgesatone (void) { unsigned char i,j; MtCPMode(); stcount=0; for(j=0;j<12;j++) { // 12s延时
cpdly=(1000ms); b_cpdly=0; while (cpdly) { // 等待第一个脉冲,1s延时 if(b_mtirq) { cpdly=(700ms); // 接收到第一个脉冲,700ms检测时间 break; } } if(b_mtirq) { while(cpdly); // 等待延时结束 if(stcount>200) return (1); // 正确 } } return (0); // 12s后返回错误
}
[/CODE] |