>Can the cycletime be different for each channel of hardware PWM or
will the last value that was entered be used for all the channels?
Does the processor have 6 independent PWM channels (ie six
Capture/compare channels)
The HWPWM is now implemented using a #include file. For simplicity
the same cycle time is used for all channels, and is set to the last
cycle time programmed. This is not a requirement of the hardware.
The timer/counter hardware in the LPC2103 can do some quite complex
functions. That hardware actually has 16 timer/counter/compare
channels, which can be programmed to interact in various ways.
Details of this hardware are available in the LPC2103 user manual
(linked from the ARMbasic help files)
http://www.nxp.com/acrobat_download/use ... 0161_1.pdf
You can use HWPWM.bas as an example how to program these channels.
HWPWM with different cycle times
Re: HWPWM with different cycle times
In the "C-Tools", I notice that the HWPWM function is set up to use a
single cycle time between all of the HWPWM channels. I was wondering
if it is possible to have 2 different cycle times? I need to set up
one HWPWM channel to one frequency (cycle time) and all the others to
another frequency while still being able to set the duty cycle (high
time) independently on all. Thanks in advance for your help.
RB
single cycle time between all of the HWPWM channels. I was wondering
if it is possible to have 2 different cycle times? I need to set up
one HWPWM channel to one frequency (cycle time) and all the others to
another frequency while still being able to set the duty cycle (high
time) independently on all. Thanks in advance for your help.
RB
Re: HWPWM with different cycle times
This is possible, but you will need to program the timer/match
registers differently. Though sketchy the details of those registers
is in the User Manual from NXP (link in the Help Files-> CPU details)
registers differently. Though sketchy the details of those registers
is in the User Manual from NXP (link in the Help Files-> CPU details)
Re: HWPWM with different cycle times
Here is some code that I grunted out.
I have checked the outcome for consistency with my digital o-scope.
In short, the code can output simultaneous PWN pulse trains from pins 3 and 5
while changing the cycletimes on the fly (I just used some DO loops).
I have noticed that only pins 3 and 5 work for this. If you add another PWM
channel all goes to poop.
That said, the code below has one other idiosyncrasy : The pulses are always
mis-aligned by about 10.5usec. No big deal for me, as I am driving steppers.
Close enough...You might not be so lucky.
If anyone has any input on exactly why this worked please enlighten me. I just
kept banging on the problem till something finally submitted.
Thanks,
John
Here's the code.
'//////////////////////////////////////////
#include <HWPWM.bas>
'DUAL_CYCLETIME_HWPWM.bas
CONST pin3 = 3
CONST pin5 = 1
DIM cycletime3 AS INTEGER '<== in usec
DIM cycletime5 AS INTEGER
DIM pulsewidth AS INTEGER '<== in usec
DIM a AS INTEGER
DIM loopcount AS INTEGER
a = 0
loopcount = 0
pulsewidth =10
cycletime3 =50
cycletime5 =100
DO
LOW a
a = a+1
LOOP UNTIL a > 16
DO
HWPWM (pin3,(1+loopcount)*cycletime3,pulsewidth)
HWPWM (pin5,cycletime5,pulsewidth)
loopcount = loopcount+1
WAIT(100)
LOOP UNTIL loopcount > 9
HWPWM (pin3,-1,0)
HWPWM (pin5,-1,0)
IO(pin3)= 0
IO(pin5)= 0
WAIT 100
a = 0
loopcount = 0
cycletime3 =100
cycletime5 =50
DO
LOW a
a = a+1
LOOP UNTIL a > 16
DO
HWPWM (pin3,cycletime3,pulsewidth)
HWPWM (pin5,(1+loopcount)*cycletime5,pulsewidth)
loopcount = loopcount+1
WAIT(100)
LOOP UNTIL loopcount > 9
HWPWM (pin3,-1,0)
HWPWM (pin5,-1,0)
IO(pin3)= 0
IO(pin5)= 0
I have checked the outcome for consistency with my digital o-scope.
In short, the code can output simultaneous PWN pulse trains from pins 3 and 5
while changing the cycletimes on the fly (I just used some DO loops).
I have noticed that only pins 3 and 5 work for this. If you add another PWM
channel all goes to poop.
That said, the code below has one other idiosyncrasy : The pulses are always
mis-aligned by about 10.5usec. No big deal for me, as I am driving steppers.
Close enough...You might not be so lucky.
If anyone has any input on exactly why this worked please enlighten me. I just
kept banging on the problem till something finally submitted.
Thanks,
John
Here's the code.
'//////////////////////////////////////////
#include <HWPWM.bas>
'DUAL_CYCLETIME_HWPWM.bas
CONST pin3 = 3
CONST pin5 = 1
DIM cycletime3 AS INTEGER '<== in usec
DIM cycletime5 AS INTEGER
DIM pulsewidth AS INTEGER '<== in usec
DIM a AS INTEGER
DIM loopcount AS INTEGER
a = 0
loopcount = 0
pulsewidth =10
cycletime3 =50
cycletime5 =100
DO
LOW a
a = a+1
LOOP UNTIL a > 16
DO
HWPWM (pin3,(1+loopcount)*cycletime3,pulsewidth)
HWPWM (pin5,cycletime5,pulsewidth)
loopcount = loopcount+1
WAIT(100)
LOOP UNTIL loopcount > 9
HWPWM (pin3,-1,0)
HWPWM (pin5,-1,0)
IO(pin3)= 0
IO(pin5)= 0
WAIT 100
a = 0
loopcount = 0
cycletime3 =100
cycletime5 =50
DO
LOW a
a = a+1
LOOP UNTIL a > 16
DO
HWPWM (pin3,cycletime3,pulsewidth)
HWPWM (pin5,(1+loopcount)*cycletime5,pulsewidth)
loopcount = loopcount+1
WAIT(100)
LOOP UNTIL loopcount > 9
HWPWM (pin3,-1,0)
HWPWM (pin5,-1,0)
IO(pin3)= 0
IO(pin5)= 0
Re: HWPWM with different cycle times
> In short, the code can output simultaneous PWN pulse trains from pins 3 and 5
while changing the cycletimes on the fly (I just used some DO loops).
>
> I have noticed that only pins 3 and 5 work for this. If you add another PWM
channel all goes to poop.
> ...
> If anyone has any input on exactly why this worked please enlighten >me. I
just kept banging on the problem till something finally >submitted.
No its not a deep dark mystery. You could take a peak at the actual library
that is called HWPWM.bas, which is in the /Program Files/Coridium/BASIClib
directory.
One of the main motivations to move these routines out of firmware (where they
use to be in version 6) to BASIC was to allow people to change them.
The version we provide does set all cycletimes for PWM to be the same. But as
you discovered there is more flexability there.
If you look in the code, PWM channels 5,7 and 8 use TIMER1. Channels 1 and 6
use TIMER2 and channels 2,3 and 4 use TIMER3.
So you really could set 3 independent cycle times, for each of the 3 groups of
PWM channels. Rather than figuring out how to call HWPWM, just take the
existing code and start hacking. Use the same startup to initialize channels,
probably also program all the PCB_PINSEL registers. But then generate routines
like
HWMPWINIT()
HWPWM16(cycletime, hightime1, hightime6)
HWPWM234(cycletime, hightime2, hightime3, hightime4) ...
Details on what those registers are doing can be found in the LPC2103 User
Manual (at NXP or linked from our help files Hardware->CPU section).
As they use to tell me, the rest is an exercise for the reader.
while changing the cycletimes on the fly (I just used some DO loops).
>
> I have noticed that only pins 3 and 5 work for this. If you add another PWM
channel all goes to poop.
> ...
> If anyone has any input on exactly why this worked please enlighten >me. I
just kept banging on the problem till something finally >submitted.
No its not a deep dark mystery. You could take a peak at the actual library
that is called HWPWM.bas, which is in the /Program Files/Coridium/BASIClib
directory.
One of the main motivations to move these routines out of firmware (where they
use to be in version 6) to BASIC was to allow people to change them.
The version we provide does set all cycletimes for PWM to be the same. But as
you discovered there is more flexability there.
If you look in the code, PWM channels 5,7 and 8 use TIMER1. Channels 1 and 6
use TIMER2 and channels 2,3 and 4 use TIMER3.
So you really could set 3 independent cycle times, for each of the 3 groups of
PWM channels. Rather than figuring out how to call HWPWM, just take the
existing code and start hacking. Use the same startup to initialize channels,
probably also program all the PCB_PINSEL registers. But then generate routines
like
HWMPWINIT()
HWPWM16(cycletime, hightime1, hightime6)
HWPWM234(cycletime, hightime2, hightime3, hightime4) ...
Details on what those registers are doing can be found in the LPC2103 User
Manual (at NXP or linked from our help files Hardware->CPU section).
As they use to tell me, the rest is an exercise for the reader.
-
- Posts: 1462
- Joined: Fri Oct 19, 2012 5:11 am
Re: HWPWM with different cycle times
Below is a little basic program that proves one can get three distinct and
different cycletime PWM signals emitted from an ARMexpress LITE, and that said
three PWM signals can be controlled on-the-fly as it were.
All calls to HWPWM are using the stock HWPWM.bas subroutine provided by
Coridium.
Hope this helps someone. Seem like this should have been pointed out in the docs
but what the hey.
Comments are in the code.
John
'/////////////////////////////////////////////////
'BAX_MULTIPLE_CYCLETIMES.bas
#include <HWPWM.bas>
'I grunted this out, but it works.
'I am not an expert. I am a beginner.
'I do know this code demonstrates that the ARMexpress LITE
'can indeed emit three seprate pulse trains simultaneously
'from three pins, all with different cycletimes.
'Further, this code proves that any or all of the
'three PWM signals can have unique or the same cycletimes as you wish.
'On an o-scope I have verified that the PWM square-wave signals
'are emitted within a consistent betwen-pin signal time error of
'10 microseconds.
'For stepper motor control this is effectively true simultaneity
'of control signal for all three steppers. Sweet.
DIM cycletimeTEST AS INTEGER
DIM pulsewidth AS INTEGER '<== in usec
DIM loopcount AS INTEGER
'All pins set to be output pins at low level (zero).
'We want this because the HWPWM call makes positive
'pulse square-wave PWM signals and we want a low level
'at each pin before we emit the first HWPWM signal.
loopcount = 0
DO
IO(loopcount) = 0
loopcount = loopcount+1
LOOP UNTIL loopcount = 15
'Below is the beef: 3 separate HWPWM calls, each with a
'unique cycle time that also changes on-the-fly
'according to the program. This implies a great many
'opportunities for active control of three simultaneous
'stepper motors.
'!!!BIG NOTE!!! THE ORDER YOU CALL THE CHANNELS MATTERS!
'Calling channels 7,3,1 or 8,3,1 in that exact order will
'produce 3 separate and distinct pulse trains, each capable
'of emitting a pulse train of unique or same cycletime.
'By the way. They mean it when they say channels 4 and 6
'are NOT available in an ARMexpress LITE. This is not because
'no pule trains are emitted, just none you want.
'Choose ARMexpress LITE channels 7,3, and 1 in that exact order
'and you should see the results on pins 13, 3, and 5 respectively.
pulsewidth =100
cycletimeTEST = 500
loopcount = 0
DO
HWPWM (7,cycletimeTEST*(1+loopcount),pulsewidth)
HWPWM (3,cycletimeTEST,pulsewidth)
HWPWM (1,cycletimeTEST*((1+loopcount)*3),pulsewidth)
loopcount = loopcount+1
WAIT(100)
LOOP UNTIL loopcount > 9
'Reset the HWPWM channels so that they are now set to be
'regular digital IO pins.
'Essentially turns off the HWPWM and cuts off the pulse trains
'on all 3 pins. Channels 2, 5, and 8 are also rest in no
'particular order. Just being retentive here. I may be wrong.
HWPWM (7,-1,0)
HWPWM (3,-1,0)
HWPWM (1,-1,0)
HWPWM (2,-1,0)
HWPWM (5,-1,0)
HWPWM (8,-1,0)
'All pins set low as I end the pulse trains.
'(Preps the pins low for future pulse trains.)
loopcount = 0
DO
IO(loopcount) = 0
loopcount = loopcount+1
LOOP UNTIL loopcount = 15
different cycletime PWM signals emitted from an ARMexpress LITE, and that said
three PWM signals can be controlled on-the-fly as it were.
All calls to HWPWM are using the stock HWPWM.bas subroutine provided by
Coridium.
Hope this helps someone. Seem like this should have been pointed out in the docs
but what the hey.
Comments are in the code.
John
'/////////////////////////////////////////////////
'BAX_MULTIPLE_CYCLETIMES.bas
#include <HWPWM.bas>
'I grunted this out, but it works.
'I am not an expert. I am a beginner.
'I do know this code demonstrates that the ARMexpress LITE
'can indeed emit three seprate pulse trains simultaneously
'from three pins, all with different cycletimes.
'Further, this code proves that any or all of the
'three PWM signals can have unique or the same cycletimes as you wish.
'On an o-scope I have verified that the PWM square-wave signals
'are emitted within a consistent betwen-pin signal time error of
'10 microseconds.
'For stepper motor control this is effectively true simultaneity
'of control signal for all three steppers. Sweet.
DIM cycletimeTEST AS INTEGER
DIM pulsewidth AS INTEGER '<== in usec
DIM loopcount AS INTEGER
'All pins set to be output pins at low level (zero).
'We want this because the HWPWM call makes positive
'pulse square-wave PWM signals and we want a low level
'at each pin before we emit the first HWPWM signal.
loopcount = 0
DO
IO(loopcount) = 0
loopcount = loopcount+1
LOOP UNTIL loopcount = 15
'Below is the beef: 3 separate HWPWM calls, each with a
'unique cycle time that also changes on-the-fly
'according to the program. This implies a great many
'opportunities for active control of three simultaneous
'stepper motors.
'!!!BIG NOTE!!! THE ORDER YOU CALL THE CHANNELS MATTERS!
'Calling channels 7,3,1 or 8,3,1 in that exact order will
'produce 3 separate and distinct pulse trains, each capable
'of emitting a pulse train of unique or same cycletime.
'By the way. They mean it when they say channels 4 and 6
'are NOT available in an ARMexpress LITE. This is not because
'no pule trains are emitted, just none you want.
'Choose ARMexpress LITE channels 7,3, and 1 in that exact order
'and you should see the results on pins 13, 3, and 5 respectively.
pulsewidth =100
cycletimeTEST = 500
loopcount = 0
DO
HWPWM (7,cycletimeTEST*(1+loopcount),pulsewidth)
HWPWM (3,cycletimeTEST,pulsewidth)
HWPWM (1,cycletimeTEST*((1+loopcount)*3),pulsewidth)
loopcount = loopcount+1
WAIT(100)
LOOP UNTIL loopcount > 9
'Reset the HWPWM channels so that they are now set to be
'regular digital IO pins.
'Essentially turns off the HWPWM and cuts off the pulse trains
'on all 3 pins. Channels 2, 5, and 8 are also rest in no
'particular order. Just being retentive here. I may be wrong.
HWPWM (7,-1,0)
HWPWM (3,-1,0)
HWPWM (1,-1,0)
HWPWM (2,-1,0)
HWPWM (5,-1,0)
HWPWM (8,-1,0)
'All pins set low as I end the pulse trains.
'(Preps the pins low for future pulse trains.)
loopcount = 0
DO
IO(loopcount) = 0
loopcount = loopcount+1
LOOP UNTIL loopcount = 15
-
- Posts: 1462
- Joined: Fri Oct 19, 2012 5:11 am
Re: HWPWM with different cycle times
Actually I was suggesting that you change the HWPWM.bas to allow for 3 different
cycle times. Last I checked they weren't handed to us on stone tablets, but I
might be wrong
Anyway I've posted a new version of HWPWM.bas in the files section, that you
should use by
#define CYCLETIMES_DIFFER ' use this for 3 seperate cycletimes
#include <HWPWM.bas>
then call
HWPWM126(cycletime1, high1, high2, high6)
HWPWM578(cycletime2, high5, high7, high8)
HWPWM34 (cycletime3, high3, high4)
WARNING -- WARNING -- WARNING
This code compiles, but it is otherwise untested
Let me know if it works
Also feel FREE to modify the calling procedure, as changing any high time will
reset the other channels too. As one size never fits all, thats why we wrote
these in BASIC rather than have them in the firmware.
cycle times. Last I checked they weren't handed to us on stone tablets, but I
might be wrong

Anyway I've posted a new version of HWPWM.bas in the files section, that you
should use by
#define CYCLETIMES_DIFFER ' use this for 3 seperate cycletimes
#include <HWPWM.bas>
then call
HWPWM126(cycletime1, high1, high2, high6)
HWPWM578(cycletime2, high5, high7, high8)
HWPWM34 (cycletime3, high3, high4)
WARNING -- WARNING -- WARNING
This code compiles, but it is otherwise untested
Let me know if it works
Also feel FREE to modify the calling procedure, as changing any high time will
reset the other channels too. As one size never fits all, thats why we wrote
these in BASIC rather than have them in the firmware.
-
- Posts: 1462
- Joined: Fri Oct 19, 2012 5:11 am
Re: HWPWM with different cycle times
Here is a ZIP that contains an iconic HTML web doc. Just keep everything in the
folders as is and it should work.
It explains everything regarding the problem I had with my ARMexpress LITE, and
seem to have solved.
You might find it interesting.
Anyway, it is what I was trying to ask, and I also include the manual errors you
asked me to elaborate on.
folders as is and it should work.
It explains everything regarding the problem I had with my ARMexpress LITE, and
seem to have solved.
You might find it interesting.
Anyway, it is what I was trying to ask, and I also include the manual errors you
asked me to elaborate on.
-
- Posts: 1462
- Joined: Fri Oct 19, 2012 5:11 am
Re: HWPWM with different cycle times
Your attachment didn't make it into the group, you can post it in the files
section (though it didn't link well as a zip). A couple comments
The LPC2103 User Manual does define T1_TCR, but it has been written in a
different style than the LPC2106 manual. You'll find it by searching for TCR or
the hex address as E000 8004, where before it was listed as E0008004. These
manuals come from NXP, and they have a hard enough time keeping them accurate,
we're not going to re-edit them and introduce more errors.
In your program examples, you are putting the HWPWM inside a DO LOOP. This is
not how they are really intended to be used, and could cause problems as you're
continuously changing values. The real advantage of HWPWM, is that once you
program it, it will continue to put out the PWM pulse train until you need to
change it. You don't need to call it over and over again, which is what you
need to do with the bit-banged PWM routine.
To turn off the pulse train, you can set the high time to 0, or you can
reprogram the pin function in the PCB_PINSEL register. The IO pins can be
programmed for up to 4 functions, and you can change it from a MR (match
register) back to a straight IO.
section (though it didn't link well as a zip). A couple comments
The LPC2103 User Manual does define T1_TCR, but it has been written in a
different style than the LPC2106 manual. You'll find it by searching for TCR or
the hex address as E000 8004, where before it was listed as E0008004. These
manuals come from NXP, and they have a hard enough time keeping them accurate,
we're not going to re-edit them and introduce more errors.
In your program examples, you are putting the HWPWM inside a DO LOOP. This is
not how they are really intended to be used, and could cause problems as you're
continuously changing values. The real advantage of HWPWM, is that once you
program it, it will continue to put out the PWM pulse train until you need to
change it. You don't need to call it over and over again, which is what you
need to do with the bit-banged PWM routine.
To turn off the pulse train, you can set the high time to 0, or you can
reprogram the pin function in the PCB_PINSEL register. The IO pins can be
programmed for up to 4 functions, and you can change it from a MR (match
register) back to a straight IO.
-
- Posts: 1462
- Joined: Fri Oct 19, 2012 5:11 am
Re: HWPWM with different cycle times
1. Setup a Loop Running a Freq Output from 5-440Hz Specified by a Serial input
variable.
2. Inside the Loop Check for Data at the USB Serial Port
3. If Data is Present, Read it Immediately
4. If it is a Signal to Trip an External Device, Trip the External Device, By
Pulling a PIN Low for 50ms.
5. If it is a Frequency Update, Change the Frequency of a Square Wave that is
Generated wihin the Loop
6. Loop Generating the specified Frequency until the Next Byte is available at
the USB Input.
7. The generated frequency is to emulate rotary encoder for Shaft speed.
I have the serial input and variable change functions written. I have been
trying to output to HWPWM at the frequency. But even though the variables are
changing, I can see no difference in the output voltage using a digital
voltmeter.
Am I missing something about how to measure the change.
Below is the entire program:
#include <HWPWM.BAS>
Dim I as Integer
Dim OFreq as Integer
Dim ITVL as Integer
Dim A$(40) as String
I=1
Do
debugin A$
IF A$="TRIP" THEN
'It's a Trip Signal Toggle the LED
I=I+1
io(15)=I and 1
WAIT(50)
I=I+1
io(15)=I and 1
ELSE
'It's a New Frequency Read it and change the
'output Frequency
OFreq=Val(A$)
ITVL=OFreq/2
HWPWM (1,OFreq,20)
END IF
print OFreq,50,A$
A$=""
Loop
Thanks for any help,
Darin
variable.
2. Inside the Loop Check for Data at the USB Serial Port
3. If Data is Present, Read it Immediately
4. If it is a Signal to Trip an External Device, Trip the External Device, By
Pulling a PIN Low for 50ms.
5. If it is a Frequency Update, Change the Frequency of a Square Wave that is
Generated wihin the Loop
6. Loop Generating the specified Frequency until the Next Byte is available at
the USB Input.
7. The generated frequency is to emulate rotary encoder for Shaft speed.
I have the serial input and variable change functions written. I have been
trying to output to HWPWM at the frequency. But even though the variables are
changing, I can see no difference in the output voltage using a digital
voltmeter.
Am I missing something about how to measure the change.
Below is the entire program:
#include <HWPWM.BAS>
Dim I as Integer
Dim OFreq as Integer
Dim ITVL as Integer
Dim A$(40) as String
I=1
Do
debugin A$
IF A$="TRIP" THEN
'It's a Trip Signal Toggle the LED
I=I+1
io(15)=I and 1
WAIT(50)
I=I+1
io(15)=I and 1
ELSE
'It's a New Frequency Read it and change the
'output Frequency
OFreq=Val(A$)
ITVL=OFreq/2
HWPWM (1,OFreq,20)
END IF
print OFreq,50,A$
A$=""
Loop
Thanks for any help,
Darin