chipKIT® Development Platform

Inspired by Arduino™

Various Ways to Toggle digital pin

Created Mon, 01 Jun 2015 03:27:40 +0000 by djgardn2


Mon, 01 Jun 2015 03:27:40 +0000

There are many different ways to toggle a digital pin on a PIC32 microcontroller using MPIDE or UECIDE.

I will be going over a few different ways available and then going over the details for each if there is any interest in a complete code example to run.

  1. digitalWrite(14, HIGH); digitalWrite(14, LOW);

  2. LATA |= 1; LATA &= ~1;

  3. LATAbits.LATA1 = 1; LATAbits.LATA1 = 0;

  4. digitalWrite(14, ~digitalRead(14));

  5. digitalWrite(14, !digitalRead(14));

6) LATAINV = 1; //Most efficient suggested from post below.

  1. LATASET = 1; //suggested below. LATACLR = 1;

Do you have a favorite way to access a digital pin or another way not listed?

Feel free to leave a comment below.


Mon, 01 Jun 2015 09:26:04 +0000

You missed out the most efficient way:


Most of the PIC32 registers are actually made up of 4 registers - the real register, a "clear" register, a "set" register and an "inv" register. "Set" registers (such as LATASET) are used to set bits in the master register, "clear" (like LATACLR) are used to clear them, and the handy "invert" registers (eg LATAINV) are used to invert bits in the register. Makes for much more efficient code.

For instance the above line compiles into:

li    v1,1
lui   v0,0xbf88
sw    v1,24620(v0)

... whereas "LATA |= 1; LATA &= ~1;" compiles into:

lui   v0,0xbf88
lw    v1,24608(v0)
ori   v1,v1,0x1
sw    v1,24608(v0)
lw    a0,24608(v0)
li    v1,-2
and   v1,a0,v1
sw    v1,24608(v0)

... and "LATAbits.LATA1 = 1; LATAbits.LATA1 = 0;" becomes:

lui   v0,0xbf88
lw    v1,24608(v0)
li    a0,1
ins   v1,a0,0x1,0x1
sw    v1,24608(v0)
lw    v1,24608(v0)
ins   v1,zero,0x1,0x1
sw    v1,24608(v0)

digitalRead() and digitalWrite() are comparatively slow beasts - they do a lot of work to find out which IO pin the pin number actually references which adds some overhead. Plus they're functions, so they have to be called and registers preserved and the stack manipulated, which adds even more overhead.

Also the plib.h macros should be avoided. They aren't officially supported by the later MPIDE systems and if they work it's purely by accident.


Mon, 01 Jun 2015 23:21:53 +0000

I appreciate the insight on the assembly side of things. I will definitely keep that in mind and I'm sure others will appreciate it as well.

The post is now updated to avoid confusion using macros and added the LATAINV = 1; along with the SET & CLR above too.