How to Generate a Pulse Train Output using the timers.
Frequency generator using mbed
This is a tutorial on how to generate a square wave pulse train output (PTO)
Being able to generate a pulse train it is something that can result quite useful in some situations, for example to drive a stepper motor. So this article will show how to setup mbed in order to drive a stepper motor.
There are three aspects to this setup:
- The timers, how to configure them
- The circuit, how to drive the motor
- The program, how to control the motor
The Timers
There are four times/counters, one of them, timer three, is used internally by the libraries of mbed, this timer is used whenever you use a wait() function, anad a Ticker or Timer object as well. So it is very much recommended not to mess around with timer three unless you are absolutely sure you know what you're doing, take into account that even if you don't use this functions, any included library may be using them.
There are many ways to generate a pulse train, one of them could be with a ticker object and toggle a pin on every interruption, but if you need high frequencies, and for a PTO (Pulse Train Output) you often do, then this interruptions are not the best way to solve this problem. There is one feature the timers have to solve our need for a PTO and that is the External Match Output.
Information
You will need the datasheet
And this one is very usefull to find pins on LPC1768, thanks Chistian!
Each timer has four Match Registers, each one with different capabilities so that when the timer counter matches these registers the output can either, toggle, go low, go high or do nothing.. The External Match Register controls the External Match pins MATn.m, where 'n' represents a timer and 'm' represents a Match register. For this tutorial we will be using Timer2, so we need to locate pins corresponding to MAT2.0-3, this pins will be driven from the Timer2 Match Registers to toggle and reset the timer. This will generate a constant pulse train on those pins without generating interrupts.
First we need to locate those pins, and set them to MAT functionality. These pins are located on PINSEL0, we are only going to use two pins and those will be MAT2.2 and MAT2.3 which correspond to [p6] and [p5 ] of mbed's pinout, normally those pins have SPI functionality so we need to change that to use them as we want. So we need to write to PILSEL0 register.
LPC_PINCON->PINSEL0 |= 15UL << 16;
Information
If you understand the line of code you may want to skip this part, if you're new to programming microcontrollers this will be useful:
15UL in binary means ...00001111 15UL << 16 means move 16 spaces to the left, or another way to see it is insert 16 zeros after the least significant bit, either way you see it the result is: 00000000000011110000000000000000 in a 32bit processor, (this is called the mask) |= Next we have this, which is a compound assignations and means, whichever value the left hand side has, perform a bit OR operation with the right side and save it to the same location in memory. And if you know your binary operations, you know the result will be like this: 0101101 OR 0011000 --------- 0111101
So, no matter what value the register used to have at those bits, they are now logic one, but the other bits that your not interested in have not been altered. This works if you wanted to write a logic one in some specific bits of registers, but if you want to clear them you need to use another kind of logic which goes like this:
LPC_PINCON->PINSEL0 &= ~ (15UL << 16);
Which inverts the mask (~) , from 00011000 to 11100111 and performs the AND operation on those bits, effectively erasing only those bits. Sometimes when you begin in programming and have a high level micro, like mbed, you don usually know how this logic works.
Now we have the correct MAT2.2-3 pins, so lets configure the External Match Register [EMR] to toggle those pins:
LPC_TIM2->EMR |= 15UL << 8; // Again a single line to toggle two pins
Now the Match Registers [MR] because we are using MAT2.2 and MAT2.3 we also need to use MR2 and MR3 from the Timer2 register, and because our example is about a stepper motor we need to create a 90° phase between the two outputs, (this will be explained in a moment) the match registers will be set to:
uint32_t period = ( SystemCoreClock / 400 ); LPC_TIM2->MR2 = period; LPC_TIM2->MR3 = period * 2; // times two because of the
In this example we will control the frequency output using the prescaler, higher prescaler lower frequency, lower prescaler higher frequecy.
Finally we need to set the Timer2 to reset at the end of MR3 because we don't want it to go all the way to the end [2^32 – 1] before it is ready to generate another toggle. This line of code will take care of that, read the datasheet to see why.
LPC_TIM2->MCR |= 1 << 10; // Reset on MR3.
The Circuit
I don't want to spend to much time on this, so briefly, I'm using a bipolar motor with a L293D driver, normally you need four outputs but you can get rid of two by inverting them, this means of these four outputs two will always be the inverse of the other two. So I use two transistor to invert the signals fed into the L293D driver. And for driving this motor, I need those two pulses to be 90° out of phase, like in a encoder, and depending on which pulse is leading you have a different direction for the motor.
Warning
Here's is an idea how it should look like BUT THE PINS ARE MIXED UP, because I made this to test my driver configuration and some PWM to vary intensity, still should give you an idea on how this works
The control
So for the purposes of demonstrating this concept I have created a LabVIEW virtual instrument (VI) to control the Prescaler value (speed) and the phase between the two pulses (direction).
Import programCD_Rom
This is a program to drive a stepper servomotor from SerialUSB without any other interrution but the serial one.
This is a demonstration of this project, It is in spanish but I believe you'll have no problem understanding how it works, but if not leave a comment and I'll explain it better.
There is also another project I'm working on, it's about an AC Servo motor, very similar to what I've explained here, but with a little twist, check It out.
This one has subtitles [CC]
2 comments on How to Generate a Pulse Train Output using the timers.:
Please log in to post comments.
I have waited a long time using my mbed, because I could not get my hands on the timers/counters.
I want to be able to give 1 or more stepper motor(s) the 'right step at the right time'.
Your example is a good starting point. Thank you very much!