Tutoriales

Breve Tutorial - PIC32MX

El siguiente tutorial pretende ayudar a iniciarse con los PIC32MX, C32 de Microchip y prender un led.

Material empleado
+ PIC32MX420F032H (link)
+ MPLAB (8.43 o mejor)
+ C32 Standard v1.10





Diagramas para que construyas tus PCBs

(Descarga 3 placas)
(Descarga 1 placa)


Las conexiones obligatorias que el PIC32 debe llevar son:

+ Todos los pines Vdd y Vss siempre conectados (3.3V y 0V respectivamente)
+ Todos los pines AVdd y AVss siempre conectados
+ Un capacitor de 10uF entre la terminal Vcap/Vddcore y GND, sirve para regular el voltaje interno del núcleo del pic
+ La terminal ENVREG conectada a 3.3V para habilitar el regulador interno
+ El pin MCLR como siempre se ha conectado
+ Los pines PGEC1 y PGED1, o PGEC2 y PGED2 conectados al programador Pickit2 (por ahora el único que lo puede programar)
+ OSC1 y OSC2 con un cristal de 4MHz y capacitores de 15pF (si se usa el Fast RC Oscillator interno entonces esto se omite)


Una vez que se ha conectado lo anterior, puedes colocar un LED y una R de 220 ohms en cualquier terminal del puerto B (RB0 a RB15).

Debes abrir el Project Wizard de MPLAB, elegir el pic apropiado, elegir la suite C32 y crear un nuevo archivo.c en el que colocarás lo siguiente:

/*
Programa para encender un led
MigSantiago, Marzo 2010
*/
#include <p32mx420f032h.h>
#include <plib.h>

//Entrada de cristal a 4MHz
//Para CPU será elevada a 80Mhz

//CPU
#pragma config FPLLIDIV = DIV_1, FPLLMUL = MUL_20, FPLLODIV = DIV_1 //80MHz
#pragma config POSCMOD = XT, FNOSC = PRIPLL, FPBDIV = DIV_8
#pragma config FSOSCEN = OFF //sin oscilador secundario

int main()
{
    int i=0;

    //Disable JTAG port
    //Hace que las terminales RB10 y RB11 sean I/O
    DDPCONbits.JTAGEN = 0;

    //PORTSetPinsDigitalOut(IOPORT_B, BIT_0);
    mPORTBDirection(0x0000); //todo b salida

while(1)
   {
   ++i;
   PORTWrite(IOPORT_B, i);
   }
}



Adicionalmente hay que agregar una ruta include al proyecto para que el compilador encuentre las librerías. Esto se logra yendo a Project, Build Options, project, Directories, Show Directories for: Include Search Path y se debe agregar esta ruta:

C:\Program Files (x86)\Microchip\MPLAB C32\pic32mx\include\proc

Modifica Program Files (x86) para que coincida con tu Windows.

Lo que hace el programa es que incrementa la variable i en una unidad. Posteriormente la coloca en el puerto B. El resultado es que cada pin del puerto B tendrá un encendido y apagado con un duty time del 50%. El pin b0 es el que más rápidamente oscilará mientras que el pin b15 será el más lento, pero todos tendrán un duty time del 50%.

Con un voltímetro en DC puedes comprobarlo midiendo aproximadamente 1.6V en los pines.

Este es mi circuito de prueba:



Como todo buen PIC, el PIC32 trae PLL para multiplicar la frecuencia de oscilación hasta 80MHz (80MIPS). La ruta que sigue la frecuencia de oscilación es la siguiente:



Entran 4MHz, se dividen entre 1, se multiplican por 20, se dividen entre 1 y salen 80MHz. Entran 80Mhz al CPU. Entran 10MHz al bus de los periféricos ya que el divisor es de 8.

Si quieres ahorrarte el cristal deberás configurar el FRCPLL. Dividir los 8MHz que genera entre 2, multiplicarlo por 20, dividirlo entre 1 y obtendrás 80MHz sin cristal.

La librería plib.h incluye muchas funciones para el manejo de los periféricos del PIC32 (I2C, UART, Timers, etc.).

Un segundo ejemplo, esta vez utiliza el timer1 configurado para generar una interrupción cada 1s e incrementar el estado del puerto B. Ahora sí el led flashea a una velocidad humanamente visible.

/*
Programa para encender un led
MigSantiago, Marzo 2010
*/
#include <p32mx420f032h.h>
#include <plib.h>

//Entrada de cristal a 4MHz
//Para CPU será elevada a 80Mhz

//CPU
#pragma config FPLLIDIV = DIV_1, FPLLMUL = MUL_20, FPLLODIV = DIV_1 //80MHz
#pragma config POSCMOD = XT, FNOSC = PRIPLL, FPBDIV = DIV_8
#pragma config FSOSCEN = OFF //sin oscilador secundario

// Let compile time pre-processor calculate the PR1 (period)
#define SYS_FREQ             (80000000L)
#define PB_DIV                 8
#define PRESCALE               256
#define TOGGLES_PER_SEC        1
#define T1_TICK               (SYS_FREQ/PB_DIV/PRESCALE/TOGGLES_PER_SEC)

int i=0;

//////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    //Disable JTAG port
    //Hace que las terminales RB10 y RB11 sean I/O
    DDPCONbits.JTAGEN = 0;

    mPORTBDirection(0x0000); //todo b salida
    //Configure Timer 1 using internal clock, 1:256 prescale
    OpenTimer1(T1_ON | T1_SOURCE_INT | T1_PS_1_256, T1_TICK);

    // set up the timer interrupt with a priority of 2
    ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_2);

    // enable multi-vector interrupts
    INTEnableSystemMultiVectoredInt();

    while(1);
}
//////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////
//Interrupción timer 1
void __ISR(_TIMER_1_VECTOR, ipl2) Timer1Handler(void)
{
    // clear the interrupt flag
    mT1ClearIntFlag();

    // .. things to do
    // .. in this case, toggle the LED
   ++i;
   PORTWrite(IOPORT_B, i);
}
//////////////////////////////////////////////////////////////////////////////////////////

Éxito en tus circuitos PIC32MX.