|
|
View previous topic :: View next topic |
Author |
Message |
kgng97ccs
Joined: 02 Apr 2022 Posts: 97
|
Passing a PWM stream ID to a function |
Posted: Sun Apr 17, 2022 9:23 pm |
|
|
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: 19510
|
|
Posted: Mon Apr 18, 2022 12:53 am |
|
|
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
|
|
Posted: Mon Apr 18, 2022 4:11 am |
|
|
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: 19510
|
|
Posted: Mon Apr 18, 2022 9:53 am |
|
|
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. |
|
|
kgng97ccs
Joined: 02 Apr 2022 Posts: 97
|
|
Posted: Mon Apr 18, 2022 10:10 pm |
|
|
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
|
|
Posted: Mon Jun 20, 2022 2:41 am |
|
|
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: 19510
|
|
Posted: Mon Jun 20, 2022 5:05 am |
|
|
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. |
|
|
|
|
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
|