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

📄 dtmf_gen.c

📁 这本书里共11章
💻 C
字号:
/*
 * P89LPC935 DTMF Tone Generator and DAC Example
 *
 * Copyright KEIL ELEKTRONIK GmbH and KEIL SOFTWARE, Inc. 2003 - 2004
 *
 */

#include <REG935.H>
#include <stdio.h>

#define CLOCK  6000000L       // PCLK at 12MHz XTAL 
#define RELOAD (CLOCK / 8000) // 8000Hz Timer 0 interrupt

volatile unsigned char ticks;  // 125 uSec clock tick counter

// Tone Generator Memory
struct tone  {                 // struct for Sine Wave Generator Signal
  char cos;                    // cosine factor
  char y1;                     // y[-1] value
  char y2;                     // y[-2] value
};

volatile struct tone ton1;     // DTMF Row Frequency
volatile struct tone ton2;     // DTMF Column Frequency

/*
 * Timer 0 Interrupt every 125 uSec (8KHz)
 */
void timer0 (void) interrupt 1 using 1 {
  char y;

  ticks++;             // increment tick count
	  
// Reload Timer 0 for 125 uSec period
  TL0 = (unsigned char) (5-RELOAD);
  TH0 = (unsigned char) ((5-RELOAD)>>8);

// Output DTMF tones with offset volatage 3.3V / 2 (= 0x80)
  AD1DAT3 = (unsigned char) (ton1.y1 + 0x80) + ton2.y1;

// Ton Generator: calculate sine for new DTMF tone pair  
  if (ton1.cos)  {     // generate new DTMF Row Frequency
    y       = ((char) (((int) ton1.cos * (int) ton1.y1) >> 6)) - ton1.y2;
    ton1.y2 = ton1.y1;
    ton1.y1 = y;
  }
	else  {
	  ton1.y1 = 0;       // output off
	}

  if (ton2.cos)  {     // generate new DTMF Row Frequency
    y       = ((char) (((int) ton2.cos * (int) ton2.y1) >> 6)) - ton2.y2;
    ton2.y2 = ton2.y1;
    ton2.y1 = y;
  }
	else  {
	  ton2.y1 = 0;       // output off
	}
}

/*
 * Time Delay in mSec using Timer 0 Interrupt
 */
void wait_ms (unsigned char ms)  {
  static unsigned char oldticks;

  while (1) {
	  if (ticks != oldticks)  {     // check for new tick value 
			oldticks = ticks;           // store tick value
      if ((ticks % 8) == 0)  {    // every 8 timer ticks
        if (ms == 0)  return;     // time elapsed => done
  			ms--;                     // decrement time counter
      }
		}
		PCON |= 0x01;                 // Idle mode
  }
}


// DTMF Factors for OutAmpl = 0.5
//   cos = (cos (2*PI*(DTMF_Freq/8000.0))) * 128;
//   y2  = (sin (2*PI*(DTMF_Freq/8000.0)) * OutAmpl) * 128;
#define T697Hz_cos   0x6D    // DTMF Row Frequency
#define T697Hz_y2    0x21
#define T770Hz_cos   0x69
#define T770Hz_y2    0x24
#define T852Hz_cos   0x64
#define T852Hz_y2    0x27
#define T941Hz_cos   0x5E
#define T941Hz_y2    0x2B

#define T1209Hz_cos  0x4A    // DTMF Column Frequency
#define T1209Hz_y2   0x34
#define T1336Hz_cos  0x3F
#define T1336Hz_y2   0x37
#define T1477Hz_cos  0x33
#define T1477Hz_y2   0x3A
#define T1633Hz_cos  0x24
#define T1633Hz_y2   0x3D

// struct to store DTMF ton pair frequencies
struct DTMF_tone_pair {      // Factors for Row and Column digits
  unsigned char Row_cos;     // Row Frequency
	unsigned char Row_y2;
	unsigned char Col_cos;     // Column Frequency
	unsigned char Col_y2;
};

// assign DTMF frequencies to digits
struct DTMF_tone_pair DTMF_Tones [] =  {
  {          0,         0,           0, 0          }, // no tone
  { T697Hz_cos, T697Hz_y2, T1209Hz_cos, T1209Hz_y2 }, // digit 1
  { T697Hz_cos, T697Hz_y2, T1336Hz_cos, T1336Hz_y2 }, // digit 2
  { T697Hz_cos, T697Hz_y2, T1477Hz_cos, T1477Hz_y2 }, // digit 3
  { T770Hz_cos, T770Hz_y2, T1209Hz_cos, T1209Hz_y2 }, // digit 4
  { T770Hz_cos, T770Hz_y2, T1336Hz_cos, T1336Hz_y2 }, // digit 5
  { T770Hz_cos, T770Hz_y2, T1477Hz_cos, T1477Hz_y2 }, // digit 6
  { T852Hz_cos, T852Hz_y2, T1209Hz_cos, T1209Hz_y2 }, // digit 7
  { T852Hz_cos, T852Hz_y2, T1336Hz_cos, T1336Hz_y2 }, // digit 8
  { T852Hz_cos, T852Hz_y2, T1477Hz_cos, T1477Hz_y2 }, // digit 9
  { T941Hz_cos, T941Hz_y2, T1336Hz_cos, T1336Hz_y2 }, // digit 0
  { T941Hz_cos, T941Hz_y2, T1209Hz_cos, T1209Hz_y2 }, // digit *
  { T941Hz_cos, T941Hz_y2, T1477Hz_cos, T1477Hz_y2 }, // digit #
  { T697Hz_cos, T697Hz_y2, T1633Hz_cos, T1633Hz_y2 }, // digit A
  { T770Hz_cos, T770Hz_y2, T1633Hz_cos, T1633Hz_y2 }, // digit B
  { T852Hz_cos, T852Hz_y2, T1633Hz_cos, T1633Hz_y2 }, // digit C
  { T941Hz_cos, T941Hz_y2, T1633Hz_cos, T1633Hz_y2 }, // digit D
};  


/*
 * Set Tone Generators for DTMF Tone Pair
 */
void Set_DTMF_Ton (unsigned char digit)  {
  ton1.cos = DTMF_Tones[digit].Row_cos;     // Row Frequency
	ton1.y2  = DTMF_Tones[digit].Row_y2;
	ton2.cos = DTMF_Tones[digit].Col_cos;     // Column Frequency
	ton2.y2  = DTMF_Tones[digit].Col_y2;
}
  
/*
 * Dail a DTMF Number
 */
void DTMF_Dail (unsigned char *number)  {
  while (*number)  {         // still numbers to dail there
    Set_DTMF_Ton (*number);  // setup Ton Generator 
    wait_ms (60);            // generate Ton for 60 mSec
    Set_DTMF_Ton (0);        // stop Ton Generator
    wait_ms (40);            // generate Pause for 40 mSec
		number++;
	}
}


// Number to Dail
unsigned char code Number[] = { 
   1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* 0 */, 11 /* * */, 12 /* # */, 0 /* end */ 
};

// I/O Pin Assignment
//   DAC1 P0.4  - DTMF Output

void main (void)  {
// setup Digital-to-Analog Converter
  ADCON1 = 0x04;         // Enable ADC/DAC 1
  ADMODB = 0xA8;         // set clock and enable DAC

// setup Timer 0 for periodic interrupt
  TL0 = (unsigned char) (5-RELOAD);
  TH0 = (unsigned char) ((5-RELOAD)>>8);
  TMOD = TMOD | 0x01;    // select mode 1
  TR0 = 1;               // start timer 0

// configure Interrupt System
  IEN0 = 0x82;           // Timer 0 + Global Interrupt Enable
  IP0  = 0x02;           // Timer 0 high priority

// Dail the phone number
  while (1)  {
	  DTMF_Dail (Number);  // Dail DTMF Number
    wait_ms (200);       // wait 0.2 seconds
 	}
}

⌨️ 快捷键说明

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