MCU通用资源
返回
登录/注册
FSK解码原理及实现方法
楼主
debug 于 2006-04-18 23:01:54
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]
回复
1
电脑版
Page created in 0.1719 seconds width 3 queries.