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

[solved] Avoiding delay_us and delay_ms
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
gmtandi



Joined: 22 Apr 2013
Posts: 10

View user's profile Send private message

[solved] Avoiding delay_us and delay_ms
PostPosted: Mon Apr 22, 2013 11:30 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 22, 2013 12:27 pm     Reply with quote

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:
Quote:
38*khz

Search page:
http://www.ccsinfo.com/forum/search.php
gmtandi



Joined: 22 Apr 2013
Posts: 10

View user's profile Send private message

PostPosted: Mon Apr 22, 2013 12:44 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 22, 2013 12:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 22, 2013 1:15 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 22, 2013 2:02 pm     Reply with quote

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

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

PostPosted: Mon Apr 22, 2013 4:16 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 22, 2013 4:50 pm     Reply with quote

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

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

PostPosted: Mon Apr 22, 2013 6:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Apr 22, 2013 9:11 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Apr 23, 2013 4:19 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Apr 23, 2013 9:56 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Apr 23, 2013 10:50 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Apr 23, 2013 2:15 pm     Reply with quote

So, have you still got a problem or not?

Mike
gmtandi



Joined: 22 Apr 2013
Posts: 10

View user's profile Send private message

PostPosted: Tue Apr 23, 2013 2:26 pm     Reply with quote

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.)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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