|
|
View previous topic :: View next topic |
Author |
Message |
Woody
Joined: 11 Sep 2003 Posts: 83 Location: Warmenhuizen - NL
|
PWM and PIC18F55Q43 |
Posted: Thu Apr 29, 2021 4:05 am |
|
|
Hi,
The continuous joys of using a relatively new piece of hardware
Let me start with the good news: I have PWM running on this chip. Four outputs producing different PWM signals to control the current through 4 different IR leds. The bad news however is that I am still not completely confident in how this works. And I hate that.
I can't find much info on this particular chip over here, so hence this (I hope) start of a discussion to get some more data on these 'new' PWM peripherals.
AFAIK from the DS the 18F55Q43 has 3 individual PWM units. Every unit has 1 'slice' and every slice has 2 outputs, making for a total of 6 outputs. Things like frequency are set for a unit (pwm1..pwm3), justification is selected for a slice and duty cycle is set per output.
Relevant code:
Code: |
#use delay(clock=18432000,clock_out)
#define PWM_PERIOD 0x400 // This makes for a ~18kHz pwm signal
// Setup PWM output pins
#pin_select PWM1S1P1=PIN_C0
#pin_select PWM1S1P2=PIN_C1
#pin_select PWM2S1P1=PIN_D0
#pin_select PWM2S1P2=PIN_D1
// Setup 4 PWM outputs, 2x PWM module, 1 slice per module, 2 outputs per slice
setup_pwm1 ( PWM_ENABLED | PWM_CLK_FOSC , PWM_PERIOD, 1 );
setup_pwm1_slice( 1, PWM_STANDARD );
setup_pwm2 ( PWM_ENABLED | PWM_CLK_FOSC , PWM_PERIOD, 1 );
setup_pwm2_slice( 1, PWM_STANDARD );
// Output the PWM signal, where l_sensor_data_words is an int16 array containing 4 values between 0 - 3ff
set_pwm1_duty(1,l_sensor_data.words[0],l_sensor_data.words[1]);
set_pwm2_duty(1,l_sensor_data.words[2],l_sensor_data.words[3]);
|
This works. I understand that the 18432000 clock divided by the 0x400 period value gives me the 18kHz pwm signal I measure at the outputs. I do not completely understand why that gives me a 400 count pwm signal. And, if I would like that signal to be 12kHz with the same 'count', how I would achieve that. The calculator at http://micro.alleypress.org/ does not seem to have the right options for the 18F55Q43.
And how do I set only one output in a slice? AFAICS when I use set_pwmx_duty() I always need to set both outputs together. I would expect to be able to set only one output and leave the other alone.
Anyway, as my favorite compiler is no big help here (sketchy info how to use slices, outputs etc) I am open to all comments. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Thu Apr 29, 2021 7:23 am |
|
|
There are actually six PWM's available, not just three.
There are 3 16bit PWM's which are as you describe. But there are also
three CCP modules which can also be programmed to produce PWM
outputs. These though use the timers for their clocks (just like the
normal PWM on most other chips), and only give 10bit available resolution
versus the 16bit on the modules you are using.
Yes, the CCS functions do have to program both duties at once, but if you
are only using one slice just leave as zero. If you look at these registers
they are marked 'DMA access only'. It doesn't appear that they are available
in the standard memory map!...
Thing that is not made at all clear is the PWM numbering used. CCS, seem
to have 'forgotten' that they also need duty settings potentially for both the
CCP PWM's and the 16bit PWM's....
I'd actually contact CCS, pointing this out, and asking for an example
using both the CCP PWM's and the 16bit PWM's.
The issue here is that this is not just a new chip, but it carries a very
large number of previously unimplemented peripherals. So where CCS
can add a standard peripheral they have done so, but they have not yet
actually written the code to handle some of the new parts.
You really need to talk to them. |
|
|
Woody
Joined: 11 Sep 2003 Posts: 83 Location: Warmenhuizen - NL
|
|
Posted: Fri Apr 30, 2021 3:20 am |
|
|
Wow, I managed to completely miss the CCP-with-PWM possibility. That can come in handy as I might need 8 PWMs somewhere along the line. Thanks for pointing this out.
In my application I have pwm outputs all the time, only every now and then I need to adjust one of the outputs. I cannot let the other output on a slice be 0 so that forces me to write both outputs if only one changes. Not a showstopper in any way but to me it would be more logical if I could only write one output at a time.
I contacted CCS a fortnight ago about a PWM example. They sent me one using the pwm peripheral on this chip but I have to admit that the code was a bit beyond my working C. Lots of uint32_t, cTicks and what not.
I am basically just an assembler guy using C for readability and by then had my own solution working and was very busy with the rest of the code so I have not yet tested and toyed with their example.
Anyway, I agree that CCS needs contacting but (as was the case with my earlier I2C hassle) I first have to formulate sensible questions. In the meantime I use what I have and hope the next compiler update will solve some of these issues.
Paul |
|
|
|
|
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
|