|
|
View previous topic :: View next topic |
Author |
Message |
orlandoG
Joined: 15 Jun 2007 Posts: 6
|
Generate DTMF Tones |
Posted: Mon Jul 30, 2007 11:15 am |
|
|
Does anyone know how to generate DTMF tones using a single I/O line similar to the PICbasic DTMFout command? I've seen the example provided with the compiler but it looks like it needs more than one I/O line.
I have attempted make a tone generator using the modified Ex_Tone example below but it does not generate the right tones or even sound close
please help!
thanks in advance
#include <16F873.h>
#device adc=10
#FUSES NOWDT,HS,NOPUT,PROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
int i;
const long One[2] ={ 700,1200};
const long Two[2] ={ 700,1335};
const long Three[2] ={ 700,1450};
const long Four[2] ={ 770, 1200};
const long Five[2] ={ 770,1335};
const long Six[2] ={ 770,1450};
const long Seven[2] ={ 850,1200};
const long Eight[2]= { 850,1335};
const long Nine[2] ={ 850, 1450};
const long Zero[2] ={ 950, 1335};
const long Star[2] ={ 950,1200};
const long Pound[2] ={ 950,1450};
const long A[2] ={ 700,1630};
const long B[2] ={ 770,1630};
const long C[2] ={ 850,1630};
const long D[2] ={ 950,1630};
#define TONE_PIN PIN_B7
void do_delay(int ms_delay, int num_ms, int us_delay, int num_us) {
int i;
for(i=0;i<num_ms;i++)
delay_ms(250);
delay_ms(ms_delay);
for(i=0;i<num_us;i++)
delay_us(250);
delay_us(us_delay);
}
void generate_tone(long frequency, long duration)
{
int32 total_delay_time; // in microseconds
long total_ms_delay_time, total_us_delay_time;
int num_us_delays, num_ms_delays, ms_delay_time, us_delay_time;
long num_periods;
total_delay_time = (1000000/frequency)/2-10; // calculate total delay time (10 for error)
total_ms_delay_time = total_delay_time/1000; // total delay time of ms
num_ms_delays = total_ms_delay_time/250; // number of 250ms delays needed
ms_delay_time = total_ms_delay_time%250; // left over ms delay time needed
total_us_delay_time = total_delay_time%1000; // total delay time of us (ms already acounted for)
num_us_delays = total_us_delay_time/250; // number of 250us delays needed
us_delay_time = total_us_delay_time%250; // left over us delay time needed
num_periods = ((int32)duration*1000)/(1000000/frequency);
while((num_periods--) != 0)
{
do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
output_high(TONE_PIN);
do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
output_low(TONE_PIN);
}
return;
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
While(TRUE)
{
for(i=0;i<2;i++)
{
generate_tone(One[i],100);
}
delay_ms(75);
}
} |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Mon Jul 30, 2007 11:36 am |
|
|
I don't know about the DTMFout command in PICbasic, but have you stopped to consider what a waveform containing two tones might look like on one digital output line? You would need to form the analog sum of two periodic waveforms. Perhaps something could be done with high-speed PWM. You could pick four duty cycle values that correspond to the four possible sums of two logic outputs. Then use some very tricky timing to switch these duty cycles at just the right time. You would have to set up a timer interrupt that was not periodic, because the time to switch duty cycles is at the next transition of either of the two tones, whichever one was due to change state the soonest.
Robert Scott
Real-Time Specialties
Ypsilanti, Michigan |
|
|
Briartek
Joined: 07 Nov 2003 Posts: 5
|
|
Posted: Fri Aug 03, 2007 8:51 am |
|
|
Actually, CCS was suppose to include this capability in version 4. You may want to press them on it.
I asked for this when they were soliciting feeback for version 4, and they even advertised they were implementing it on their website once upon a time with these words in their posting:
Many new example programs and libraries
These are some of the new libraries and examples added to Version 4:
· FAT - Access/read/write files on a SD/MMC card that has a FAT file system. Run a long term log on your PIC® MCU, saving each entry by appending to a file. Then read the results on your PC by opening the file.
· SIM/SMART Card - Access the contact and phone number information on a SIM/SMART card, commonly found on GSM/GPRS cell phones.
· 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.
It can be done, and quite well. A faster clock speed will produce a cleaner waveform, but it can be done as slow as 4mhz. You will need to utilize a simple 2pole RC filter to clean up the waveform. I have some C code that works well compiled on its on, but once embedded into the application, it get mangled a little changing the desired frequency. We are working on a C/ASM version now. |
|
|
Digicom Guest
|
DTMF code |
Posted: Wed Aug 29, 2007 6:55 pm |
|
|
I know i am late. Joined just today, but if you or any one else in the forum need a DTMF generating code using one only pin, please, post a new inquire and I'll post the code. I have to say the is ASM code. |
|
|
Briartek
Joined: 07 Nov 2003 Posts: 5
|
|
Posted: Thu Aug 30, 2007 8:32 am |
|
|
I am sure many would appreciate it, post it in the "Code Library" forum section with a subject like, "Single Pin DTMF tone generation" |
|
|
|
|
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
|