Software PWM resources

Have you got the greatest 48 bit multiplier ever conceived? Prove it - post your code here.

Moderator: phalanx

Post Reply
HappyBomberGuy
Posts: 24
Joined: Sat Mar 13, 2010 9:37 pm

Software PWM resources

Post by HappyBomberGuy » Sun May 16, 2010 8:51 pm

Im using the 12F675 and need to come up with code to control 3 pwm lines. As the chip does not have any pwm lines it all needs to be in software. Can anyone point me in the direction of some good resources?

User avatar
leon_heller
Support Volunteer
Posts: 5734
Joined: Sun May 01, 2005 11:20 am
Location: St. Leonards-on-Sea, E. Sussex, UK.

Re: Software PWM resources

Post by leon_heller » Sun May 16, 2010 9:11 pm

Leon Heller
G1HSM

languer
Posts: 96
Joined: Fri Apr 09, 2010 12:48 pm
Location: Arizona

Re: Software PWM resources

Post by languer » Wed May 26, 2010 9:12 pm

You can also search for software pwm in MeLabs website. For C-code, look at CCS forum.

60amp_relay
Posts: 44
Joined: Fri Feb 26, 2010 12:12 pm

Re: Software PWM resources

Post by 60amp_relay » Thu Jun 03, 2010 5:32 pm

Here's how I normally do it. Unfortunately, this method uses up a lot of CPU time, but if all you need is a quick & dirty solution, this is it. The following is written from memory because I don't have any examples handy, so there may be a bunch of little mistakes, but hopefully it shows you the general idea.

Code: Select all

#include <htc.h>
#define OUTPUT 0
#define INPUT 1
#define led_a_tris TRISC0
#define led_a RC0

void pwm_out(void)
/* Brightness can be from 0 to 10.  At 0, the LED is always off.  At 10, it is always on.
 * Between those two, it's cycled off and on proportionally. */
{
  static int cycles = 0;
  int brightness = 4; /* Can be anything from 0 to 10 */

  led_a = (brightness > cycles);
  cycles = (cycles + 1) % 10;
}

void interrupt isr(void)
{
  if (T0IE && T0IF)
  {
    T0IF = 0; /* Acknowledge TIMER0 interrupt */
    pwm_out();
  }
}

void setup_timer0(void)
{
  /* Put TIMER0 into TIMER mode (counts using internal clock. External
   * clock signals and pins will be ignored. */
  T0CS = 0;
  
  /* Set the pre-scaler */
  PSA = 0;
  PS2 = 0;
  PS1 = 1;
  PS0 = 1;
  
  TMR0 = 0; /* Reset the timer */
  T0IF = 0; /* Acknowledge any prior interrupt */
  T0IE = 1; /* Unmask the timer0 interrupt */ 
}  

int main(void)
{
  led_a_tris = OUTPUT;
  setup_timer0();
  GIE = 1;  /* Enable interrupts */
  while (-1)
  {
    /* The main part of your program happens here.  Interrupts handle PWM output. */
  } 
  return 0;
}
Hope this helps.

HappyBomberGuy
Posts: 24
Joined: Sat Mar 13, 2010 9:37 pm

Re: Software PWM resources

Post by HappyBomberGuy » Fri Jun 04, 2010 5:21 am

Thanks very much. I believe this will be of great use.

millwood
Posts: 115
Joined: Thu Jul 02, 2009 2:09 pm

Re: Software PWM resources

Post by millwood » Mon Jul 05, 2010 7:53 am

I have an approach that will generate exceptionally fast software pwm.

assuming that you want a 8-bit resolution pwm, the traditional approach increments a cycle counter from 0 - 255 and at each count, you compare it with your desired duty cycle to determine if you turn a channel on or off. so you test the duty cycle 256 times in one pwm cycle, x the number of channels you desire. a very time consuming process.

my approach divides that into time domain. It breaks down the duty cycle into binary steps: 1, 2, 4, 8, ... 128. so a duty cycle of 18 consists of a "on" state of 2 cycles + a "on" state of 16 cycles. As such, you make 8 comparisons. the result is exceptionally fasts pwm whose speed is largely unaffected by the number of pwm channels.

here is the rough flow:

start: dc counter=1<<0;
if (dc_counter = ch1's dc) turn on ch1; else turn off ch1;
//repeat the above for the desired number of channels
delay a little based on dc_counter;
i<<=1;
go to start until you have finished all 8 bits

on a 12f675 running at 4mhz, I can get 2 independent channels of pwm in about 1.2ms, un-optimized.

the speed / linearity of the pwm output largely depends on the delay routine used.

you can easily adapted this approach to produce any number of resolutions.

the use of binary here is for speed. you can certainly modify the code to produce in decimal or hex steps.
Last edited by millwood on Mon Jul 05, 2010 7:56 am, edited 2 times in total.

millwood
Posts: 115
Joined: Thu Jul 02, 2009 2:09 pm

Re: Software PWM resources

Post by millwood » Mon Jul 05, 2010 7:54 am

it was pointed out to me this approach of pwm generation is called "bit angle modulation".

firestarter
Posts: 8
Joined: Mon Jun 20, 2011 11:18 am

Re: Software PWM resources

Post by firestarter » Thu Jun 23, 2011 4:17 pm

It is called bit angle modulation, BAM for short, and it is by far the best way to accomplish the tasks at hand in this thread. Hopefully this comment can provide a final statement for those who come across it. I have dealt with this on a variety of electronic projects all the way from computing devices, to home electronics, to moisture meter testing, etc. It is a helpful process.

Post Reply