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

Passing a PWM stream ID to a function

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



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

Passing a PWM stream ID to a function
PostPosted: Sun Apr 17, 2022 9:23 pm     Reply with quote

Is there a way to pass a PWM stream ID to a function, such that the stream ID can be used in the pwm_on(stream ID) and pwm_off(stream ID) statements within the function? My intent is to avoid repeating a code segment.

My code goes something like this:

Code:

#include "18LF46K22.h"
#use delay(clock=16MHz)
#use pwm(PWM1, timer=2, frequency=125kHz, duty=50, pwm_off, stream=PWM1)
#use pwm(PWM3, timer=2, frequency=125kHz, duty=50, pwm_off, stream=PWM3)
#use pwm(PWM4, timer=4, frequency=38kHz, duty=50, pwm_off, stream=PWM4)
#use pwm(PWM5, timer=4, frequency=38kHz, duty=50, pwm_off, stream=PWM5)

void send_pulse(char PWM_id[])
{
   pwm_on(PWM_id);
   delay_ms(1);
   pwm_off(PWM_id);
   delay_ms(1);
}

void main()
{
   unsigned int8 i;
   char PWM_id[5];

   /* Select PWM pin to use */
   i = 3;          /* this value will be changed depending on program algorithm */
   
   switch (i)
   {
      case 1:
      strcpy(PWM_id, "PWM1");
      send_pulse(PWM_id);
      break;
      
      case 3:
      strcpy(PWM_id, "PWM3");
      send_pulse(PWM_id);
      break;
      
      case 4:
      strcpy(PWM_id, "PWM4");
      send_pulse(PWM_id);
      break;
      
      case 5:
      strcpy(PWM_id, "PWM5");
      send_pulse(PWM_id);      
   }
}


The CCS compiler shows this error for pwm_on(PWM_id) and pwm_off(PWM_id): "Expression must evaluate to a constant".

I am using CCS PCWHD compiler v5.078 on MPLAB IDE v8.92.

I will appreciate any help or suggestions. Thank you.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Mon Apr 18, 2022 12:53 am     Reply with quote

Basic answer. No.
You have to duplicate he code yourself to do this. Stream ID' are also not
char strings, they are numbers (int16). Just use your own flag to select the
stream. So:
Code:

    //for your cases:
      case 1:
      case 3:
      case 4:
      case 5:
          send_pulse(i);
          break;
    //etc.

//Then your send_pulse code needs to select based on the number:
void send_pulse(int ID)
{
   switch (ID) {
   case 1:
      pwm_on(PWM1);
      break;
   case 3:
      pwm_on(PWM3);
      break;
   case 4:
      pwm_on(PWM4);
      break;
   case 5:
      pwm_on(PWM5);
      break;
   }
   delay_ms(1);
   switch (ID) {
   case 1:
      pwm_off(PWM1);
      break;
   case 3:
      pwm_off(PWM3);
      break;
   case 4:
      pwm_off(PWM4);
      break;
   case 5:
      pwm_off(PWM5);
      break;
   }
   delay_ms(1);
}


Stream ID's are _pre processor_ definitions. No ability to charge code
'on the fly' in the functions. Think about it, when you call a 'pwm_on'
command it is setting bits in different registers based on the ID passed.
It doesn't have a single function that tests the ID and then branches,
the compiler is selecting the registers involved at compile time.
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Mon Apr 18, 2022 4:11 am     Reply with quote

For something like this, I like to use the pre-processor if I have enough ROM though.
But save a lot of time duplicating a function and when changing something you have to change everywhere.

Code:
#include "18LF46K22.h"
#use delay(clock=16MHz)
#use pwm(PWM1, timer=2, frequency=125kHz, duty=50, pwm_off, stream=PWM1)
#use pwm(PWM3, timer=2, frequency=125kHz, duty=50, pwm_off, stream=PWM3)
#use pwm(PWM4, timer=4, frequency=38kHz, duty=50, pwm_off, stream=PWM4)
#use pwm(PWM5, timer=4, frequency=38kHz, duty=50, pwm_off, stream=PWM5)

#define send_pulse(PWM_id)\
{\
   pwm_on(##PWM_id);\
   delay_ms(1);\
   pwm_off(##PWM_id);\
   delay_ms(1);\
}

void main()
{
   unsigned int8 i;
//   char PWM_id[5];

   /* Select PWM pin to use */
   i = 3;          /* this value will be changed depending on program algorithm */
   
   switch (i)
   {
      case 1:
      send_pulse(PWM1);
      break;
     
      case 3:
      send_pulse(PWM3);
      break;
     
      case 4:
      send_pulse(PWM4);
      break;
     
      case 5:
      send_pulse(PWM5);     
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Mon Apr 18, 2022 9:53 am     Reply with quote

A very good suggestion.
The point is that instead of a 'function', you have a #define'd command,
with all it's macro expansion capabilities. So it creates the code lines
corresponding to the original 'function', with the correct substituted
text for the stream names.
It does cost 'space' in the final code, but given that the delays are
themselves small calls, not much, and makes the result very tidy. Smile
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Mon Apr 18, 2022 10:10 pm     Reply with quote

Thank you so much, Ttelmah and Alan. Really appreciate your helpful suggestions. Will keep both options in mind when developing similar programs.
kgng97ccs



Joined: 02 Apr 2022
Posts: 97

View user's profile Send private message

PostPosted: Mon Jun 20, 2022 2:41 am     Reply with quote

Is using pwm_off() or pwm_off([stream]) the same as setting the corresponding PWM pin to low? For example, is it the same as output_low(pin_C2), if the corresponding PWM pin is C2?
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Mon Jun 20, 2022 5:05 am     Reply with quote

No.
If you want to drive low, then set the duty cycle to 0.

The behaviour depends on the peripheral. It normally turns the peripheral
'off'. What happens to the output then is dependant on how the LAT
bit for the bit being used for the PWM is set, and how the TRIS is set
(and whether the chip uses PPS).
On chips without PPS, turning the peripheral off, sets the pin back to using
the bit programmed in the LAT bit. On these chips TRIS has to have been
set as output for the PWM to have been generated.
On chips with PPS, the assignment remains in force, so the peripheral
is still connected, so you would need to check in the data sheet whether
the peripheral being off is defined as low.
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