NU32v2: Serial Communication with the PC

From Mech
Revision as of 13:04, 25 January 2011 by NickMarchuk (talk | contribs) (New page: '''Under construction NDM 1/25/2010''' Digital inputs and outputs (DIO) are the simplest of interfaces between the PIC and other electronics, sensors, and actuators. The PIC32 has many D...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Under construction NDM 1/25/2010

Digital inputs and outputs (DIO) are the simplest of interfaces between the PIC and other electronics, sensors, and actuators. The PIC32 has many DIO pins, each of which can take one of two states: high or low.

Overview

The PIC32

Details

The functions of the DIO pins are controlled by special function registers (SFRs). Each of these SFRs has 32 bits on the PIC32, but for many, not all 32 are relevant. Depending on whether these bits are set to 0 or 1, different actions or settings are performed:

  • AD1PCFG: This SFR determines which of the 16 pins with an analog input function (port B) is treated as an analog input or a DIO pin. The 16 most significant bits (high bits) AD1PCFG<31:16> are ignored, but AD1PCFG<15:0> determine which of the 16 pins is treated as an analog input. 0 indicates analog input, and 1 indicates DIO. So if the bit AD1PCFG<7> is 0, then the pin with the function AN7 is an analog input; if AD1PCFG<7> is 1, then it is a DIO. AD1PCFG resets to 0x0000, so all 16 pins of port B are treated as analog inputs by default. To make AN15 and AN1 analog inputs and the rest DIO, we can use the C command AD1PCFG = 0x7FFD. To make AN15 and AN1 analog inputs but leave the other settings unchanged, we can use the C command AD1PCFG &= 0x7FFD. Note we only have to specify 16 bits, or 4 hex digits, as the 16 most significant bits have no role. Instead of acting on the entire SFR, we could instead address an individual bit, using AD1PCFGbits.PCFG15 = 1, for example, to set the value of a single bit.


Library Functions

The peripheral library offers a number of function calls to help you use the DIO pins. These functions have names such as PORTRead, PORTSetPinsDigitalIn, PORTSetPinsDigitalOut, etc. C source code can be found in pic32-libs/peripheral/ports/source/*.c, and .h header files can be found in pic32-libs/include/peripheral/ports.h. Documentation can be found in your MPLAB C32's doc directory, in Microchip-PIC32MX-Peripheral-Library.chm. The DIO functions are simple enough, however, that we will usually just set the appropriate SFRs manually, as described above and demonstrated in the samples below.

Sample Code

This example uses two of the PIC32 pins as digital outputs and one pin as digital input. In particular, it uses pins RG12 and RG13 as outputs, since these are connected to LEDs on the NU32v2 board (by the NU32v2 circuit schematic, the associated LED is on when the pin is low). It configures RG6 as an input for a button press. If RG6 is high, the LEDs will be off. If RG6 is low, the LEDs will be on. Let's assume RG6 is low when the button is pressed (as it is with the NU32v2 and your button in the breadboard).

/*
 * Simple digital input/output.
 */

#include <plib.h>

// No need to configure the configuration bits controlling clock speed, etc.;
// these definitions are in the bootloader.

// Lines below could go into a separate .h file, since they're the same
// for all projects using the NU32v2 and the NU32v2 bootloader.
#define LED0     LATGbits.LATG12
#define LED1     LATGbits.LATG13
#define SW       PORTGbits.RG6
#define SYS_FREQ 80000000        // 80 MHz

int main(void) {
  // Turn on the pre-fetch cache, choose the maximum possible peripheral
  // bus frequency, and choose minimum flash wait states.  Could be done in
  // bootloader.  See pic32-libs/include/peripheral/system.h.
  SYSTEMConfig(SYS_FREQ, SYS_CFG_ALL);

  AD1PCFG = 0xFFFF;  // sets all port B to DIO.  Only needed if using port B.

  // Initialize LEDs as output, switch as input.  Could be done in bootloader.
  // Note we don't technically have to set switch as an input, since it's the
  // default, but let's do it in case someone inserts code before this line.
  TRISGCLR = 0x3000; TRISGSET = 0x0040;

  while(1) {
    while(!SW) {           // if button is pressed, turn LEDs on
      LED0 = 0; LED1 = 0;
    }
    LED0 = 1; LED1 = 1;    // when button is released turn LEDs off
  }
  return 0;
}

Now, for fun, let's make a couple of small changes to the code.

/*
 * Simple digital input/output.
 */

#include <plib.h>
#define LED0     LATGbits.LATG12
#define LED1     LATGbits.LATG13
#define SW       PORTGbits.RG6
#define SYS_FREQ 80000000        // 80 MHz

int main(void) {

  int i;

  SYSTEMConfig(SYS_FREQ, SYS_CFG_ALL);
  TRISGCLR = 0x3000; TRISGSET = 0x0040;
  while(1) {
    while(!SW) {
      while(!SW) {
        LED0 = 0; LED1 = 0;       // LED is on
      }
      for(i=0; i<10000000; i++);  // 10 million
    }
    LED0 = 1; LED1 = 1;           // LED is off
  }
  return 0;
}

More Information

More information on the I/O ports can be found in Chapter 12 of the Data Sheet and Chapter 12 of the Reference Manual. Some special function registers (SFRs) are listed in Chapter 4 of the Data Sheet. The SET, CLR, and INV registers are described in Section 2 of the Reference Manual.