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.