×
嵌入式 > 技术百科 > 详情

软件包实现DTMF信号的产生

发布时间:2020-06-13 发布时间:
|

#pragma SMALL                  /* 预处理命令 */
//#pragma SRC
#i nclude                   
#i nclude    


#define DTMF_STEP_TAB 0x200
#define DTMF_NO_TAB 0X210
#define DTMF_SIN_TAB 0x220

#define DAC_PORT P0

#define CBYTE ((char *)0x050000)  //定义一个查表指针
//定义   名字   类型   0X05是查表区 0000是起始地址
//                     1==idata
//                     2==xdata
//                     3==pdata
//                     4==data
//                     5==code

                                       //DTMF OUTPORT

static unsigned char data H_step;                          //高频步长寄存器
static unsigned char data L_step;                          //低频步长寄存器
static unsigned char data H_ACC;                           //高频幅度寄存器
static unsigned char data L_ACC;                           //低频幅度寄存器
static unsigned char data H_DTMF;                          //高频频率寄存器
static unsigned char data L_DTMF;                          //低频频率寄存器
static unsigned char data DTMF_NO;                         //DTMF原码
static unsigned char data DTMF_NO_BUF;                     //DTMF原码寄存器
static unsigned char data DTMF_STATUS;                     //DTMF状态寄存器
static unsigned char data NO_ACC;                          //DTMF占用
static unsigned char data H_step_ACC;                      //高频步长累加寄存器
static unsigned char data L_step_ACC;                      //低频步长累加寄存器

static bit     H_DEC;               // ;高频组反向查表标志
static bit     L_DEC;               // ;低频组反向查表标志
static bit     H_CPL;               // ;高频组取反查表标志
static bit     L_CPL;               // ;低频组取反查表标志
static bit     DTMF_SWITCH;         // ;DTMF启动标志


DTMF();
void INTTTER0();
void TIMER0();
void INTTER1();
void TIMER1();
void series();
void TIMER2();


void main()
{  
    TCON=0x10;
    TH1=255;
    TL1=256-65;
    EA=1;
    TR1=1;
    TF1=1;
    for(;;)
    DTMF();
}


void INTTTER0()interrupt 0
     {
     }

void TIMER0()interrupt 1
     {
     }

void INTTER1()interrupt 2
     {
     }

void TIMER1()interrupt 3
     {
      TR1=0;
      TL1=256-65;
      TH1=0xff;
      TR1=1;
      }   

void series()interrupt 4
      {
      } 

void TIMER2()interrupt 5
      {
      }

 


DTMF()
{
       if (DTMF_SWITCH==0) goto DTMF_EXIT;       //不允许输出则退出
       if (DTMF_NO==DTMF_NO_BUF) goto SCANTAB;   //DTMF号码未改则继续
   DAC_PORT=0X80;                            //初始化输出口
       DTMF_NO_BUF=DTMF_NO&0XF;                  //导入新数据
       L_step_ACC=0;                             //清除数据区
       H_step_ACC=0;
       L_DEC=0;                                  //清除标志位
       H_DEC=0;
       L_CPL=0;
       H_CPL=0;
       ACC=CBYTE[DTMF_NO_TAB+DTMF_NO_BUF];        //;查DTMF高低频率合成数据
   NO_ACC=ACC;
       H_DTMF=ACC&0XF;                            // ;分离高频数据
       L_DTMF=NO_ACC>>4;                          //;分离低频数据
       L_step=CBYTE[DTMF_STEP_TAB+L_DTMF];        //;求低频步长
       H_step=CBYTE[DTMF_STEP_TAB+H_DTMF];        //;求高频步长

SCANTAB:
       if (L_DEC==1) goto SUBTABL;                //;转向反向查表   
       L_step_ACC=L_step_ACC+L_step;              //步长累加
       if (L_step_ACC<=144) goto continue_SCANL;  //未超出由继续
       L_step_ACC=144-(L_step_ACC-144);                        //超出就转反向扫描
       L_DEC=1;                                   //建立反向标志
       goto continue_SCANL;

SUBTABL:
       L_step_ACC=L_step_ACC-L_step;
       if (L_step_ACC<=144) goto continue_SCANL;  //;低频查表
       L_step_ACC=256-L_step_ACC;
       L_DEC=0;
       L_CPL=!L_CPL;
         
continue_SCANL:
       L_ACC=CBYTE[DTMF_SIN_TAB+L_step_ACC]+63;   //求低频幅度
       if (L_CPL==1) L_ACC=255-L_ACC;             //结果取反
       L_ACC&=0x7f;                               //修正
       if (H_DEC==1) goto SUBTABH;                //;转向反向查表           
       H_step_ACC=H_step_ACC+H_step;
       if (H_step_ACC<=144) goto continue_SCANH;
       H_step_ACC=144-(H_step_ACC-144);
       H_DEC=1;
       goto continue_SCANH;

SUBTABH:
       H_step_ACC=H_step_ACC-H_step;
       if (H_step_ACC<=144) goto continue_SCANH;    //;高频查表
       H_step_ACC=256-H_step_ACC;
       H_DEC=0;
       H_CPL=!H_CPL;
        
continue_SCANH:
       H_ACC=CBYTE[DTMF_SIN_TAB+H_step_ACC]+63;
       if (H_CPL==1) H_ACC=255-H_ACC;          //结果取反
       H_ACC&=0X7F;                      
       DAC_PORT=H_ACC+L_ACC ;                  //;DTMF数据合成
DTMF_EXIT:
       return;
   }

TAB(){
#pragma asm

org DTMF_STEP_TAB
 DB 26,29,32,35,45,50,55,61;

org DTMF_NO_TAB
 DB 0X37,0X4,0X5,0X6,0X14,0X15,0X16,0X24,0X25;
 DB 0X26,0X35,0X34,0X36,0X7,0X17,0X27;

org  DTMF_SIN_TAB  //;T=65/(δ=90/144=0.625)采样点的值
              DB 0 ,1 ,1 ,2 ,3 ,3 ,4 ,5 ,5 ,6 ;   //;0-9点
              DB 7 ,8 ,8 ,9 ,10,10,11,12,12,13;   //;10-19
              DB 14,14,15,16,16,17,18,18,19,20;   //;20-29
              DB 20,21,22,22,23,23,24,25,25,26;   //;30-39
              DB 27,27,28,28,29,30,30,31,32,32;   //;40-49
              DB 33,33,34,34,35,36,36,37,37,38;   //;50-59
              DB 38,39,39,40,40,41,42,42,43,43;   //;60-69
              DB 44,44,45,45,46,46,46,47,47,48;   //;70-79
              DB 48,49,49,50,50,50,51,51,52,52;   //;80-89
              DB 52,53,53,53,54,54,55,55,55,56;   //;90-99
              DB 56,56,57,57,57,57,58,58,58,58;   //;100-109
              DB 59,59,59,59,60,60,60,60,60,61;   //;110-119
              DB 61,61,61,61,62,62,62,62,62,62;   //;120-129
              DB 62,62,62,63,63,63,63,63,63,63;   //;130-139
              DB 63,63,63,63,63;                  //;140-144
#pragma endasm

            }




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
中国国产第三代核电实现并网发电