⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtmf.c

📁 DTMF FSK 在51 上的实现
💻 C
字号:
                                               
//                                                                           
//   PROGRAM DESCRIPTION: This routine transmit one CID message according to
//   the DTMF routine. It will dialing server phone number, then wait for the
//   answer tone. The answer tone is 100ms 2300hz tone, 100ms silence,then
//	 100 ms 1400hz tone. We after we send the message ,there will be a 1400hz
//	 kiss off tone.
//                                                                           
//   ADDITIONAL DOCUMENTATION:                                               
//         Flow Chart:                                                       
//         Support Doc's:                                                    
//                                                                           
//   INPUTS:                                                                 
//   OUTPUTS:                                                                
//   REGISTERS USED:                                                         
//   SUBROUTINE CALLS:                                                       
//   CALLED BY:                                                              
//                                                                           
//   REVISION HISTORY:                                                       
//                                                                           
//   DATE        REVISED BY        DESCRIPTION OF CHANGE                     
// ------------------------------------------------------------------------- 


#include<reg51f.h>
#include "dtmf.h"


//------------------------------- PCA period value -------------------------/
code unsigned int DTMF_PERIOD[16][2]=  //dual tone time period.
{//arranged by:{CEX0:high tone; CEX1:low tone }
  {0x0176,0x0213},//;digit 0
  {0x019E,0x02CD},//;digit 1
  {0x0176,0x02CD},//;digit 2
  {0x0153,0x02CD},//;digit 3
  {0x019E,0x028A},//;digit 4
  {0x0176,0x028A},//;digit 5
  {0x0153,0x028A},//;digit 6
  {0x019E,0x024B},//;digit 7
  {0x0176,0x024B},//;digit 8
  {0x0153,0x024B},//;digit 9
 
  {0x0132,0x0213},//;digit a
  {0x019E,0x0213},//;digit b
  {0x0153,0x0213},//;digit c
  {0x0132,0x02CD},//;digit d
  {0x0132,0x028A},//;digit */e
  {0x0132,0x024B},//;digit #/f
};
bit  DTMF_start;
bit  DTMF_1ms_timer;
bit  DTMF_capture_flag;
extern bit CEX2_first_period;//control the 1ms timer when set this bit to 1;
      
unsigned char tel_number_count=8;
unsigned char DTMF_process_step0;
unsigned char DTMF_process_step1;
unsigned char DTMF_capture_window;
unsigned char DTMF_capture_count;//used in data period detect
unsigned int  DTMF_process_time;//
unsigned int  DTMF_1ms_count;
unsigned int  DTMF_10ms_count;
unsigned int  received_tone;
unsigned int  DTMF_report_time;

unsigned char tel_number0[15]={5,8,5,5,9,6,1,2};//telephone number that we dial

///////////////////CID event code 401, debug used arrary///////
unsigned char trans_data[16]={0,0,0,0,1,8,3,4,0,1,0,0,0,0,1,12};


void send_dtmf_digit(unsigned char n)
{
    unsigned int i;
	//fetch period value from table.
	i=DTMF_PERIOD[n][0];
	CR=0;
	EC = 0;
	//fix the PCA module 0 register
	PCA_buf0_low = i;//low byte
	CCAP0L = PCA_buf0_low;
	PCA_buf0_high = i>>8;//high byte
	CCAP0H = PCA_buf0_high;
	CH = 0;
	CL = 0;
	
	i=DTMF_PERIOD[n][1];
	//fix the PCA module 1 register
	PCA_buf1_low = i;//low byte
	CCAP1L = PCA_buf1_low;
	PCA_buf1_high = i>>8;//high byte
	CCAP1H = PCA_buf1_high;
    CEX0 = 1;
	CEX1 = 1;

	CCAPM0 = PCA_COMPARE_ON;
	CCAPM1 = PCA_COMPARE_ON;


	CCF0=0;
	CCF1=0;
	EC = 1;
	CR=1;

}
void loop_dtmf_digits(unsigned char send_data,unsigned char period)
{
	send_dtmf_digit(send_data);
    Timer0_reload();
    //send the digit for 50 ms 
	DTMF_1ms_timer = 1;
	DTMF_1ms_count=0;
	while(DTMF_1ms_count<period)
	{};
	// disable PCA output;
	CCAPM0 = PCA_OFF;
	CCAPM1 = PCA_OFF;
	CEX0 = 1;
	CEX1 = 1;
	EC = 0;
	CCF0=0;
	CCF1=0;
	DTMF_1ms_count = 0;
	Timer0_reload();
	DTMF_1ms_timer = 1;
	while(DTMF_1ms_count<period)
	{};
	DTMF_1ms_timer=0;
	DTMF_1ms_count=0;
}
void dial_the_receiver(void)
{//dial the telephone number routine
    int i;
	//pich up the phone line
	SEIZE= 0;
	HOOK = 1;
	//delay 
	delay(50000);

	for(i=0;i<tel_number_count;i++)
	{
	//loop dial the 8 phone number di
		loop_dtmf_digits(tel_number0[i],100);
	}
}
void DTMF_process(void)
{
    switch(DTMF_process_step0)
	{
	    case 0://initialize the DTMF transmit process.
		{
			DTMF_1ms_count = 0;
			DTMF_1ms_timer = 0;
			DTMF_process_step0 = 1;


		}break;
		case 1:
		{
		    //dial the telephone number
		    dial_the_receiver();
			DTMF_1ms_timer = 1;
			DTMF_1ms_count=0;
			//turn of the PCA
			CCAPM0 = PCA_OFF;
	        CCAPM1 = PCA_OFF;
	        DTMF_process_step0 = 2;
		}break;
		case 2:
		{
		    if(DTMF_1ms_count>2000)
		    {//delay 2 seconds and set PCA to detect answer tone
	            DTMF_process_step0 = 3;
				DTMF_1ms_count=0;
				DTMF_1ms_timer=1;
				DTMF_capture_flag=1;
				CEX2_first_period=1;
				DTMF_capture_window=40;//40ms
			    Timer0_reload();
				CCAPM2 = PCA_CAPTURE_ON;
				EC=1;
			}
		}break;
		case 3:
		{
		    //detect answer tone first 2300HZ answer, then 100ms 1400HZ then 100ms space
			//and then 100ms 2300HZ, if all the 
   			while(received_tone!=2300);
			while(received_tone!=1400);
			while(received_tone!=2300);

			DTMF_capture_flag=0;
			CEX2_first_period=1;


			CCAPM2 = PCA_OFF;
		    DTMF_process_step0 = 4;
		}break;
		case 4:
		{int i;
		    Timer0_reload();
			DTMF_1ms_count = 0;
			DTMF_1ms_timer = 1;
			while(DTMF_1ms_count<500)
			{};
			DTMF_1ms_count = 0;
			DTMF_1ms_timer = 0;
		    
			for(i=0;i<16;i++)
			{
			       loop_dtmf_digits(trans_data[i],50);
			}

			SEIZE=1;
			HOOK=0;

			DTMF_1ms_count = 0;
			DTMF_1ms_timer = 1;
			while(DTMF_1ms_count<500)
			{};
			CFSK_process_flag=1;
			DTMF_process_flag=0;
			
			DTMF_process_step0 = 0;
		}break;
		default:{}
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -