Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Thread Closed: Issue successfully resolved

???
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);
}



List of 16 messages in thread
TopicAuthorDate
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      

Back to Subject List