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 support@ccsinfo.com

Generate 38KHz frequency signal using 16F877A

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



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

Generate 38KHz frequency signal using 16F877A
PostPosted: Fri Oct 17, 2008 10:14 pm     Reply with quote

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
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Sat Oct 18, 2008 5:53 am     Reply with quote

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.
aruna1



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

PostPosted: Sat Oct 18, 2008 8:03 am     Reply with quote

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
languer



Joined: 09 Jan 2004
Posts: 144
Location: USA

View user's profile Send private message

PostPosted: Sat Oct 18, 2008 5:53 pm     Reply with quote

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.
aruna1



Joined: 14 Oct 2008
Posts: 103

View user's profile Send private message

PostPosted: Sat Oct 18, 2008 9:29 pm     Reply with quote

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
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Sun Oct 19, 2008 9:38 pm     Reply with quote

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.
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Mon Oct 20, 2008 12:12 am     Reply with quote

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