View previous topic :: View next topic |
Author |
Message |
sorasit46
Joined: 07 May 2007 Posts: 69
|
How to fixed 38KHz output for IR transmitter? |
Posted: Fri Dec 26, 2008 10:27 pm |
|
|
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
|
|
Posted: Sat Dec 27, 2008 12:00 am |
|
|
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
|
|
Posted: Sun Dec 28, 2008 9:26 am |
|
|
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
|
How can i calculate for 38Khz? |
Posted: Sun Dec 28, 2008 12:43 pm |
|
|
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
|
|
|
sorasit46
Joined: 07 May 2007 Posts: 69
|
|
Posted: Sun Dec 28, 2008 8:35 pm |
|
|
Thanks alot. |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Mon Dec 29, 2008 9:05 am |
|
|
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. |
|
|
|