View Full Version : Setting up a PWM signal

10-29-2012, 10:49 PM
I would like to generate a >1MHz clock signal for an external LED driver chip to use for its PWM cycle. I've been doing this on another microcontroller by setting up a PWM pin with a 50% duty cycle to pulse on and off very quickly, which required access to the low-level registers. I've read this thread on interrupts (http://forum.pjrc.com/showthread.php?14-Teensy-3-0-and-interrupts&highlight=interrupt) so I'm pretty sure I can accomplish something similar here, but the datasheet is extremely daunting. If I could even be pointed in the right direction, that would be a great help.

The clock-generation is just a peripheral function the code would have to perform; the main loop would be tied up doing some other work, but the world outside it has to keep on ticking, hence the need for doing this outside the main loop without using interrupts.


10-30-2012, 06:40 AM
I'm considering adding a function to configure the PWM carrier frequency.

Maybe it should take an unsigned integer (32 bit) for the frequency? Or maybe it should take a number for the period? Whatever type of input, it seems best to use absolute units (as opposed to a divider that depends upon knowing the CPU or bus clock). But I'm not really decided on which way is best...

10-30-2012, 06:57 AM
I think a divider ratio based on the clock is OK, just as in Arduino the SPI clock is set as a divider ratio (although admittedly Arduinos don't usually change clock frequency at compile time.) Still, the programmer can't fully escape responsibility for knowing the system clock frequency. If you use absolute units, then some numbers become unreachable, depending on the clock setting.

On the other hand, for many purposes and in many situations, absolute units help code portability and readability, and if you need to use the extremes of the range you can still fall back on using direct registers.

10-30-2012, 07:23 PM
If you go with frequency, the PWM duty cycle would have to be parametrized as some sort of percentage. If you go with the period in time units, the duty cycle could be accepted as a pulse width in time units. I personally find the frequency domain more natural, but I'm happy with either so long as the parameter's data type doesn't preclude some valid range of values for the Teensy's hardware. This was a problem I previously had with the mbed, which had nice library functions for doing this but was limited to microsecond periods. To get into the sub-microsecond range you had to go get down and dirty with the registers and CPU frequency and dividers and all that.

I don't mind that, but assuming it is possible to drive the PWM signal much closer to the clock speed of the Teensy, I would love to do so with just a library function.

11-01-2012, 09:22 AM
It is not easy to solve any type of technical problem. PWM signals are sued in LCD TV. If you are facing problems in successfully installing the PWM then you can get help from iyogi one of the best companies in technical support.

iyogi (www.iyogi.com/iyogi.html)

11-01-2012, 06:38 PM
I believe you can do this using the timer hardware, but you'll need to directly manipulate the hardware registers. That also means reading the Flextimer chapter from the chip's reference manual, which is rather daunting. Here's my initial thoughts on how it might be done.

The FTM0 module has 8 compare registers, each associated with a pin. Normally those are controlled by analogWrite(). You might look at the analogWrite() code. The hardware can be configured in many different ways. The default is PWM. By default, the timer counts up and rolls back over to zero at some maximum value. If you can wait for your pulse to begin at the rollover, you could just use PWM mode. The registers are buffered, so if you write the PWM value in advance, it will take effect at the next rollover. The pin goes high at the rollover, than then goes low when the counter is equal to the compare register. To get just a single pulse, you'll need to respond after the compare but before the next rollover, to reconfigure the comparator to not keep creating more pulses. It's probably possible to do this with an interrupt.

The FTM0 also has a mode where 2 comparators can be chained together for a single pin. Then the pin can go high when the counter equals the first comparator and low when it equals the second. Using that approach, you could set the first just slightly past the current count, so the pulse begins very soon, and set the second one so it ends when you want. Again, you'll need to respond after the 2nd event so the pulse doesn't begin again when the counter rolls over and get back to whatever value you wrote to the 1st register.

At least that's the rough idea. Anything I've said here is trumped by whatever Freescale's reference manual says.

11-01-2012, 09:58 PM
Opps - meant to post this on another topic.

For the PWM frequency, I'm planning to add an option. It'll require a bit of coding work, because I'll do it together with the (currently missing) option to set the resolution. If the frequency is high, the resolution is low. I'm planning to scale the configured resolution to the actual resolution. Fortunately, the Cortex-M4 has a 2-cycle hardware divide, so this is pretty efficient.

If you want to play with this now, look in pins_teensy.c for _init_Teensyduino_internal_ You want this line:

FTM0_MOD = 32767;

Change the number to something smaller for a higher frequency PWM output.

11-05-2012, 12:24 PM
I'm considering adding a function to configure the PWM carrier frequency.

I just got my first 3.0 and ordered a couple more. Am in urgent need of two fixed PWM frequency settings on any two separate pins (20KHz and 32 KHz). What would be the easiest way to set it using the Teensyduino IDE ?

Thanks in advance.