📄 dtmp.c
字号:
# include "pic16f62xa.h" //2007.11.24
# include "pic.h"
# include "delay.h"
void DTMFFXXZ(); //DTMF方向选择
void DTMFDect(); //DTMF检测
unsigned char DATA3; //存放要发送的双音频数据
/*********************************
* 名称:init_all()
* 功能:初始化CPU,使其适应系统要求
* 入口参数:无
* 出口参数:无
**********************************/
void init_all()
{
CMCON=0x07; //将RA口作为通用数字I/O引脚
STATUS=STATUS|0x20&(~0x40); //设置文件寄存器的体1
OPTION/*_REG*/=0xcf; //将分频器分配给WDT,分频比设置为1:128,INT上升沿触发;禁止RB口上拉功能.
CLRWDT(); //喂狗(约18*128=2304ms)
TRISA=0x07; //设置RA口,使RA<0..2>为输入
TRISB=0x05; //设置RB口,使RB0\RB2为输入,余为输出
VRCON=0x07; //将RA口作为通用数字I/O引脚
STATUS=STATUS&(~0x60); //设置文件寄存器的体0
//PORTA=PORTA|0x08; //RA口初始化设置(RA3为高)
RA3=1;
//PORTB=PORTB|0xc2; //Rb口初始化设置(RB1\RB6\RB7为高)
RB1=1;RB6=1;RB7=1;
INTCON=0x90; //开放INT和全局中断使能位
}
/****************************************************************************
* 名称:interrupt INT()
* 功能:interrupt中断服务程序。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void interrupt INT()
{
unsigned char DATA1,DATA2,/*DATA3,*/DATA4,DATA5;
INTCON=0x00; //关总中断
STATUS=STATUS&(~0x60); //设置文件寄存器的体0
if(RB0) //RB0为高 有中断
{
DATA1=PORTA&0x07; //存RA<0..2>数据
DelayMs(10);
if(RB0)
{
DATA2=PORTA&0x07; //再次存RA<0..2>数据
if(DATA1==DATA2)
{
switch(DATA2)
{
case 0x06:
DATA3=0x0d; //将闭锁信号(0d)保存到DATA3单元
break;
case 0x05:
DATA3=0x0a; //将前停信号(0a)保存到DATA3单元
break;
case 0x03:
DATA3=0x0e; //将后停信号(0e)保存到DATA3单元
break;
case 0x07:
DATA3=0x00; //将正常信号(00)保存到DATA3单元
break;
default:
break;
}
DTMFFXXZ(); //判断发送双音频方向
DelayMs(1);
DTMFDect(); //发送双音频
RB6=0; //开XP1-1开关,下传VCC
do
{
CLRWDT();
DATA4=PORTB&0x01; //存放第一次采样数据
DelayMs(10);
DATA5=PORTB&0x01; //存放第二次采样数据
}
while(DATA4|DATA5!=0);
}
else //取样数据不相同则发送正常信号
{
DATA3=0x00; //将正常信号(00)保存到DATA3单元
DTMFFXXZ(); //判断发送双音频方向
DelayMs(1);
DTMFDect(); //发送双音频
RB6=0; //开XP1-1开关,下传VCC
do
{
CLRWDT();
DATA4=PORTB&0x01; //存放第一次采样数据
DelayMs(10);
DATA5=PORTB&0x01; //存放第二次采样数据
}
while(DATA4|DATA5!=0);
}
}
}
RB6=1; //置位RB6,隔直流
DelayMs(1); //延时
PORTB=PORTB|0x82; //置位RB1、RB7,双音频不选通
//INTCON=INTCON&(~0x02); //清除INT中断标志位
INTF=0;
INTCON=0x90; //开放INT和全局中断使能位
}
/*
*****************************************************************
**函数原型 : DTMFFXXZ()
**参数说明 : 无
**返回 值 : 无
**说 明 : DTMF方向选择
*****************************************************************
*/
void DTMFFXXZ()
{
unsigned char CYDATA1,CYDATA2;
RA3=0; //检测板送5V选通
DelayMs(1);
do
{
CYDATA1=PORTB&0x04; //存放第一次采样数据
DelayMs(10);
CYDATA2=PORTB&0x04; //存放第二次采样数据
}
while(CYDATA1!=CYDATA2); //两次采样数据相同表示没有干扰信号
switch(CYDATA2) //判断发送双音频方向
{
case 0x00:
{
DelayMs(1);
RA3=1;
RB7=0; //双音频选通
}
break;
case 0x04:
{
DelayMs(1);
RA3=1;
RB1=0; //双音频选通
}
break;
default:
break;
}
}
/*
*****************************************************************
**函数原型 : DTMFDect()
**参数说明 : 无
**返回 值 : 无
**说 明 : DTMF检测
*****************************************************************
*/
void DTMFDect()
{
unsigned char i,m;
STATUS=STATUS&(~0x60); //设置文件寄存器的体0
RB5=0; //开片选
NOP();
RB5=0; //开片选 防止有干扰
DelayMs(10);
for(i=0;i<5;i++) //发送沿线电话状态的双音频
{
RB4=1; //置时钟
m=DATA3>>i&0x01;
if(m!=0) RB3=1;
else RB3=0;
RB4=0; //清时钟(与置时钟一起产生下降沿,锁存数据代码)
DelayUs(10);
}
RB4=1; //置时钟
DelayMs(50);
for(i=0;i<5;i++) //赋值五个“1” ,产生停止码双音频
{
RB4=1; //置时钟
RB3=1;
RB4=0; //清时钟(与置时钟一起产生下降沿,锁存数据代码)
DelayUs(10);
}
PORTB=PORTB|0xba;
}
/*
************************************************************************************************************************
**函数原型 : void main(void)
**参数说明 :
**返回 值 : 无
**说 明 :主循环函数
************************************************************************************************************************
*/
void main()
{
init_all();
while(1)
{
CLRWDT();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -