View previous topic :: View next topic |
Author |
Message |
aruna1
Joined: 14 Oct 2008 Posts: 103
|
Generate 38KHz frequency signal using 16F877A |
Posted: Fri Oct 17, 2008 10:14 pm |
|
|
Hi guys can some one tell me how to generate 38KHz signal using 16F877A ?
I'm making an IR obstacle detector for my robot. I have a TSOP1738 and I need to give 38KHz IR signal to operate it. So I would like to know how to generate this signal using 16F877A.
Please tell me how to do it using 16F877A with 4MHz crystal. (without using PWM pins, I need 2 PWM pins to control motors.)
But I have no idea how to do this. I'm new to PIC programming.
So can someone help me.
many thanks ![Question](images/smiles/icon_question.gif) |
|
![](templates/subSilver/images/spacer.gif) |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sat Oct 18, 2008 5:53 am |
|
|
38kHz with just software and a 4MHz clock is going to keep your PIC REAL busy. It better not have much else to do!
The brute force way is with a loop and delay statements, but interrupts for other functions will cause bumps in your waveform.
The next way is to use a timer that interrupts on overflow. When you get the interrupt reset the timer and toggle the output.
The most elegant way, but probably too computationally intensive for 38kHz, is to make an interrupt driven "numerically controlled oscillator" which can produce any precise frequency. Google will get you some good info on NCOs. I wrote one years ago for a 16C58 running at 20MHZ and it could barely cover 24kHz to 30kHz. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
![](templates/subSilver/images/spacer.gif) |
aruna1
Joined: 14 Oct 2008 Posts: 103
|
|
Posted: Sat Oct 18, 2008 8:03 am |
|
|
SherpaDoug wrote: |
The next way is to use a timer that interrupts on overflow. When you get the interrupt reset the timer and toggle the output.
|
can you explain this method please |
|
![](templates/subSilver/images/spacer.gif) |
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
Posted: Sat Oct 18, 2008 5:53 pm |
|
|
For the timer you would need something as follows. I am avoiding using TMR2 since you are using the PWM modules.
Calculations:
Fclk = 4MHz
TMR1_clk = 1MHz (Fclk / 4) -> 1:1 prescaler used
TMR1_cnt = 26
TMR1_int_freq = 38.46kHz -> error 1.2%
Code: | setup_timer_1 ( T1_DISABLED );
set_timer1(26);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
//at this point the timer will start and you should have an interrupt routine to monitor the timer
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1); |
the interrupt routine will look like this (note that this should be before the main program):
Code: | #INT_TIMER1
{
output_toggle(38k_clk_pin); // 38_clk_pin is whatever pin you have set for this
set_timer1(26);
} |
Also note that you only have less than 26 instructions to do other things. As mentioned previously, the PIC is going to be pretty busy. |
|
![](templates/subSilver/images/spacer.gif) |
aruna1
Joined: 14 Oct 2008 Posts: 103
|
|
Posted: Sat Oct 18, 2008 9:29 pm |
|
|
languer wrote: | For the timer you would need something as follows. I am avoiding using TMR2 since you are using the PWM modules.
Calculations:
Fclk = 4MHz
TMR1_clk = 1MHz (Fclk / 4) -> 1:1 prescaler used
TMR1_cnt = 26
TMR1_int_freq = 38.46kHz -> error 1.2%
Code: | setup_timer_1 ( T1_DISABLED );
set_timer1(26);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
//at this point the timer will start and you should have an interrupt routine to monitor the timer
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1); |
the interrupt routine will look like this (note that this should be before the main program):
Code: | #INT_TIMER1
{
output_toggle(38k_clk_pin); // 38_clk_pin is whatever pin you have set for this
set_timer1(26);
} |
Also note that you only have less than 26 instructions to do other things. As mentioned previously, the PIC is going to be pretty busy. |
thanks |
|
![](templates/subSilver/images/spacer.gif) |
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Sun Oct 19, 2008 9:38 pm |
|
|
I wonder if you'd be better off using the PWM output for the IR driver, and generate PWM for at least one motor in software. You don't need ultra-fast output for that, but the 38KHz has to be what it has to be. |
|
![](templates/subSilver/images/spacer.gif) |
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Mon Oct 20, 2008 12:12 am |
|
|
Quote: | I'm making an IR obstacle detector for my robot |
Do be aware that the TSOP has an automatic gain control circuit (AGC) built into it. If you give it a continuous unmodulated 38kHz carrier, the AGC treats the carrier as noise, and rejects the signal.
Look at the TSOP17xx data sheet in the Suitable Data Format section.
Turn the carrier on for a minimum of 10 cycles per burst, sample the TSOP output, then turn the carrier off.
The TSOP IR module is designed to ignore carrier bursts that are too short, or too long. It assumes these signals are noise.
If you use the above technique, then your processor won't be held up for too long doing IR.
Rohit |
|
![](templates/subSilver/images/spacer.gif) |
|