DTMF
From Wiki
Jump to navigationJump to search
PIC Implementations
- http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011071
- http://www.sxlist.com/techref/microchip/dtmf.htm
- http://avtanski.net/projects/phone_dialer/#DATA (NTE1690 encoder)
Encoder Chips
- TC35219F (used in EHM-57)
- TP5089 (Jameco, keypad)
- TP5088 (Obsolete, binary)
- NTE1690
- UM91531
- HT9200B
PIC Code
// DTMF.C #define T2CON 0x12 #define TMR2ON 0x02 #define RP0 0x05 struct DTMF_Type { unsigned int HighFreq_Pointer;// Pointer for high frequency band, points to sinusoidal pattern unsigned int LowFreq_Pointer; // Pointer for low frequency band, points to sinusoidal pattern unsigned int HighFreq_Offset; // Offset necessary to give the wave frequency to HF Pointer unsigned int LowFreq_Offset; // Offset necessary to give the wave frequency to LF Pointer long int Tone_Duration; // Tone duration short int Active; } DTMF_Generator; // The keypad has the tones as follows: // // 1209 1336 1477 1633 // 1 2 3 A 697 // 4 5 6 B 770 // 7 8 9 C 852 // * 0 # D 941 // // To assembly the sinusoidal wave form with these frequencies // from the sinusoidal pattern table Sine, we step an offset a fixed // time, as follow below: // // 697 Hz -> Offset 09 // 770 Hz -> Offset 10 // 852 Hz -> Offset 11 // 941 Hz -> Offset 12 // 1209 Hz -> Offset 15 // 1336 Hz -> Offset 17 // 1477 Hz -> Offset 19 // 1633 Hz -> Offset 21 #define O_0697 9 #define O_0770 10 #define O_0852 11 #define O_0941 12 #define O_1209 15 #define O_1336 17 #define O_1477 19 #define O_1633 21 const unsigned int Offsets [32]={O_0941,O_1336, // '0' -> 941 and 1336 O_0697,O_1209, // '1' -> 697 and 1209 O_0697,O_1336, // '2' -> 697 and 1336 O_0697,O_1477, // '3' -> 697 and 1477 O_0770,O_1209, // '4' -> 770 and 1209 O_0770,O_1336, // '5' -> 770 and 1336 O_0770,O_1477, // '6' -> 770 and 1477 O_0852,O_1209, // '7' -> 852 and 1209 O_0852,O_1336, // '8' -> 852 and 1336 O_0852,O_1477, // '9' -> 852 and 1477 O_0697,O_1633, // 'A' -> 697 and 1633 O_0770,O_1633, // 'B' -> 770 and 1633 O_0852,O_1633, // 'C' -> 852 and 1633 O_0941,O_1633, // 'D' -> 941 and 1633 O_0941,O_1209, // 'E' -> 941 and 1209 O_0941,O_1477};// 'F' -> 941 and 1477 const unsigned int Sine [256]= { 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, 82, 83, 85, 86, 88, 89, 91, 92, 93, 95, 96, 97, 99,100,101,103,104,105,106,107, 108,109,111,112,113,114,115,115,116,117,118,119,120,120,121,122, 122,123,123,124,124,125,125,125,126,126,126,127,127,127,127,127, 127,127,127,127,127,127,126,126,126,125,125,125,124,124,123,123, 122,122,121,120,120,119,118,117,116,115,115,114,113,112,111,109, 108,107,106,105,104,103,101,100, 99, 97, 96, 95, 93, 92, 91, 89, 88, 86, 85, 83, 82, 80, 79, 77, 76, 74, 73, 71, 70, 68, 67, 65, 64, 62, 60, 59, 57, 56, 54, 53, 51, 50, 48, 47, 45, 44, 42, 41, 39, 38, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 21, 20, 19, 18, 16, 15, 14, 13, 12, 12, 11, 10, 9, 8, 7, 7, 6, 5, 5, 4, 4, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 53, 54, 56, 57, 59, 60, 62}; void DTMF_ExecuteTone (unsigned int tone); void DTMF_Setup (void); void DTMF_DutyUpdate (void); void DTMF_ExecuteTone (unsigned int tone) { DTMF_Generator.HighFreq_Offset = Offsets [2*tone]; DTMF_Generator.LowFreq_Offset = Offsets [2*tone+1]; DTMF_Generator.HighFreq_Pointer = 0; DTMF_Generator.LowFreq_Pointer = 0; DTMF_Generator.Tone_Duration = 0; enable_interrupts (INT_TIMER2); setup_ccp2 (CCP_PWM_PLUS_2); // Configures PWM with 2 Duty LSBs to B'10' (mean value). set_pwm2_duty (127>>2); // Set duty initial value to 0 (Duty 50%). set_timer2 (0); // Clears Timer 2. setup_timer_2 (T2_DIV_BY_1, 0x3F, 4); // Configures Timer 2 to 78,12 KHz. return; } void DTMF_DutyUpdate (void) { set_pwm2_duty ((Sine[DTMF_Generator.HighFreq_Pointer]>>2)+ (Sine[DTMF_Generator.LowFreq_Pointer ]>>2)); DTMF_Generator.HighFreq_Pointer += DTMF_Generator.HighFreq_Offset; DTMF_Generator.LowFreq_Pointer += DTMF_Generator.LowFreq_Offset; return; } void DTMF_TurnOff (void) { disable_interrupts (INT_TIMER2); #asm bcf STATUS,RP0 bcf T2CON,TMR2ON #endasm return; }