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 CCS Technical Support

48 pwm channels
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Feb 07, 2008 2:54 pm     Reply with quote

Quote:

You forgot to disable HTML, so the code didn't post correctly.


Thanks for the tip, PCM programmer.
I will make sure to log in before answering next time.

Best regards
Noam
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Thu Feb 07, 2008 3:02 pm     Reply with quote

Dear Noam,


Could you repost it please (With HTML disabled)?


Many thanks,

/me waiting for your reply Very Happy


EDIT: never mind, i managed to get your code to work correctly

Final result:

Code:
#include <18f4550.h>
#device HIGH_INTS=TRUE
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,PLL3,CPUDIV1,NOMCLR
#use delay(clock=48000000)
#use fast_io(d)

int8 pattern[100][1];
int8 pattern_index;
int8 i;

void set_pwm_pattern(int8 channel, int8 duty_cycle)
  {
  int8 byte_ix, mask, index;
  mask = 1 << (channel & 7);
  for (index = 0; index < duty_cycle; index++)
    pattern[index][0] |= mask;
  mask ^= 0xFF;
  while (index < 100)
    pattern[index++][0] &= mask;
  }

#int_timer2 high
void timer2_isr(void) // 6.6mS interrupt for 150Hz
{
output_d(pattern[pattern_index][0]);
if (++pattern_index >= 100)
pattern_index = 0;
}

void init(void)
{

// usual setup functions here
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,33,16);// 66uS interrupt for 150Hz * 1% steps
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);

// initialize six 8-bit ports as outputs
output_d(0);
set_tris_d(0);

memset(pattern, 0, sizeof(pattern)); // turn ALL pwm outputs OFF

enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
}

void main(void)
{
pattern_index = 0;
init();
set_pwm_pattern(0,0);
while (1){

for(i=0;i<15;++i){
set_pwm_pattern(0,i);
delay_ms(25);
}
for(i=15;i>0;--i){
set_pwm_pattern(0,i);
delay_ms(25);
}
}


}


This test code will do an Up and down fade on a led ,,, pin RD0 especially

working with 0-15 of duty is ok for a led , higher than this it just get brighter for nothing...

Best Regards,

Laurent
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Thu Feb 07, 2008 11:33 pm     Reply with quote

Ok the previous post did work #1 for PORT D.

Now I have decided to try the real deal, try for what the code was intended to be at first...multiple port pwm!

My code is:

Code:

#include <18f4550.h>
#device HIGH_INTS=TRUE
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,PLL3,CPUDIV1,NOMCLR
#use delay(clock=48000000)
#use fast_io(d)
#use fast_io(b) //<----- ADDED PORT B

int8 byte_ix,pattern[100][2];
int8 pattern_index;

void set_pwm_pattern(int8 channel, int8 duty_cycle) //PASTED your codeyou said that this was for the multiple ports
  {
  int8 byte_ix, mask, index;
  mask = 1 <<channel>> 3;
  for (index = 0; index < duty_cycle; index++)
    pattern[index][byte_ix] |= mask;
  mask ^= 0xFF;
  while (index < 100)
    pattern[index++][byte_ix] &= mask;
  }

#int_timer2 high
void timer2_isr(void) // 6.6mS interrupt for 150Hz
{
output_d(pattern[pattern_index][0]);
output_b(pattern[pattern_index][1]);//<----- ADDED PORT B
if (++pattern_index >= 100)
pattern_index = 0;
}

void init(void)
{
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1,33,16);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
output_b(0); //<----- ADDED PORT B
set_tris_b(0); //<----- ADDED PORT B
output_d(0);
set_tris_d(0);
memset(pattern, 0, sizeof(pattern));
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
}

void main(void)
{
pattern_index = 0;
init();
set_pwm_pattern(0,15);
set_pwm_pattern(1,15);
set_pwm_pattern(2,15);
set_pwm_pattern(3,15);
set_pwm_pattern(4,15);
set_pwm_pattern(5,15);
set_pwm_pattern(6,15);
set_pwm_pattern(7,15);
set_pwm_pattern(8,15);//<----- ADDED PORT B
set_pwm_pattern(9,15);//<----- ADDED PORT B
set_pwm_pattern(10,15);//<----- ADDED PORT B
set_pwm_pattern(11,15);//<----- ADDED PORT B
set_pwm_pattern(12,15);//<----- ADDED PORT B
set_pwm_pattern(13,15);//<----- ADDED PORT B
set_pwm_pattern(14,15);//<----- ADDED PORT B
set_pwm_pattern(15,15);//<----- ADDED PORT B
while (1);

}


and the result is this:



As you can see, i have not 16 but 5 led at on (the tiny pink thing you see on the leds that are OFF , is the phosphor coating which reflect red , they look like they are at ON with little voltage but they are at OFF).

but if i run the code that i have previously posted , the 8 leds can be switched at on without difficulties at an awesome pwm of 220.6hz.

Now i still get the same refresh rate of 220hz but with only 5 pins responding!!

Please help me to fix it, your code is so nice and short !

Oh btw, when you submitted your code as a guest,, I've fixed ++ increment that was missing from your code because of HTML ,, please take a look to see if everything is here Smile

Many thanks !

Laurent
Guest








PostPosted: Tue Feb 12, 2008 2:19 pm     Reply with quote

Dear Laurent,
Nice picture.
Try the following code instead of the one you sent me.

best regards
Noam

Code:

void set_pwm_pattern(int8 channel, int8 duty_cycle)
  {
  int8 byte_ix, mask, index;
  mask = 1 << (channel & 7);
  byte_ix = channel >> 3;
  for (index = 0; index < duty_cycle; index++)
    pattern[index][byte_ix] |= mask;
  mask ^= 0xFF;
  while (index < 100)
    pattern[index++][byte_ix] &= mask;
  }

ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Tue Feb 12, 2008 2:49 pm     Reply with quote

WOW thanks it works ! :D

Thank you so much ! Smile

If it wasn't because the PCD compiler is very broken , i would really like to port it to the dsPIC platform Smile

This topic is gonna be so much useful to anyone else who would be asking for software pwm !

Have a nice week,

Best Regards,

Laurent
ELCouz



Joined: 18 Jul 2007
Posts: 427
Location: Montreal,Quebec

View user's profile Send private message

PostPosted: Sat Nov 08, 2014 2:53 pm     Reply with quote

Just an update to n-squared...

This is still the most useful piece of code I've found on CCS.

I use it in many project requiring multple PWM (because 1-8 PWM avaible on some pics are not enough).


Thank you very much n-squared!
_________________
Regards,
Laurent

-----------
Here's my first visual theme for the CCS C Compiler. Enjoy!
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 Previous  1, 2
Page 2 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