hardware PWM, set number of pulses
hardware PWM, set number of pulses
Hi all
Playing around with steppers. Is it possible to define how many pulses I would like a hardware PWM channel to output, rather than just being able to specify a rate and duty cycle?
I basically want to say, send x number of pulses at a rate of x hz with high times of 40us.
I can do this using external PWM coprocessor, but would rather just be able to handle this project on the zx if possible.
Cheers
Ben
Playing around with steppers. Is it possible to define how many pulses I would like a hardware PWM channel to output, rather than just being able to specify a rate and duty cycle?
I basically want to say, send x number of pulses at a rate of x hz with high times of 40us.
I can do this using external PWM coprocessor, but would rather just be able to handle this project on the zx if possible.
Cheers
Ben
Re: hardware PWM, set number of pulses
The PWM functions of the ZBasic Library do not have the ability to output a specified number of pulses.sturgessb wrote:Is it possible to define how many pulses I would like a hardware PWM channel to output [...]
You could, however, implement the PWM directly and add an interrupt handler that counts the number of match interrupts, terminating the PWM when the desired number of pulses has been issued. See Tony's PWM application note AN-216 for the details on how to set up PWM.
Other alternatives would be to use OutputCapture() or to bit-bang the pulse stream while watching a timer to regulate the timing.
Last edited by dkinzer on 02 December 2013, 10:25 AM, edited 1 time in total.
- Don Kinzer
Unfortunately, you can't configure for rising edges only. You'll have to configure for both edges and then ignore the falling edge.sturgessb wrote:[W]hat would be the correct register settings to enable rising edge interrupts for PORTE_INT1 (pin 17)
On the xmega, the ISC[2:0] bits of the PINxCTRL register of each port (where X is {0-7}) controls the edge/level configuration. The INTCTRL register of each port, in conjunction with the INTnMASK register, controls which pins can generate an interrupt.
- Don Kinzer
It just occurred to me that one could use the "repeat count" of OutputCaptureEx() to generate a given number of pulses on any pin. In the example code below, the active/inactive time is hard-coded as 10uS and 90uS but one could pass parameters for that, too.
Code: Select all
Const pin as Byte = 14
Const pulseState as Byte = 1
Sub Main()
' initialize the pin to the "idle" state
Call PutPin(pin, (Not pulseState) And 1)
' emit some pulses
Call outputPulses(pin, pulseState, 5)
End Sub
'
'' outputPulses
'
' Output a number of pulses on a pin, assumed to be in the "idle" state.
'
Sub outputPulses(ByVal outPin as Byte, ByVal cnt as UnsignedInteger)
' initialize the OutputCapture() data for the desired pulse times
Dim data(1 to 2) as UnsignedInteger
data(1) = 147 ' about 10uS
data(2) = 13271 ' about 90uS
' emit the pulses
Call OutputCaptureEx(outPin, data, 2, (Not GetPin(outPin)) And 1, cnt)
End Sub
- Don Kinzer
Thanks again Don, that works, but I think I'm gonna try and push forwards with the interrupt method as it means I can modify the target step amount on the fly and stop when required. The output capture method would mean I could only fire and forget movement commands.
Looking at the docs now, will shout if I get stuck (most likely!)
Looking at the docs now, will shout if I get stuck (most likely!)
So far I have
To select Int1, but I'm really not sure what the value for Register.PORTE_INT1MASK should be for E.1 pin
I thought it would just be zx00000001 to enable INT1, but that doesn't seem to work.
Sorry, but any pointers? Thanks
Code: Select all
Register.PORTE_INTCTRL = zx00000010
I thought it would just be zx00000001 to enable INT1, but that doesn't seem to work.
Sorry, but any pointers? Thanks
Ah, this is correct I think…
well, it seems to doing what i want anyway!
Code: Select all
Register.PORTE_PIN1CTRL = zx00000001
Register.PORTE_INTCTRL = zx00000110
Register.PORTE_INT1MASK = zx00000010