| ??? 06/21/03 16:55 Read: times |
#48993 - RE: DTMF from 8052 pin Responding to: ???'s previous message |
This could help you.. :0)
********************************************************************
* DTMF.C - example program for generating DTMF tones using Direct *
* Digital Synthesis. *
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define SAMPLE_RATE 10000 //10 kHz sample rate
#define MAX_PHASE_ACCUM 0x10000 //16-bit phase accumulator overflow value
/* Enumeration to identify DTMF characters */
enum DTMF_CHAR
{
DTMF_0, // digit 0
DTMF_1, // digit 1
DTMF_2, // digit 2
DTMF_3, // digit 3
DTMF_4, // digit 4
DTMF_5, // digit 5
DTMF_6, // digit 6
DTMF_7, // digit 7
DTMF_8, // digit 8
DTMF_9, // digit 9
DTMF_STAR, // char *
DTMF_POUND, // char #
DTMF_A, // char A
DTMF_B, // char B
DTMF_C, // char C
DTMF_D // char D
};
/* Table of sine waveform points. These are unsigned integers that vary */
/* around 128 and range as high as 255 and as low as 1. Values in this */
/* range are suitable for an 8-bit PWM register or unipolar DAC. For */
/* a bipolar DAC use signed values in whatever format works best. Bear */
/* in mind that you may need to average the two tones' sample values */
/* together to keep from overranging the DAC with the sum of both */
/* signals. */
/* The number of entries in this table corresponds to the number of */
/* bits of the phase accumulator used to index it. */
unsigned char sine_table[] =
{
0x80, 0x83, 0x86, 0x89, 0x8C, 0x8F, 0x92, 0x95,
0x98, 0x9B, 0x9E, 0xA1, 0xA4, 0xA7, 0xAA, 0xAD,
0xB0, 0xB3, 0xB6, 0xB9, 0xBB, 0xBE, 0xC1, 0xC3,
0xC6, 0xC9, 0xCB, 0xCE, 0xD0, 0xD2, 0xD5, 0xD7,
0xD9, 0xDB, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE7,
0xE9, 0xEB, 0xEC, 0xEE, 0xF0, 0xF1, 0xF2, 0xF4,
0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFB,
0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD,
0xFC, 0xFB, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6,
0xF5, 0xF4, 0xF2, 0xF1, 0xF0, 0xEE, 0xEC, 0xEB,
0xE9, 0xE7, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDB,
0xD9, 0xD7, 0xD5, 0xD2, 0xD0, 0xCE, 0xCB, 0xC9,
0xC6, 0xC3, 0xC1, 0xBE, 0xBB, 0xB9, 0xB6, 0xB3,
0xB0, 0xAD, 0xAA, 0xA7, 0xA4, 0xA1, 0x9E, 0x9B,
0x98, 0x95, 0x92, 0x8F, 0x8C, 0x89, 0x86, 0x83,
0x80, 0x7C, 0x79, 0x76, 0x73, 0x70, 0x6D, 0x6A,
0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
0x4F, 0x4C, 0x49, 0x46, 0x44, 0x41, 0x3E, 0x3C,
0x39, 0x36, 0x34, 0x31, 0x2F, 0x2D, 0x2A, 0x28,
0x26, 0x24, 0x21, 0x1F, 0x1D, 0x1B, 0x19, 0x18,
0x16, 0x14, 0x13, 0x11, 0x0F, 0x0E, 0x0D, 0x0B,
0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x04,
0x03, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x11, 0x13, 0x14,
0x16, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x21, 0x24,
0x26, 0x28, 0x2A, 0x2D, 0x2F, 0x31, 0x34, 0x36,
0x39, 0x3C, 0x3E, 0x41, 0x44, 0x46, 0x49, 0x4C,
0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
0x67, 0x6A, 0x6D, 0x70, 0x73, 0x76, 0x79, 0x7C
};
/* Tone pairs that correspond to DTMF characters in enumeration above */
struct DTMF_FREQ
{
unsigned short low_tone;
unsigned short high_tone;
} dtmf_freq[] =
{
941, 1336, //digit 0
697, 1209, //digit 1
697, 1336, //digit 2
697, 1477, //digit 3
770, 1209, //digit 4
770, 1336, //digit 5
770, 1477, //digit 6
852, 1209, //digit 7
852, 1336, //digit 8
852, 1477, //digit 9
941, 1209, //char *
941, 1477, //char #
697, 1633, //char A
770, 1633, //char B
852, 1633, //char C
941, 1633 //char D
};
/* Structure containing phase accumulators and phase increment */
/* values for the desired tone pair. Once this structure is */
/* initialized for a given DTMF digit or character, it can be */
/* used to keep generating tones indefinitely. */
struct DTMF_TONE
{
unsigned short low_phase_accum; //low tone phase accumulator
unsigned short high_phase_accum; //high tone phase accumulator
unsigned short low_phase_incr; //low tone phase increment
unsigned short high_phase_incr; //high tone phase increment
} dtmf_tone;
/* Initialize DTMF tone structure with new character */
void
new_tone(enum DTMF_CHAR dtmf_char)
{
unsigned long temp_increment;
/* Zeroing phase accumulators makes both sine waves start at zero. */
/* If you want to transition smoothly from one tone to the next */
/* without the glitch caused by dropping to zero at the end of the */
/* previous tone, don't clear the phase accumulators. */
dtmf_tone.low_phase_accum = 0;
dtmf_tone.high_phase_accum = 0;
/* Calculate phase increments for low and high tones based on */
/* frequencies of each tone, phase accumulator size, and */
/* sample rate: */
/* phase increment = frequency * accumulator size / sample rate */
/* Use a long temporary because the max phase accumulator size */
/* is already 16 bits. */
temp_increment = dtmf_freq[dtmf_char].low_tone * MAX_PHASE_ACCUM;
dtmf_tone.low_phase_incr = temp_increment / SAMPLE_RATE;
temp_increment = dtmf_freq[dtmf_char].high_tone * MAX_PHASE_ACCUM;
dtmf_tone.high_phase_incr = temp_increment / SAMPLE_RATE;
}
/* Get the next sample of the combined tone signal for the most */
/* recent DTMF character. Ordinarily this would be executed in */
/* a 10 kHz periodic interrupt and the returned value would be */
/* written to a DAC. */
unsigned short
next_dtmf_sample(void)
{
unsigned short temp_sample; //for combining both tones' sample values
/* Advance the low tone phase accumulator */
dtmf_tone.low_phase_accum += dtmf_tone.low_phase_incr;
/* Look up the next sample of the sine wave using the upper 8 bits */
/* of the phase accumulator */
temp_sample = sine_table[dtmf_tone.low_phase_accum >> 8];
/* Now repeat the process for the high tone, adding the sample */
/* value to that for the low tone */
dtmf_tone.high_phase_accum += dtmf_tone.high_phase_incr;
temp_sample += sine_table[dtmf_tone.high_phase_accum >> 8];
/* Average the two sample values so it won't overrange an 8-bit DAC */
return (temp_sample / 2);
}
void
main(void)
{
int i;
printf("Waveform sample set for DTMF Digit 1.n");
printf("Redirect output to a file and graph to view waveform.n");
/* Initialize DTMF generator for Digit 1 output. */
new_tone(DTMF_1);
/* Assuming a sample rate of 10 kHz, issue 100 ms of tone samples */
for (i = 0; i < 1000; i++)
{
printf("%dn", next_dtmf_sample());
}
exit(0);
}
|
| Topic | Author | Date |
| DTMF from 8052 pin | 01/01/70 00:00 | |
| RE: DTMF from 8052 pin | 01/01/70 00:00 | |
| RE: DTMF from 8052 pin | 01/01/70 00:00 | |
| RE: DTMF from 8052 pin | 01/01/70 00:00 | |
| RE:Rob Redding | 01/01/70 00:00 | |
| RE: RE:Rob Redding | 01/01/70 00:00 | |
| RE: Rob Redding and Michael Karas | 01/01/70 00:00 | |
| RE: Rob Redding and Michael Karas | 01/01/70 00:00 | |
| RE: Rob Redding and Michael Karas | 01/01/70 00:00 | |
| RE: Rob Redding and Michael Karas | 01/01/70 00:00 | |
| RE: Rob Redding and Michael Karas | 01/01/70 00:00 | |
| RE: Rob Redding and Michael Karas | 01/01/70 00:00 | |
| RE: RE:Rob Redding | 01/01/70 00:00 | |
| RE: DTMF generation from ADuc812 | 01/01/70 00:00 | |
| RE: DTMF generation from ADuc812 | 01/01/70 00:00 | |
RE: DTMF generation from ADuc812 | 01/01/70 00:00 |



