CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

DTMF

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ln_mark7930



Joined: 06 Mar 2009
Posts: 21

View user's profile Send private message Send e-mail

DTMF
PostPosted: Wed Jan 11, 2012 12:33 pm     Reply with quote

Hi boys,
I want to do a circuit that generate DTMF tone. I'm using EX_DTMF.c example for my PIC18F876A. my clock is 20 Crystal, but there is a problem with signal generated. I install also a 2W MONO audio amplifier at the ouput pin.
I use 220 Ohm resistors instead of 200 Ohm: I think that it's not the problem.Telephone don't recognize Tone.
I have not oscilloscope to view the ouput signal, so it's too difficult understand what''s the problem. I check the output signal with DTMF Tone Decoder (DEMO VERSION) software and seems witch the frequency of N°6 are 742,1Hz (Row) and 1484 Hz (Column).
Does some have tested this example? Does it work?

I try also the other example ( the other with 2 array of waves) but with the same result.

Follow the code of my source:

Code:


#if defined(__PCB__)
#include <16C56.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)    // must be 20 MHz

#elif defined(__PCM__)
#include <16F876A.h>
#fuses HS,NOWDT,NOPUT,NOPROTECT,NOLVP,DEBUG,NOBROWNOUT,
#use delay(clock=20000000)    // must be 20 MHz

#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)    // must be 20 MHz
#endif


CONST unsigned int SINE_WAVE[200] = {
128,132,136,139,143,147,150,154,158,161,165,169,172,176,179,
182,186,189,192,195,199,202,204,207,210,213,215,218,220,223,
225,227,229,231,233,235,237,238,240,241,242,243,244,245,246,
247,247,247,248,248,248,248,248,247,247,247,246,245,244,243,
242,241,240,238,237,235,233,231,229,227,225,223,220,218,215,
213,210,207,204,202,199,195,192,189,186,182,179,176,172,169,
165,161,158,154,150,147,143,139,136,132,128,124,120,117,113,
109,106,102, 98, 95, 91, 87, 84, 80, 77, 74, 70, 67, 64, 61,
 57, 54, 52, 49, 46, 43, 41, 38, 36, 33, 31, 29, 27, 25, 23,
 21, 19, 18, 16, 15, 14, 13, 12, 11, 10,  9,  9,  9,  8,  8,
  8,  8,  8,  9,  9,  9, 10, 11, 12, 13, 14, 15, 16, 18, 19,
 21, 23, 25, 27, 29, 31, 33, 36, 38, 41, 43, 46, 49, 52, 54,
 57, 61, 64, 67, 70, 74, 77, 80, 84, 87, 91, 95, 98,102,106,
109,113,117,120,124};

int index1,index2,inc1,inc2;
int8 freq=13;

#INT_RTCC
void wave_generator() {
   int wave = 0;

   set_rtcc(freq);     //13      // when clock is 20MHz, interrupts every 100us

   wave = ((long)SINE_WAVE[index1]+(long)SINE_WAVE[index2])/2;
   output_c(wave);

   index1 += inc1;
   index2 += inc2;

   if(index1 >= 200)
      index1 -= 200;

   if(index2 >= 200)
      index2 -= 200;
}

//#define DTMF_ROW1   14  // for 700 Hz, increment this many times every 100us
//#define DTMF_ROW2   15  // for 750 Hz, increment this many times every 100us
//#define DTMF_ROW3   17  // for 850 Hz, increment this many times every 100us
//#define DTMF_ROW4   19  // for 950 Hz, increment this many times every 100us
//#define DTMF_COLA   24  // for 1200 Hz, increment this many times every 100us
//#define DTMF_COLB   27  // for 1350 Hz, increment this many times every 100us
//#define DTMF_COLC   30  // for 1500 Hz, increment this many times every 100us

#define DTMF_ROW1   14  // for 700 Hz, increment this many times every 100us
#define DTMF_ROW2   15  // for 750 Hz, increment this many times every 100us
#define DTMF_ROW3   17  // for 850 Hz, increment this many times every 100us
#define DTMF_ROW4   19  // for 950 Hz, increment this many times every 100us
#define DTMF_COLA   24  // for 1200 Hz, increment this many times every 100us
#define DTMF_COLB   27  // for 1350 Hz, increment this many times every 100us
#define DTMF_COLC   30  // for 1500 Hz, increment this many times every 100us


void generate_dtmf_tone(char keypad, long duration)
{
index1=0;
index2=0;
inc1=0;
inc2=0;

if      ((keypad==1)||(keypad==2)||(keypad==3))      inc1=DTMF_ROW1;
else if   ((keypad==4)||(keypad==5)||(keypad==6))       inc1=DTMF_ROW2;
else if   ((keypad==7)||(keypad==8)||(keypad==9))   inc1=DTMF_ROW3;
else if   (keypad==0)   inc1=DTMF_ROW4;

if      ((keypad==1)||(keypad==4)||(keypad==7))inc2=DTMF_COLA;
else if   ((keypad==2)||(keypad==5)||(keypad==8)||(keypad==0))inc2=DTMF_COLB;
else if   ((keypad==3)||(keypad==6)||(keypad==9))inc2=DTMF_COLC;

   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   while(duration-- > 0)
   {
      delay_us(1000);
   }
   disable_interrupts(INT_RTCC);
   output_c(0);
}
////
//
// tone_out.c                                              2002/02/20

///* -------------------------------------------------------------------------------
//                           F_Low F_High  TONE  HM9270_Q4 Q3 Q2 Q1  Hex_from_HM9270
//                                                  pin_A3 A2 A1 A0   PORTA & 0x0F
//------------------------------------------------------------------------------- */
//#define  TONE_1    0x01  // 697   1209     1        0    0  0  1          1
//#define  TONE_2    0x02  // 697   1336     2        0    0  1  0          2
//#define  TONE_3    0x03  // 697   1477     3        0    0  1  1          3
//#define  TONE_4    0x04  // 770   1209     4        0    1  0  0          4
//#define  TONE_5    0x05  // 770   1336     5        0    1  0  1          5
//#define  TONE_6    0x06  // 770   1477     6        0    1  1  0          6
//#define  TONE_7    0x07  // 852   1209     7        0    1  1  1          7
//#define  TONE_8    0x08  // 852   1336     8        1    0  0  0          8
//#define  TONE_9    0x09  // 852   1477     9        1    0  0  1          9
//#define  TONE_0    0x0A  // 941   1336     0        1    0  1  0          a
//#define  TONE_mi   0x0B  // 941   1209     *        1    0  1  1          b
//#define  TONE_pa   0x0C  // 941   1477     #        1    1  0  0          c
//#define  TONE_A    0x0D  // 697   1633     A        1    1  0  1          d
//#define  TONE_B    0x0E  // 770   1633     B        1    1  1  0          e
//#define  TONE_C    0x0F  // 852   1633     C        1    1  1  1          f
//#define  TONE_D    0x00  // 941   1633     D        0    0  0  0          0
//// -------------------------------------------------------------------------------
//
//const unsigned int SINE_WAVE_HIGH[256] = { // Sine wave amplitude range : 8 ~ 248
//128,131,134,137,140,143,146,149,151,154,157,160,163,166,168,
//171,174,177,179,182,185,187,190,192,195,197,199,202,204,206,
//209,211,213,215,217,219,221,223,224,226,228,229,231,232,234,
//235,236,238,239,240,241,242,243,244,244,245,246,246,247,247,
//247,248,248,248,248,248,248,248,247,247,247,246,246,245,244,
//244,243,242,241,240,239,238,236,235,234,232,231,229,228,226,
//224,223,221,219,217,215,213,211,209,206,204,202,199,197,195,
//192,190,187,185,182,179,177,174,171,168,166,163,160,157,154,
//151,149,146,143,140,137,134,131,128,125,122,119,116,113,110,
//107,105,102, 99, 96, 93, 90, 88, 85, 82, 79, 77, 74, 71, 69,
// 66, 64, 61, 59, 57, 54, 52, 50, 47, 45, 43, 41, 39, 37, 35,
// 33, 32, 30, 28, 27, 25, 24, 22, 21, 20, 18, 17, 16, 15, 14,
// 13, 12, 12, 11, 10, 10,  9,  9,  9,  8,  8,  8,  8,  8,  8,
//  8,  9,  9,  9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18,
// 20, 21, 22, 24, 25, 27, 28, 30, 32, 33, 35, 37, 39, 41, 43,
// 45, 47, 50, 52, 54, 57, 59, 61, 64, 66, 69, 71, 74, 77, 79,
// 82, 85, 88, 90, 93, 96, 99,102,105,107,110,113,116,119,122,
//125};
//
//CONST unsigned int SINE_WAVE_LOW[256] = { // Sine wave amplitude range : 43 ~ 213
//128,130,132,134,136,138,140,143,145,147,149,151,153,155,157,
//159,161,162,164,166,168,170,172,173,175,177,179,180,182,184,
//185,187,188,190,191,192,194,195,196,197,199,200,201,202,203,
//204,205,206,207,207,208,209,209,210,210,211,211,212,212,212,
//213,213,213,213,213,213,213,213,213,212,212,212,211,211,210,
//210,209,209,208,207,207,206,205,204,203,202,201,200,199,197,
//196,195,194,192,191,190,188,187,185,184,182,180,179,177,175,
//173,172,170,168,166,164,162,161,159,157,155,153,151,149,147,
//145,143,140,138,136,134,132,130,128,126,124,122,120,118,116,
//113,111,109,107,105,103,101, 99, 97, 95, 94, 92, 90, 88, 86,
// 84, 83, 81, 79, 77, 76, 74, 72, 71, 69, 68, 66, 65, 64, 62,
// 61, 60, 59, 57, 56, 55, 54, 53, 52, 51, 50, 49, 49, 48, 47,
// 47, 46, 46, 45, 45, 44, 44, 44, 43, 43, 43, 43, 43, 43, 43,
// 43, 43, 44, 44, 44, 45, 45, 46, 46, 47, 47, 48, 49, 49, 50,
// 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 64, 65, 66, 68,
// 69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86, 88, 90, 92, 94,
// 95, 97, 99,101,103,105,107,109,111,113,116,118,120,122,124,
//126};
//
////int8 index1,index2,inc1,inc2;
//
//#INT_RTCC
//void wave_generator()
//{
//   int16 wave;
//
//   set_rtcc(freq);           //25 when clock is 20MHz, interrupts every 100us
//
//   wave   = SINE_WAVE_LOW[index1] ;
//   wave  += SINE_WAVE_HIGH[index2];
//   wave >>= 2; //
//   output_c( wave);
//
//   index1 += inc1;   //if(index1 >= 256)  index1 -= 256;  // Wu, 2003/02/26
//   index2 += inc2;   //if(index2 >= 256)  index2 -= 256;
//}
//
//#define DTMF_ROW1   18  //18 for  697 Hz, increment this many times every 100us
//#define DTMF_ROW2   20  //20 for  770 Hz,                     for SIN_WAVE[256]
//#define DTMF_ROW3   22  //22 for  852 Hz,
//#define DTMF_ROW4   24  //24 for  941 Hz,
//
//#define DTMF_COLA   32  //32 for 1209 Hz,
//#define DTMF_COLB   35  //34 for 1336 Hz, changed to 35, 2003/03/04
//#define DTMF_COLC   38  //38 for 1477 Hz,
//#define DTMF_COLD   43  //42 for 1633 Hz, //43
//
//void generate_dtmf_tone(int8 keypad, long duration)  {
//
//   index1=0;   index2=0;  inc1=0;   inc2=0;
//
//   if     ((keypad== 1)||(keypad== 2)||(keypad== 3)||(keypad==13)) inc1=DTMF_ROW1;
//   else if((keypad== 4)||(keypad== 5)||(keypad== 6)||(keypad==14)) inc1=DTMF_ROW2;
//   else if((keypad== 7)||(keypad== 8)||(keypad== 9)||(keypad==15)) inc1=DTMF_ROW3;
//   else if((keypad==11)||(keypad==10)||(keypad==12)||(keypad== 0)) inc1=DTMF_ROW4;
//
//   if     ((keypad== 1)||(keypad== 4)||(keypad== 7)||(keypad==11)) inc2=DTMF_COLA;
//   else if((keypad== 2)||(keypad== 5)||(keypad== 8)||(keypad==10)) inc2=DTMF_COLB;
//   else if((keypad== 3)||(keypad== 6)||(keypad== 9)||(keypad==12)) inc2=DTMF_COLC;
//   else if((keypad==13)||(keypad==14)||(keypad==15)||(keypad== 0)) inc2=DTMF_COLD;
//
//   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
//   enable_interrupts(INT_RTCC);
//
//   enable_interrupts(GLOBAL);   
//
//   while ( duration-- > 0 )  delay_us(1000);
//
//   disable_interrupts(INT_RTCC);
//   output_c(0);
//}
//
//


void main()
{
char k;

   while(TRUE)
         {
//      for (k=0;k<10;k++)
//         {
//         generate_dtmf_tone(k, 500);
//         delay_ms(1000);
//         }
      generate_dtmf_tone(2, 500);
      delay_ms(1000);
      generate_dtmf_tone(2, 500);
      delay_ms(1000);
      generate_dtmf_tone(6, 500);
      delay_ms(3000);
      }
}


Some One have some Idea?
Do someone use DTMF on sinlge PIN? Is it possibile have source code for DTMF single Pin?
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jan 11, 2012 1:13 pm     Reply with quote

First, I would go back to the ORIGINAL CCS ex_dtmf.c program, wire up your 16F876a as stated in the preamble of the code and see what happens.

CCS is very good about supplying working code examples, so I suspect you may have wiring issues.Be sure to use the proper resistors 100r and 200r.You could also use 110r and 220r though.

As far as a 'one pin' DTMF generator, the simple solution is to buy a DTMF chip ($2), lookup the Microchip application notes,or try 'googling' to see what is already on the Net.
Ln_mark7930



Joined: 06 Mar 2009
Posts: 21

View user's profile Send private message Send e-mail

No results
PostPosted: Thu Jan 12, 2012 7:39 am     Reply with quote

I realize original circuit with R=100 ohms 2R=200 Ohms.
I restore original ccs example firmware (EX_DTMF.C) ; I change only uC = PIC16F876A instead PIC16F16F877), but phone don't place the call.
Nothing happen's.
Now I try to replace 16f876A with 16F877A and recompile firmware.
I hope that it works!

2 o 3 years ago my friend show me that he realyzed a very simple circuit that generate DTMF tone with only one PIN ( with 16F628A - 10 Mhz clock's). I see that he use Microcode Studio software and a routine called DTMFOUT . Ie = DTMFOUT DT,200,100,[1,7,2]. DT is pin-name ; 200 is tone duration ; 100 is pause between tones and [1,7,2] is phone number that it call. Isn't there nothing similar on CCS?

I don't need that code use only one pin: code can use also eight bit. I tell you that I prefer only one pin. It's very important witch code must will work.

From CCS site: http://www.ccsinfo.com/content.php?page=compexamples we can read new functions added:

Frequency Generator - Generate tones, frequencies and DTMF using only one user define general purpose I/O pin. This is done by implementing a software PWM on one pin.

Where is DTMF only one pin function???
Do you/someone ever test/try this source on your circuit?
Is it work without problems?
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jan 12, 2012 11:48 am     Reply with quote

You should try 'googling'. While I didn't quickly find CCS C code, there are several ASM programs as well as a PBASIC 'function'. Converting them to C isn't that bad though I don't know why you're having problems with the CCS example. It could be your wiring setup as you need to have that R-2R ladder right! Also be sure to use the same crystal frequency.

Also what DTMF decoder are you using to prove/disprove it's working right or is it that you do not get any tones ?
Ln_mark7930



Joined: 06 Mar 2009
Posts: 21

View user's profile Send private message Send e-mail

DMTF : right low frequency , wrong high frequency
PostPosted: Thu Jan 12, 2012 2:08 pm     Reply with quote

Hi, thank for your time.
I control the frequency with a PC and a software that verify the audio spectrum from microphone connected to the sound card.
I can see the low frequency it's perfect, but the high frequency is always wrong about of 30-100 Hz. DTMF Tolerance it's too small respect to my frequency error.
However if put the speaker near the microphone of my phone no call start.
I retry more times to place a call with the phone, but nothing.
If You look my source I call a small number (3 digits/tone only) but it's a mystery, because no tone is decoded by phone. Tomorrow I connect my circuit to a DTMF decoder by Holtek (at the moment I forgot the name) and update the forum with the result.

Maybe I try to realize an ASM code to generate DTMF, maybe it work well.
Ln_mark7930



Joined: 06 Mar 2009
Posts: 21

View user's profile Send private message Send e-mail

No result
PostPosted: Mon Jan 16, 2012 8:24 am     Reply with quote

Nothing's change...
Holtek ( model HT9170D ) don't recognize TONES.
PIC don't generate DTMF correctly. I re-check one more time my circuit ( is only R2R circuit) and it result correct.
I found one example realized on MicroC language witch used PWM and one single PIN ( PWM pin).
Today I Convert original source to CCS C language.
I hope that its work fine.

If someone have some different solution ( without external active component) pleace write me. Thanks a lot.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon Jan 16, 2012 4:16 pm     Reply with quote

I just tweaked the example a fraction, and it then gives good tones.
I changed the interrupt to use timer2, and programmed this with:

setup_timer_2(T2_DIV_BY_4, 124, 1);

and obviously enabled INT_TIMER2, rather than INT_RTCC.

Then got rid of the 'set_rtcc(25)' line in the interrupt, and frequencies were then right.

Unfortunately the example was made rather 'generic' to cover basic PIC's that don't have timer2, and at the top end the accuracy is then being degraded by the amount the counter has advanced by the time the code gets into the interrupt. The example tones were good enough to happily trigger a couple of DTMF decoders, but failed with a couple of others. The DTMF spec requires +/-1.5% and the example only manages about 2.5% on the top tone. Actually OK with quite a few things (it actually placed a phone call for me), but 'borderline'.....

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group