|
|
View previous topic :: View next topic |
Author |
Message |
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
[solved] Avoiding delay_us and delay_ms |
Posted: Mon Apr 22, 2013 11:30 am |
|
|
Hello,
I had written a code for a pic16f628a that was using the PWM module to generate the 38khz carrier square wave (ir remote control), and delay_us and delay_ms to put the signal high and low on the right time.
Now I'm writing the same thing, but trying to use interruptions, to avoid the "delays". It's being a little hard to adjust the timing based on interruption counter.
What is the best way to get the best timing with interruptions?
I'm using Timer1 div4 and my clock is 16mhz.
thanks
-- edit --
solved: postscaler
Last edited by gmtandi on Tue Apr 23, 2013 7:55 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 22, 2013 12:27 pm |
|
|
There are many previous threads on this, and some of them are pretty good. To find them, use the forum search page to search for this:
Search page:
http://www.ccsinfo.com/forum/search.php |
|
|
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
|
Posted: Mon Apr 22, 2013 12:44 pm |
|
|
Mostly of them are to decode IR, once i already got the stream. I would like to transmit the signal, but without using delays to define the pulse length.
I'll try with int_timer0 this time, thanks ;) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19401
|
|
Posted: Mon Apr 22, 2013 12:52 pm |
|
|
A very easy way, but involving extra pins, is to just have the 38KHz run continuously. Connect it to the CCP input and also to a logic gate. Then work out how many pulses you want for each period, and set/reset a pin connected to the other input of the gate when the CCP triggers.
Best Wishes |
|
|
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
|
Posted: Mon Apr 22, 2013 1:15 pm |
|
|
okay, i got it, but I'm with timing issues when counting from timer interrupts, the delay of 400us in a delay_us is not the same 400us in timer (from get_timer1()), it's being hard to get exact timing for the pulses output.
The ccp is running at 38.4khz, but the pulses only are in the exact length with delay_us function. That's causing a few issues, like delay on button press detection, delay writing on the lcd/usart. If i can remove those delay_us, and replace with timer interrupts, would be great. I looked alot on the forum looking for someone who did something like that, but on this forum, almost everybody who worked with ir remote are with issues with ccp pwm frequency(38khz) and are using delay_us/delay_ms to get the timing. Everything freezes when the delay is running. |
|
|
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
|
Posted: Mon Apr 22, 2013 2:02 pm |
|
|
is there any way to decrease the timer interrupt overflow? it's 13.1ms at now :/ too high
--- edit --
i'm sorry again, i forgot the set_timer1();
//
i can't set_timer() on timer 3 and 5, only timer 1... what does differ the timer1 from timer3 and 5?
- http://ww1.microchip.com/downloads/en/DeviceDoc/41458B.pdf
i read the datasheet and can't find what's the difference, it's 16bits, but on get_timer() of 3 and 5 i get only 8 bits, why?
thanks |
|
|
SuperDave
Joined: 22 May 2008 Posts: 63 Location: Madison, TN
|
|
Posted: Mon Apr 22, 2013 4:16 pm |
|
|
For 38kHz, your target is 26.3uS/cycle or 13.15uS/half cycle, within a percent or two.
At 16Mhz, FOsc/4 produces 4MHz which makes a count every 0.25uS. Make that your source.
You then need 13.15/0.25 counts or 52.6 counts so no need for a 16 bit counter and its complexity. Use Timer 2.
Code: | setup_timer2(T2_DIV_BY_1,52,1); //no prescale, 52 counts, no postscale |
In this condition, Timer2 counts until it hits 52, then resets and issues an interrupt and repeats, all automatically in pic hardware, no processing involved.
Note that because of interrupt processing time 52 might need to be 51 or 50, but the 38kHz spec is broad, typically +/- 800kHz for - 1dB response so this is only important at the extremes of range. However, one count is going to produce something like an 800kHz swing so it's worth checking.
Code: | //be sure you turn the interrupt on during initialization.
enable_interrupts(INT_TIMER2);
enable_interrupts(Global); |
Code: | //and of course alternate the IR led when the interrupt occurs
#INT_TIMER2
void Timer2Overflow() {
Output_Toggle(IRLed); //38kHz flash IR led on whatever pin
} |
Be sure that there is a resistor to set the IR led current to no more than about 20mA. The PIC spec is 25mA but it gets unhappy when you reach that limit.
A 16F628 only has timers 0,1,2 not 3 or 5, and as mentioned you only need an 8 bit and don't want the complexity (read processing cycles) to deal with a 16 bit counter. |
|
|
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
|
Posted: Mon Apr 22, 2013 4:50 pm |
|
|
hello,
Thanks, I'm generating the PWM carrier signal by CCP1, also I'm not with 628A, but a lf1527, as the datasheet i sent on last post. i'm sorry, but as i said, i ha written the code for 628a now i'm porting to another device.
my timer2 is: setup_timer_2(T2_DIV_BY_1,103,1);
my ccp setup is: setup_ccp1(CCP_PWM); and duty: set_pwm1_duty((int16)206);
With that i have a 38.4khz, so now i need to get the right timing for sending the pulses.
I'm trying by setting a prescaler to timer3, by set_timer3(65535-400); but it is not working. Also when i get_timer3(); the highest value i got is around 255. It seems to be a 8 bits timer.
There is any bit to toggle to make this timer a 16 bits as the datasheet told it is?
The same thing on Timer1 works fine, but i can't work with Timer1 at now.
thanks |
|
|
SuperDave
Joined: 22 May 2008 Posts: 63 Location: Madison, TN
|
|
Posted: Mon Apr 22, 2013 6:47 pm |
|
|
I don't have a lot more time to devote to this but here's what I can say briefly
I don't understand the need for CCP, Given a 16MHz clock, timer2 should set up just as I said for 38kHz (103 is twice 51, maybe CCP is a divide by 2?)
Then looking at your data stream (the modulation on 38kHz) put a conditional in the interrupt processor. That is some other function looks at the data and says whether you want it pulsing or not (pwm or any coding is essentially just an on/off decision over time). That routine sets a boolean. The interrupt routine then does the toggle if the boolean is true or an Output_Low (or Output_High, doesn't matter) in response to the boolean.
It's likely that the modulation routine should also be called by an interrupt. More likely, an interrupt sets its own boolean. Then in main if the boolean is true, the modulation routine is called to set the pulse boolean. You probably don't want the modulation routine exercising in an interrupt since that would probably interfere with the 38kHz pulser interrupt. The modulation routine is a much less frequently called function. Given the pre and post scaling of the 8 bit timers, this function could probably use them as well. With both scalers, a 16MHz crystal become a 4kHz interrupt. If you need more, just count interrupts before calling the modulation function. No reason for 16bits.
Lots of processing time left for other things.
p.s. Are you reading Timer3 into an int16? |
|
|
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
|
Posted: Mon Apr 22, 2013 9:11 pm |
|
|
Hello,
okay, i think i got what you said, not use the pwm module, but make a software pwm using interrupt on timer2, yeah? I think it would work, but what about processing? won't it affect all my other routines/interrupts?
I see no why not use the ccp to generate 38Khz and setup duty to 0 when it's low, and to 50% or the value i want when it's high.
I was thinking in 16bits timer for counting the time in micro seconds, but what you said is better ;)
-- yes, reading timer3 into int16 -
Code: | int16 tmp = get_timer3(); |
Also the set_timer3(any value); does not work, the overflow is occurring every 63.1ms. Only timer1 is with right "set_timer" and "get_timer". |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19401
|
|
Posted: Tue Apr 23, 2013 4:19 am |
|
|
A lot depends on what other timers you have, what clock speed your chip is running at, and who long the pulses want to be?.
So what timers have you got available to use?. What chip are you actually using (seems to change in the thread)?. What is your clock speed, and how long are the pulse on/off times you need?.
Best Wishes |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Apr 23, 2013 9:56 am |
|
|
We need more clarity on EXACTLY what you are trying to do.
1) PIC.
2) Compiler version.
3) Clock frequency.
4) Pulse length(s).
5) Tolerance
6) Anything else ......................
Mike |
|
|
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
|
Posted: Tue Apr 23, 2013 10:50 am |
|
|
Timers available: T2, T3, T4, T5, T6, T7, T8, T9, T10, Clock speed: 16Mhz(internal), Chip, lf1527( http://ww1.microchip.com/downloads/en/DeviceDoc/41458B.pdf ), pulse length (this is the original code, got with an TSOP1838):
header: 9.09ms high, 4.50ms low
1: 504us high, 570us low
0: 504us high, 1710us low
CCS version I'm using is 4.130
-- edit --
I had just reached it, my only error was to not set a postscaler, so the interrupt was going each 26us, and with a postscaler, i got another range ;)
thanks |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Apr 23, 2013 2:15 pm |
|
|
So, have you still got a problem or not?
Mike |
|
|
gmtandi
Joined: 22 Apr 2013 Posts: 10
|
|
Posted: Tue Apr 23, 2013 2:26 pm |
|
|
already solved ;) thanks for all who tried to help me, in special SuperDave
thanks again ;)
(to moderador: you can close the topic when u want 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
|