1: LED Toggle

Blinking (or toggling) an LED is a microcontroller’s equivalent of a “Hello World” program. If you can toggle an LED, you’ll have at least a basic understanding of what it takes setup I/O pins, deal with digital I/O pins, compile C code with MPLAB, and upload the .hex file to your PIC32. That can be a lot!

Slideshow:
Fullscreen:
Download:

/* =================================================================================
* PIC32 Tutorial 1 – Blinking an LED with a button: Digital Input and Outputs
* ==================================================================================
* Rodrigo S. Bismonte II
* with info from the Northwestern Mechatronics Wiki page on the NU32v2:
*
*
* Objective:
* -Blink an LED attached to pin RD8 when the PROG (RE7) button
* on the UBW32 is pressed.
*
* Tutorial covers:
* -Including neccesary header files.
* -Setup for best performance using the peripheral library.
* -Setup I/O ports for digital input and output.
*
* ==================== NOTES on Digital I/O setup ===================================
*
* Each I/O port (Port A – Port F) has three registers: PORTx, TRISx, LATx.
* They are short for Port, Tri-State, and Latch registers.
*
* Note that each pin on the PIC32 is grouped into a certain port. That is,
* you wouldn’t refer to “pin 4″ but might refer to “pin B4″ or “pin RB4″
* (pin 4 on Port B). The “R” in “RB4″ is convention.
*
* TRISx sets the direction of the pin. Corresponding port pin is an input
* when the bit is set (1), output when the bit is cleared (0).
* Think 1=I(nput) and 0=O(utput).
* “TRISA = 0x000C;” sets pins RA2 and RA3 to inputs, rest of PortA as outputs
* “TRISC = 0xA000;” sets pins RC13 and RC15 as inputs, all else outputs
* Individual pins can be addressed with this convention:
* TRISxbits.TRISxy (x is the port letter, y is the number of the pin)
*
* LATx sets the value at that particular port.
* “LATA = 0x003E;” sets RE1 through RE5 HIGH, all else on PortA LOW
* Individual bits can be addressed with this convention:
* LATxbits.LATxy (x is the port letter, y is the number of the pin)
*
* PORTx holds the value at that port’s pin, which can then be read.
* A write to PORTx is the same as a write to the LATx register.
* “short Value = PORTA;” writes the values of all pins on PortA to the variable ‘Value’
* Individual pins can be addressed with this convention:
* PORTxbits.Rxy (x is the port letter, y is the number of the pin)
*
* Each of the three special function registers (SFR) also have three
* registers that allow for atomic updating (which takes fewer clock cycles).
*
* TRISxSET: sets the specified bits of Port x, also works for PORTx and LATx.
* TRISxCLR: clears the specified bits of Port x, also works for PORTx and LATx.
* TRISxINV: inverts the specified bits of Port x, also works for PORTx and LATx.
*
* For alternative methods to those above, Peripheral Library Functions exist
* although are usually not necessary for these simple tasks.
*
* Note about Port B: If you want to use the analog pins (PORTB / ANx),
* as digital inputs, you must first SET the
* corresponding bits in the AD1PCFG register.
* “AD1PCFG = 0×0003;” sets pins RB0 and RB1 to analog inputs, all else digital inputs
* =================================================================================
*/
 
#define SYSCLK 80000000L // Give the System’s clock frequency (80MHz for PIC32MX440F512H)
// This is general practice in order to get the best performance
 
#include <p32xxxx.h> // Include PIC32 specifics header file.
#include <plib.h> // Include the PIC32 Peripheral Library.
 
int main(void)
{
        SYSTEMConfigPerformance(SYSCLK);
        // Peripheral function that configures for best performance given the system’s
        // clock frequency–this is for general practice.
 
        // This part is analogous to the void setup(){}; in Arduino.
 
        // Set pin RD8 as an output, could be written as TRISD = 0xFEFF;
        // but takes more clock cycles to perform.
        TRISDCLR = 0x0100;
 
        // Set pin RE7 (PROG button on UBW32) as an input, could be written as TRISE = 0×0080;
        // but takes more clock cycles to perform.
        TRISESET = 0x0080;
 
        // This part is analogous to the void loop(){}; in Arduino.
        while( 1) // Loop forever…
        {
                // Reads the state of pin RE7, and latches RD8 accordingly.
                // Note that RE7 is normally set HIGH (3.3V) through an internal pull-up
                // resistor and will actually be set LOW when the PROG button is pressed.
                LATDbits.LATD8 = PORTEbits.RE7;
        }
 
        return 1; // main returns an int
 
} // END main()
 
// Further excercises:
// – Have the button toggle a second LED.
// – Have the button toggle a third LED every two button presses.

Download that sucker -> pic32_tut1_IO.c

One thought on “1: LED Toggle

Leave a Reply

Your email address will not be published. Required fields are marked *