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

Software PWM 40KHz with variable duty cycle

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



Joined: 15 Apr 2013
Posts: 6
Location: India

View user's profile Send private message

Software PWM 40KHz with variable duty cycle
PostPosted: Sun Jun 30, 2013 10:44 am     Reply with quote

Hi all,

I'm new to PIC and have worked with the basics on PIC. I am trying to explore features like Timers, software PWM etc.

I'm using 16F677 running at 8MHz internal clock. I am trying to generate a software PWM of frequency 40KHz. I have seen methods which use
Code:
output_high(pin);
delay_us(13);
output_low(pin);
delay_us(12);

Repeating it multiple times can generate what I require. However I need to achieve the same without using delays; by using Timers. One reason why no delays because I could use that time to work with other devices.
I also require control over the duty cycle(could be anything between 5-95%) Is this even possible? If yes, kindly point me into the right direction..

Another general question: Can we access the data stored in the Timer registers.? i.e: The 8 bit data in Timer0 or the 16 bit data in Timer1, if yes, again kindly point me into the right direction

Thank you..
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Sun Jun 30, 2013 12:37 pm     Reply with quote

Not possible.
Just too fast.
It takes _time_ to setup timers, read timers, detect timers have expired. 40KHz, is a total cycle of just 25uSec. Just 50 processor cycles.
Even using the delays approach, you could only do a very limited range of cycle durations.
Seriously, the whole point of hardware PWM's, is to allow frequencies above what software can handle and allow reliable operation while the processor is doing other things.

Best Wishes
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Jun 30, 2013 1:49 pm     Reply with quote

Sit down and do the maths.
(With the data sheet if you need it)

You want 40kHz frequency with an 8MHz clock.
That defines your range of duty cycles using the PIC's built in hardware PWM.

With your posted code you've totally ignored the time taken to perform the output_xxx(pin) functions.

Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 30, 2013 1:56 pm     Reply with quote

I suspect you want to make an IR TV remote transmitter. If that's what
you want to do, you should tell us.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Jun 30, 2013 11:50 pm     Reply with quote

PIC16F677 can do hardware PWM for a single half- or full bridge. Modulation schemes are limited to basic 2-level, however.
reddyysnr



Joined: 15 Apr 2013
Posts: 6
Location: India

View user's profile Send private message

PostPosted: Mon Jul 01, 2013 6:59 am     Reply with quote

@Ttelmah,@Mike Walne

Correct me if I'm wrong.

At 8MHz, every instruction cycle takes 0.5uS. (I read on some page that 1/(clock/4) gives the time period of one instruction cycle)
If we need to generate something which has a duty cycle of 25uS, why wouldn't that be enough?

Even with the approach of
Code:
output_high(pin);
delay_us(delay);
output_low(pin);
delay_us(delay);

if we calculate the time taken for output_xx(pin) and change delay accordingly, why wouldn't it work?

If not possible, what would be the maximum achievable frequency and how do I calculate it?

@PCM programmer: At this point, I haven't thought about an IR transmitter. I'm just experimenting to learn.

Quote:
PIC16F677 can do hardware PWM for a single half- or full bridge. Modulation schemes are limited to basic 2-level, however.


@FvM: I don't seem to understand. Could you explain a bit.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Mon Jul 01, 2013 8:00 am     Reply with quote

You said this in your first post.
Quote:
Repeating it multiple times can generate what I require. However I need to achieve the same without using delays; by using Timers. One reason why no delays because I could use that time to work with other devices.
Using delays can be made to work, but there are two problems, (1) it ties up the PIC (2) resolution is limited to 500ns at best.
With the hardware PWM you free up the PIC and get 125ns resolution.

Mr. T. and I are trying to point you in the right direction.

Quote:
If not possible, what would be the maximum achievable frequency and how do I calculate it?
This question is simply moving the goal posts.
I believe maximum frequency achievable is 2MHz with your 8MHz clock, but it's not terribly helpful.
The calculations are shown in the data sheet.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Mon Jul 01, 2013 8:47 am     Reply with quote

First understand that a single C instruction is lots of PIC instructions. Something like a multiply, _hundreds_. However even something simple like reading a timer register, for a 16bit timer, has to select the bank used, read an eight bit byte, select another bank, and write this to a RAM location, then do the same for the second byte. Just loading a timer, with a value from a variable, will take something like ten machine instructions. 0.5uSec/instruction, is only 50 instructions in 25uSec. Yes, you could generate a 40KHz pulse, but using two variable widths, no. Using a timer, and setting/reading it, will just take too long. You could have two delay based routines, giving two different pulse widths, and switch physically between these.

delay_us(variable), has a minimum time it can generate (just the time needed to access the variable and test), and a minimum 'step size'. Minimum time, for your processor will be 5uSec, and 1.5uSec 'step'.

Then simply outputting a level will take typically four instructions. So, you could have a couple of routines to develop say a 35% duty cycle, and a 65% duty cycle, adjust all the timings to work, and switch between them, but how are you then going to find the time to do this switch?.
Seriously, play with the hardware PWM, that is what it is _for_.
With this, the hardware generates all the timings once told, so you can do the jobs like making a decision to change pulse width....

Now, there are ways of being 'ingenious', and getting close, Primarily (funnily), using Timer2. Alone of the 'standard' timers, it can handle generating short timings, with automatic resetting. It's designed this way, to drive a PWM.....

Code:

#USE FAST_IO(A) //speed up pin I/O
#bit T2IF=getenv("BIT:TMR2IF") //Timer 2 interrupt flag

void main(void)
{
      int8 val;
      output_low(PIN_A1); //set latch low
      output_drive(PIN_A1);  //set the pin to drive
      disable_interrupts(GLOBAL); //Make sure interrupts are off
      val=5;
      setup_timer_2(T2_DIV_BY_1,49,1); //Timer2 will now run at 40KHz
      do
      {
         clear_interrupt(INT_TIMER2);
         output_high(PIN_A1);
         delay_us(val);
         output_low(PIN_A1);
         while(T2IF==0) ; //wait for timer2
      } while(TRUE); //and loop
}

Now this is just about as close to optimal as you can get. First the loop is automatically timed by Timer2, which interrupts 40000 times per second. When this happens T2IF is set, which then terminates the loop. No changing or reading it's value, just poll the interrupt flag.

Then the port is used in 'fast_io' mode, where you control the TRIS, and so just one instruction is needed to set or clear a pin (plus bank switching).

Now, with val=0, you get a pulse of 6uSec. You get the same 6uSec all the way to val=8. Then at val=9, it jumps to 9.5uSec, with the same for val=10, then every other 'val' value, gives different times up to val=22. After this it starts running out of time, and the output frequency drops.

As a general comment, get MPLAB, and start experimenting in it's simulator. This way you can see how long things take.

Best Wishes
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Jul 01, 2013 4:36 pm     Reply with quote

WHAT are you actually trying to DO !!!

unless your goal is to simply get a good grade,
with knowledge of your specific design task,
much more help could come your way.

but with the opaque presentation so far- not so likely


Very Happy Very Happy Very Happy Very Happy
reddyysnr



Joined: 15 Apr 2013
Posts: 6
Location: India

View user's profile Send private message

PostPosted: Tue Jul 02, 2013 2:10 am     Reply with quote

@Ttelmah: That was pretty helpful. Though I didn't understand a few things, I'll use them as pointers to try and explore. I use Proteus to simulate; I'll try out MPLab..

@asmboy: There's nothing at all to be hidden.. I'm not working on any secret project. Rolling Eyes Like I said, I'm just trying to experiment with software PWM. 40KHz was a number I found interesting because I see it's used in IR Protocols, Ultrasound Transceivers and also some AC lamp dimmers.. If I succeed, I MIGHT take up and any of those in the future.. and if 40KHz isn't possible, my goal is to achieve the maximum possible frequency..
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Jul 02, 2013 3:55 am     Reply with quote

asmboy is not suggesting you are purposely hiding anything.
Your questions are so vague we can't figure out what you are trying to do.
You learn by having a play with REAL hardware.
FORGET PROTEUS. It will cause more problems than it solves.
If you must simulate, use MPLAB.

Like I said before the answers to your PWM questions are all in the data sheet.
Ttelmah has explained the software PWM limitations.

If you want to work at 40kHz with an 8MHz clock the hardware PWM is the sensible way to go.
That's a 25us period.
The duty period resolution will be 125ns.
So you will be able to go from duty period of zero, through 125ns, 250ns in 125ns steps.
All the way to 24.750us, 24.875us and 25us.
That's 201 steps or ~0.5% each.
If you want more resolution:-
(1) you use a faster clock for 40kHz PWM or
(2) accept lower frequency PWM.

Mike
reddyysnr



Joined: 15 Apr 2013
Posts: 6
Location: India

View user's profile Send private message

PostPosted: Tue Jul 02, 2013 5:24 am     Reply with quote

Thanks Mike.. I'm on it.. Sorry for being vague.. Next time I have a doubt, I'll post clearly..
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