The goal: to “randomly” flash the on-board LEDs at P1.0 and P1.6
The weapons: CCS, Launchpad, Cookies (you may choose your favourite ones)
The reason: To familiarize yourself with the coding environment, or just for the heck of it.
The library:
#ifndef GRAND_H_
#define GRAND_H_
static unsigned long int rand_next = 1;
int gRand( void ) {
rand_next = rand_next * 1103515245 + 12345;
return (unsigned int)(rand_next/65536) % 32768;
}
void gSRand( unsigned int seed ) {
rand_next = seed;
}
#define gRandom() ((gRand() & 0x7fff) / ((float)0x7fff)) // random in the range [0, 1]
#define gCRandom() (2.0 * (gRandom() - 0.5)) // random in the range [-1, 1]
#define gMax(x,y) (x > y ? x : y) // minimum
#define gMin(x,y) (x < y ? x : y) // maximum
#endif /*GRAND_H_*/
That’s our random library, it’s grand.h
The “g” prefix is one I often use privately, it’s simply the first letter of my name. However because there may be other routines in the future with a similar naming convention, having “g” prefixed is not a bad idea; without having to fall into namespace gibberish.
The PRNG is an old standard. No need to discuss it.
You may recognize those macros, yes! They’re from Quake3! — Although we aren’t using them I left them there for future reference on how to obtain usable value ranges from the PRNG. There’s a lot to be said about floating point values and whatnot, But I’m going to restrain myself in this case.
Now to the main code:
// MSP430 Launchpad - Blink onboard LEDs using random delays.
// GuShH - info@gushh.net
#include "msp430x20x2.h" // Include the necessary header for our target MCU
#include "grand.h" // Include our simplistic prng lib.
void delay_ms(unsigned int ms ) { // This function simply performs a software delay, hard from efficient but it's practical in this case.
unsigned int i;
for (i = 0; i < = ms; i++) { // Make sure your < and = has no space in between (the syntax parser seems to be messing things up)
__delay_cycles(500); // This should be dependent on clock speed... but what the hell, even the loop itself should be taken into account...
}
}
void set_and_wait( int led ) {
P1OUT = led; // Set the bits
delay_ms( gRand() * 0.01 ); // Delay a "random" amount of time
}
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Hold the WDT (WatchDog Timer)
P1DIR |= BIT0|BIT6; // Enable the appropriate output
while(1) {
set_and_wait( BIT0 ); // Set BIT0, that's our first LED.
set_and_wait( BIT6 ); // Set BIT6, The other LED.
}
}
No external hardware is required, just make sure both P1.0 and P1.6 jumpers are set.
As you can see we're simply toggling the LEDs with a random delay, the delay_ms(); function was taken from here.
Like I said there are quite a few topics to explain, however I decided to keep this one as simple as possible (Alright, I'm in a rush!)
So... Compile, run and enjoy!
Once I get the time I'll put together some utilitarian code libraries and lengthier explanations, promise.
For those interested, you may download the entire project directory from here: Random Software Delays.