To close off this little “DIP into” series, let’s go into robotics briefly…
The LPC810 has quite a bit of hardware, including the usual USARTs, I2C, SPI, and timers. But the LPC8xx series (and others from NXP) also have a “State-Configurable Timer”.
The SCT is a curious mix of a timer, an event generator, and a state machine. It’s a rather complex beast, actually, and one of the things it can be made to do is PWM generation.
Since all the timers in the LPC8xx are 32-bit, there is a considerable range of pulse widths you can generate with it. Including, servo control pulses (image from Wikipedia):
Servos are very easy to hook up: two pins for power and ground, and one pin carrying the motor control setting, in the form of a pulse which nominally repeats every 20 ms.
The width of the pulse is interpreted by the servo as a position.
Setting this up in the SCT takes quite a bit of head-scratching, if you’re doing this by manipulating the raw hardware registers. The problem is that until all the settings are exactly right, nothing will happen. Then again, it’s a great exercise to learn about what this SCT is capable of, and the end result is quite impressive:
Up to 4 servo channels with sub-microsecond resolution, assignable to any pin!
Once set up to generate pulses 20 ms apart, adjusting servos couldn’t be any easier. Here is an example, activating just one of the pulse outputs and iterating between the two limits:
int main () {
LPC_SWM->PINASSIGN7 = 0xFFFF01FF; // connect CTOUT_2 to PIO0_1
pwmSetup();
SysTick_Config(12000000);
// change pulse widths on pin 5 once a second
while (true) {
__WFI();
LPC_SCT->MATCHREL[3].U = 1000 * SCT_MHZ;
__WFI();
LPC_SCT->MATCHREL[3].U = 1500 * SCT_MHZ;
__WFI();
LPC_SCT->MATCHREL[3].U = 2000 * SCT_MHZ;
__WFI();
LPC_SCT->MATCHREL[3].U = 1500 * SCT_MHZ;
}
}
All we need to do to change a pulse width, is to store a register value. The actual pulses are generated by the SCT hardware and consume no processor resources at all. As long as the SCT clock is kept running, it can keep up to 4 servos busy and moving around at will.
Here is a little setup to try this out:
This board was hand-wired, but it can be quite convenient for certain tasks because it has FTDI-compatible headers on both sides of the board – IN on one and OUT on the other:
Note that this board is not actually used as “FTDI pass-through” in this experiment – the servo is simply hooked up to 5V, ground, and one output pin. But the board is general enough to be used as such anyway, due to the LPC8xx’s “switch matrix” capability.
As usual, the motion demo code can be found on GitHub in the “embello” repository.
This code uses 632 bytes. That leaves over 3 KB flash to implement the actual robot smarts.
[Back to article index]