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

How to fixed 38KHz output for IR transmitter?

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



Joined: 07 May 2007
Posts: 69

View user's profile Send private message

How to fixed 38KHz output for IR transmitter?
PostPosted: Fri Dec 26, 2008 10:27 pm     Reply with quote

Hello
My project is infared sensor (reflection).
My source code for using the PIC12F675 to produce the 38KHZ frequency and give to the IR transmitter:
Code:
#include <12F675.h>
#device  adc=10
#FUSES NOWDT                      // No Watch Dog Timer
#FUSES INTRC_IO                  // Internal RC Osc, no CLKOUT
#FUSES NOCPD                      // No EE protection
#FUSES NoPROTECT               // No Code protected from reading
#FUSES NOMCLR                    // Master Clear pin enabled
#FUSES PUT                           // Power Up Timer
#FUSES NOBROWNOUT           // No Reset when brownout detected
#use delay(clock=4000000)    // Use built-in function:delay_ms()&delay_us()
#define Trans   PIN_A0            // Output Frequency 38KHz     Leg7
#define Detect  PIN_A2            // output for stop work       Leg5
#define Fre38   PIN_A3            // Input for Start 38KHz      Leg4
#define Reflect PIN_A4            // Input from IR receiver     Leg3

void main()
{
setup_adc_ports(NO_ANALOGS);      // Don't fix port for ADC
setup_adc(ADC_OFF);               // Analog to digital off
disable_interrupts(GLOBAL);
setup_adc(ADC_CLOCK_INTERNAL);    // Clock RC
port_a_pullups(TRUE);
setup_counters (RTCC_INTERNAL,RTCC_DIV_2);
set_tris_A(0x18);delay_ms(500);
while(1)
     {
      output_low(Trans);output_low(Detect);
      while (input(Fre38) && input(Reflect))
            {
             output_high(Trans);delay_us(4);
             output_low(Trans); delay_us(4);
            }   
      if (input(Fre38) && !input(Reflect))
         {output_high(Detect);delay_ms(1000);}
     }
}

By this way, if I add more code it will affect the frequency. How to do it if I want to add more code and don’t want it to affect the frequency ? (Fixed at 38.0 Khz).

Regard
Sosit


Last edited by sorasit46 on Sat Dec 27, 2008 1:26 am; edited 1 time in total
andrewg



Joined: 17 Aug 2005
Posts: 316
Location: Perth, Western Australia

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

PostPosted: Sat Dec 27, 2008 12:00 am     Reply with quote

Ideally, you'd switch to a micro that supports hardware PWM, such as the 12F615.

The next best option is to use a timer interrupt to toggle the output.
_________________
Andrew
sorasit46



Joined: 07 May 2007
Posts: 69

View user's profile Send private message

PostPosted: Sun Dec 28, 2008 9:26 am     Reply with quote

andrewg wrote:
Ideally, you'd switch to a micro that supports hardware PWM, such as the 12F615.

The next best option is to use a timer interrupt to toggle the output.


How to use timer interrupt by 12F675 ?
regard
sorasit46



Joined: 07 May 2007
Posts: 69

View user's profile Send private message

How can i calculate for 38Khz?
PostPosted: Sun Dec 28, 2008 12:43 pm     Reply with quote

This give a freq of 1.9Khz (scope). Why not 38Khz ?
Anybody have any idea what did I did wrong?
How can I calculate for 38Khz?
Code:

#include <12F675.h>
#device  adc=10
#FUSES NOWDT                      // No Watch Dog Timer
#FUSES INTRC_IO                   // Internal RC Osc, no CLKOUT
#FUSES NOCPD                      // No EE protection
#FUSES NoPROTECT                  // No Code protected from reading
#FUSES NOMCLR                     // Master Clear pin enabled
#FUSES PUT                        // Power Up Timer
#FUSES NOBROWNOUT                 // No Reset when brownout detected
#use delay(clock=4000000)         // Use built-in function:delay_ms()&delay_us()
#define Trans   PIN_A0            // Output Frequency 38KHz     Leg7

#INT_TIMER0                                     
void     IntTMR0_isr(void)                       
{   
 output_toggle(Trans);
 set_timer0(26);
}

void main()
{
setup_adc_ports(NO_ANALOGS);     
setup_adc(ADC_OFF);               
setup_adc(ADC_CLOCK_INTERNAL);   
set_timer0(26);                 // Fclk=4MHz , 1:1 prescaler , 1/26=38.46kHz
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);                       
set_tris_A(0x3A);
while(True)
{}
}


regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Dec 28, 2008 2:06 pm     Reply with quote

Download the 12F675 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41190E.pdf
Read this section, on page 27 (page 29 in the Acrobat reader):
Quote:
4.1 Timer0 Operation

Is the Timer0 an up-counter or a down-counter ? Section 4.1 of the
data sheet will answer that question.

Also read this description of how to calculate the interrupt rate.
http://www.ccsinfo.com/forum/viewtopic.php?t=33764&start=3
sorasit46



Joined: 07 May 2007
Posts: 69

View user's profile Send private message

PostPosted: Sun Dec 28, 2008 8:35 pm     Reply with quote

PCM programmer wrote:
Download the 12F675 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41190E.pdf
Read this section, on page 27 (page 29 in the Acrobat reader):
Quote:
4.1 Timer0 Operation

Is the Timer0 an up-counter or a down-counter ? Section 4.1 of the
data sheet will answer that question.

Also read this description of how to calculate the interrupt rate.
http://www.ccsinfo.com/forum/viewtopic.php?t=33764&start=3


Thanks alot.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Mon Dec 29, 2008 9:05 am     Reply with quote

Maybe someone can explain how this could work, but I'm skeptical.

At 76KHz (twice the 38KHz LED flash rate, as the LED has to go on, then off) there are just over 13 microseconds, which with a 4MHz oscillator is the same as instruction times, available between interrupts. Using the basic CCS interrupt handler, it just can't be done. Maybe with the global interrupt method there's a chance, but then you have to decide which registers absolutely must be saved. Perhaps it's possible.

There's some hope for avoiding interrupts and just monitoring the flag inside a loop. At least in theory, that's workable.

However, even in that case there's the problem that the flag will be getting set every 13.0usec, not every 13.15789474usec. That difference may be enough to prevent the IR receiver from working properly. It might be better to use a 40KHz receiver; then you could at least generate the exact frequency you need. But it would be a lot better to get a chip with a PWM output!

Or, build an external oscillator and just control its operation with the processor. Not expensive or difficult.
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