DTMF Generators(Transmitter) built on IC HT9200A/HT9200B Holtek. For example, below picture DTMF signal 697 Hz + 1209 Hz, it is code digit 1
And now look at the frequency domain FFT
Here is the standard connection scheme IC HT9200A 8pin package and HT9200B 14pin package Holtek
DTMF Decoder(Receiver) MT8870 or HT9170B/HT9170D Here is the standard connection scheme 18pin package
Here is the code table for this table
Okay, now let's connect the output to the input of DTMF generator DTMF decoder. Control HT9200 DTMF generator I'll be using a microcontroller STM32F407, for this you can apply any controller Micrichip PIC16 / 18/24, Atmel, Arduino and Raspberry Pi. I used a 3 volt power supply, frequency SPI 125Khz, the output DTMF generator I placed an additional amplifier transistor for amplifying sound and I reduce the load on the generator output. The output of DTMF decoder I connected LEDs for to see that the code of the received signal.
Code
#include <stm32f4xx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stm32f4xx_conf.h>
//#include <stm32f4xx_rcc.h>
//#include <stm32f4xx_gpio.h>
// ***DTMF ***
#define PERIPH_PORT GPIOE
#define DTMF_SCK GPIO_ODR_ODR_5
#define DTMF_CS GPIO_ODR_ODR_3
#define DTMF_DATA GPIO_ODR_ODR_1
#define PIN_ON(a, b) a -> BSRRL = b
#define PIN_OFF(a, b) a -> BSRRH = b
unsigned char ShiftBit;
unsigned char i;
/*****************************************************************************
* Delay NOP
*****************************************************************************/
void Delay(volatile unsigned int Val)
{
for( ; Val != 0; Val--)
{
__NOP();
}
}
/**************************************************************
Code Digit DTMF HT9200
**************************************************************/
const unsigned short Look_DTMF[] =
{
0x0A, // (0) 941 + 1209 Hz
0x01, // (1) 697 + 1209 Hz
0x02, // (2) 697 + 1336 Hz
0x03, // (3) 697 + 1477 Hz
0x04, // (4) 770 + 1209 Hz
0x05, // (5) 770 + 1336 Hz
0x06, // (6) 770 + 1477 Hz
0x07, // (7) 852 + 1209 Hz
0x08, // (8) 852 + 1336 Hz
0x09, // (9) 852 + 1477 Hz
0x0D, // (A) 697 + 1633 Hz
0x0E, // (B) 770 + 1633 Hz
0x0F, // (C) 852 + 1633 Hz
0x00, // (D) 941 + 1633 Hz
0x0B, // (*) 941 + 1366 Hz
0x0C, // (#) 941 + 1477 Hz
0x10, // (16) 697 Hz
0x11, // (17) 770 HZ
0x12, // (18) 852 HZ
0x13, // (19) 941 HZ
0x14, // (20) 1209 HZ
0x15, // (21) 1336 HZ
0x16, // (22) 1477 HZ
0x17, // (23) 1633 HZ
0x18 // (24) DTMF OFF
};
/*****************************************************************************
*(SPI) 5bit HT9200
*Freq125 kHZ
*LSB
*****************************************************************************/
void SPI_5(uint16_t BUFF)
{
BUFF = Look_DTMF[BUFF]; // find code DTMF
PIN_OFF(PERIPH_PORT, DTMF_CS); // CS = 0
for (ShiftBit = 1; ShiftBit <= 5; ++ShiftBit)
{
if ((BUFF & 0x01) == 0x01)
{
PIN_ON(PERIPH_PORT, DTMF_DATA); // DATA =1
Delay(15); // delay 1 uS
PIN_OFF(PERIPH_PORT, DTMF_SCK); // clear CLOCK=0
Delay(60); // delay 4 uS
PIN_ON(PERIPH_PORT, DTMF_SCK); // set CLOCK=1
Delay(30); // delay 2 uS
}
else
{
PIN_OFF(PERIPH_PORT, DTMF_DATA);// clear DATA=0
Delay(15); // delay 1 uS
PIN_OFF(PERIPH_PORT, DTMF_SCK);// clear CLOCK=0
Delay(60); // delay 4 uS
PIN_ON(PERIPH_PORT, DTMF_SCK); // set CLOCK=1
Delay(30); // delay 2 uS
}
BUFF = BUFF >> 1; //
}
PIN_ON(PERIPH_PORT, DTMF_SCK); // CLOCK=1
Delay(15); // delay 1 uS
PIN_OFF(PERIPH_PORT, DTMF_DATA); // DATA=0
Delay(2000000);
//PIN_ON(PERIPH_PORT, DTMF_CS); // CS = 1
Delay(15); // delay 1 uS
}
//----------------------------------------------------------------------------
/*****************************************************************************
Основная программа
*****************************************************************************/
int main()
{
SystemInit(); // 168MHz
RCC-> AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER1_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_1; // Push-Pull
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR1;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR1;
RCC-> AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER3_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_3; // Push-Pull
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR3;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR3;
RCC-> AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER5_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_5; // Push-Pull
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR5;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5;
PIN_ON(PERIPH_PORT, DTMF_CS); // CS = 1
PIN_ON(PERIPH_PORT, DTMF_SCK);// CLOCK=1
while(1)
{
if((GPIOA->IDR & GPIO_IDR_IDR_0)==1)
{
for(i=0; i<=24; i++)
{
SPI_5(i);
}
}
//SPI_5(1); // Fixed DTMF code
}
}
And now look at the frequency domain FFT
Here is the standard connection scheme IC HT9200A 8pin package and HT9200B 14pin package Holtek
Here is the code table for this table, you can learn what you need to send a code to get the desired DTMF signal.
DTMF Decoder(Receiver) MT8870 or HT9170B/HT9170D Here is the standard connection scheme 18pin package
Okay, now let's connect the output to the input of DTMF generator DTMF decoder. Control HT9200 DTMF generator I'll be using a microcontroller STM32F407, for this you can apply any controller Micrichip PIC16 / 18/24, Atmel, Arduino and Raspberry Pi. I used a 3 volt power supply, frequency SPI 125Khz, the output DTMF generator I placed an additional amplifier transistor for amplifying sound and I reduce the load on the generator output. The output of DTMF decoder I connected LEDs for to see that the code of the received signal.
Code
#include <stm32f4xx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stm32f4xx_conf.h>
//#include <stm32f4xx_rcc.h>
//#include <stm32f4xx_gpio.h>
// ***DTMF ***
#define PERIPH_PORT GPIOE
#define DTMF_SCK GPIO_ODR_ODR_5
#define DTMF_CS GPIO_ODR_ODR_3
#define DTMF_DATA GPIO_ODR_ODR_1
#define PIN_ON(a, b) a -> BSRRL = b
#define PIN_OFF(a, b) a -> BSRRH = b
unsigned char ShiftBit;
unsigned char i;
/*****************************************************************************
* Delay NOP
*****************************************************************************/
void Delay(volatile unsigned int Val)
{
for( ; Val != 0; Val--)
{
__NOP();
}
}
/**************************************************************
Code Digit DTMF HT9200
**************************************************************/
const unsigned short Look_DTMF[] =
{
0x0A, // (0) 941 + 1209 Hz
0x01, // (1) 697 + 1209 Hz
0x02, // (2) 697 + 1336 Hz
0x03, // (3) 697 + 1477 Hz
0x04, // (4) 770 + 1209 Hz
0x05, // (5) 770 + 1336 Hz
0x06, // (6) 770 + 1477 Hz
0x07, // (7) 852 + 1209 Hz
0x08, // (8) 852 + 1336 Hz
0x09, // (9) 852 + 1477 Hz
0x0D, // (A) 697 + 1633 Hz
0x0E, // (B) 770 + 1633 Hz
0x0F, // (C) 852 + 1633 Hz
0x00, // (D) 941 + 1633 Hz
0x0B, // (*) 941 + 1366 Hz
0x0C, // (#) 941 + 1477 Hz
0x10, // (16) 697 Hz
0x11, // (17) 770 HZ
0x12, // (18) 852 HZ
0x13, // (19) 941 HZ
0x14, // (20) 1209 HZ
0x15, // (21) 1336 HZ
0x16, // (22) 1477 HZ
0x17, // (23) 1633 HZ
0x18 // (24) DTMF OFF
};
*(SPI) 5bit HT9200
*Freq125 kHZ
*LSB
*****************************************************************************/
void SPI_5(uint16_t BUFF)
{
BUFF = Look_DTMF[BUFF]; // find code DTMF
PIN_OFF(PERIPH_PORT, DTMF_CS); // CS = 0
for (ShiftBit = 1; ShiftBit <= 5; ++ShiftBit)
{
if ((BUFF & 0x01) == 0x01)
{
PIN_ON(PERIPH_PORT, DTMF_DATA); // DATA =1
Delay(15); // delay 1 uS
PIN_OFF(PERIPH_PORT, DTMF_SCK); // clear CLOCK=0
Delay(60); // delay 4 uS
PIN_ON(PERIPH_PORT, DTMF_SCK); // set CLOCK=1
Delay(30); // delay 2 uS
}
else
{
PIN_OFF(PERIPH_PORT, DTMF_DATA);// clear DATA=0
Delay(15); // delay 1 uS
PIN_OFF(PERIPH_PORT, DTMF_SCK);// clear CLOCK=0
Delay(60); // delay 4 uS
PIN_ON(PERIPH_PORT, DTMF_SCK); // set CLOCK=1
Delay(30); // delay 2 uS
}
BUFF = BUFF >> 1; //
}
PIN_ON(PERIPH_PORT, DTMF_SCK); // CLOCK=1
Delay(15); // delay 1 uS
PIN_OFF(PERIPH_PORT, DTMF_DATA); // DATA=0
Delay(2000000);
//PIN_ON(PERIPH_PORT, DTMF_CS); // CS = 1
Delay(15); // delay 1 uS
}
//----------------------------------------------------------------------------
/*****************************************************************************
Основная программа
*****************************************************************************/
int main()
{
SystemInit(); // 168MHz
RCC-> AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER1_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_1; // Push-Pull
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR1;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR1;
RCC-> AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER3_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_3; // Push-Pull
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR3;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR3;
RCC-> AHB1ENR |= RCC_AHB1ENR_GPIOEEN;
GPIOE->MODER |= GPIO_MODER_MODER5_0;
GPIOE->OTYPER &= ~GPIO_OTYPER_OT_5; // Push-Pull
GPIOE->PUPDR &= ~GPIO_PUPDR_PUPDR5;
GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5;
PIN_ON(PERIPH_PORT, DTMF_CS); // CS = 1
PIN_ON(PERIPH_PORT, DTMF_SCK);// CLOCK=1
while(1)
{
if((GPIOA->IDR & GPIO_IDR_IDR_0)==1)
{
for(i=0; i<=24; i++)
{
SPI_5(i);
}
}
//SPI_5(1); // Fixed DTMF code
}
}