📄 dtmf_gen.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 + -