在线情况
楼主
  • 头像
  • 级别
  • 门派
  • 职务论坛版主
  • 积分55
  • 经验17687
  • 文章198
  • 注册2006-03-07
FSK解码原理及实现方法
/*;-------------------------------------------------------------
忙音:    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]
[ 此帖最后由DC在2012-11-8 0:40:46从 电子通识 转移过来 ]
微控网感谢您的参与
Powered by LeadBBS 9.2 .
Page created in 0.2539 seconds with 5 queries.