MPLAB for the Arduino User

There’s nothing that’ll make you appreciate what you’ve got more than not having it anymore.

I recently had to take a sojourn from the comfortable Arduino IDE to the relatively foreign work-space of MPLAB X IDE. Arduino to MPLABIt was a brief trip; just long enough to figure out how to blink an LED on board my chipKIT DP32, but it left a lasting impression that’s given me a greater appreciation for the Arduiino IDE.

#include <stdio.h>
#include <stdlib.h>
#include <p32xxxx.h>

int main(int argc, char** argv)
{
    int i = 0;
    TRISBbits.TRISB2 = 0;
    while(1)
    {
        LATBbits.LATB2 = ~PORTBbits.RB2;
        for(i = 0; i < 10000; i++);
    }

    return (EXIT_SUCCESS);
}

 

The code above is the cut-down, uncommented version of my simple LED blinking program, written in the MPLAB X IDE. Would you believe this took me three hours (plus the help of another intern), to figure out?

Arduino may be a C-based language, but MPLAB X uses unmodified C code. So even though I was working with a familiar board, I had to use it a whole new way. In the end, I learned a lot about how microcontrollers work.

Let me explain what I’ve learned.

Tristate, Latch, and Port

Did you know in Arduino when you set a pin to output high or low, you’re not actually setting the pin directly? In fact, very little in a microcontroller happens through direct interaction. Instead we use something called “registers” as a sort of middleman. Here’s how it works.

We’ll start with the “tristate” register. This register controls whether a pin acts as an input, or as an output. In Arduino, when you call the pinMode() function, this register is what’s being changed.

Tristate
You can think of the tristate register as a sort of switch that controls the direction of the data flow.

Even once a pin is set as an output, we’ll still need to be able to set its value. That’s where the “latch” register comes in. This register controls the logic level of the pins, but not directly. Instead, we set the value of the latch, which, in turn, sets the output of the pin. If we translate this back to Arduino, whenever we call the digitalWrite() function, the latch register is what’s being used behind the scenes.

Latch
The latch register acts as a valve for our output pins, controlling whether the pressure (the voltage) is high or low.

Finally, when a pin is set as input, we can use the “port” register to read the value of that pin. Once again, this isn’t direct. Instead the port register’s value gets set by the microcontroller’s hardware. The port register is used whenever the digitalRead() function is called in Arduino.

Port
The port register acts as a sort of gauge, telling us whether the pressure (the voltage) is high or low.
TRIS PORT LATCH
Together, these three registers control and monitor the digital value of each pin.

There are several register groups, each labeled with a letter A, B, C, and so on. Each group will have a tristate, latch, and port register, and inside a register, each bit is associated with a single pin.

On the DP32, if we check my handy pin diagram, we can see that the LED 2, is connected to pin 13, which is connected to port RB02. The “RB” stands for “Register B”, and “02” refers to bit 2 in register B. That’s how we know we want to deal with tristate B, latch B, port B, and bit 2 in all three. See how that works?

Creating a Project

If you haven’t already installed MPLAB X IDE, I’ve made a short tutorial that can show you how. I’ve also made another tutorial that you can use to create projects and make them ready for downloading onto your board, using MPLAB X and the chipKIT PGM.

I mention several times in the tutorial that that code (the same code that is posted above), only works on the DP32. That’s because the registers called in the code above are specific to the DP32, and will probably be connected to something completely different on a different board.

In order to change that code so it works on a different board, the chipKIT uC32 for example, we would need to find out which registers are attached to our LED pin on that board.

The uC32 doesn’t have my handy pin diagram, so instead we’ll have to go to it’s reference manual wiki. Scroll to section 3.7 “Pinout Tables,” (it’s almost all the way at the bottom of the page). Now, find which pin has an LED attached. In this case, it’s pin 43, which is attached to RF0.

Now, go back to the code, and change every reference to the register group B into a reference to register group F. Also, change every reference to bit B2, into a reference to bit F0. You should get the following code:

#include <stdio.h>
#include <stdlib.h>
#include <p32xxxx.h>

int main(int argc, char** argv)
{
    int i = 0;
    // TRISBbits.TRISB2 = 0;
    TRISFbits.TRISF0 = 0;
    while(1)
    {
        // LATBbits.LATB2 = ~PORTBbits.RB2;
        LATFbits.LATF0 = ~PORTFbits.RF0;
        for(i = 0; i < 10000; i++);
    }

    return (EXIT_SUCCESS);
}

 

I’ve left in the unchanged lines (commented out, of course) next to the changed lines, to give you a better sense of what needs to be changed and how.

Code Breakdown

So far we’ve learned that the pinMode() function is associated with the tristate register, the digitalWrite() function is associated with the latch register, and the digitalRead() function is associated with the port register. We’ve also learned how to find out which register group, and which bit inside that group, is associated with the pin we want to use. In this case, we’re using pin 2 inside register group b. Now it’s time to see how that translates into the code.

Tristate

We’ll start with the line TRISBbits.TRISB2 = 0; The tristate register controls whether a pin is an input or an output. Our LED pin is B2 (on the DP32), so by setting bit B2 to 0, we’re setting our LED pin to an output. Functionally, this is the same as pinMODE(13, OUTPUT);

The next line, LATBbits.LATB2 = ~PORTBbits.RB2;, has to be broken up into two parts. This makes what is happening a little clearer.

Port

We’ll start with the latter half, PORTBbits.RB2;. This calls port B, and returns the value of bit B2. The ~ is a logical operator that inverts the bit (so if it’s a 0, it becomes a 1, and vice versa).

Latch

The second half, LATBbits.LATB2 calls latch B, and assigns a value to bit B2. That value is the opposite of what the port currently reads, because of the first half.

Finally, the line for(i = 0; i < 10000; i++); delays our code for some vague amount of time. It’s similar to the delay() function in Arduino, but delay() uses timers in order to cause the code to wait for a specific amount of time. If we wanted to use timers in MPLAB X IDE, we would have to do a whole bunch of additional steps. For simplicity, I’ve left all that out, and just replaced it with a for loop that does nothing but wait. It won’t wait an exact amount of time, but for this simple program, it doesn’t need to.

The Advantage of MPLAB X IDE

All together, this code is very similar to code you would find in Arduino’s LED Blink example. Outside your loop, you set up your IO pins. Inside your loop, you invert the value of the LED pin, then wait for a moment, and repeat.

The advantage the MPLAB X IDE has over the Arduino IDE, however, is that it allows you direct access to the registers that control your microcontroller. This has the effect of making it more complicated, but it also allows you to do things that Arduino simply is not set up to do.

Furthermore, because Arduino requires a bootloader to program your boards, some of your program space is already taken up by that bootloader. MPLAB X uses the chipKIT PGM, or other programmers, to program your board, and this requires no bootloader, giving you a little bit more space on your board for your programs.

Microchip has some very detailed and thorough references for each of it’s boards, which you can find on their Data Sheet document page. These will list not only all the hardware that’s inside each microcontroller, but also what registers control them, and what each individual bit will do. It’s really handy.

This tutorial has been just a short jaunt through what MPLAB X IDE can really do for your microcontroller. Once you learn how to use registers, you’ll quickly find that your board is capable of some incredible things.

3 Comments on “MPLAB for the Arduino User”

  1. Great post! This would have made my random foray into register manipulation for PIC32s a lot easier since these blink an LED tutorials for MPLAB X just don’t seem to exist.

    The tristate port latch graphic is pretty cute as well.

  2. I know it’s been a long time since this post was written, but you forgot to mention the biggest advantage using plan C over Arduino “language”: Arduinos digitalWrite and digitalRead are painfully slow, and direct port manipulation is extremely fast.

Leave a Reply

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