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