Playing with PICs : 1. Getting Started

Getting Started with PICs

Getting Started with PICs

I’ve been spending a fair amount of time recently playing with micro controller boards but for some reason I’ve never had a play with PICs. I decided that it was about time to change all that so I finally got around to ordering a PIC programmer, downloaded a copy of Microchip MPLAB and gave it a go.

I bought the programmer from RS Online. It’s a PICkit2 Debug Express and it arrives with a 44-pin demo board complete with a PIC16F887 (not the PIC16F877 advertised!) and a few additional components for experimentation purposes which are LEDs, a push button and a variable resistor.

I’m working on a Mac so I was relieved to discover that the Microchip development environment, the MPLAB IDE, is now available on OS X and Linux as well as Windows. The software is available from the Microchip website and while I was there I also downloaded and installed the pk2cmd utility. You’ll need to scroll to the bottom of the page to find it.

The PIC on the demo board comes with a program already installed so the first thing I did after scanning through the various read me files was to try and get that running starting with the command line tool to make sure that this was all working correctly. I plugged the supplied USB cable into my Mac and the other end into the PICKit2. I then plugged the PICKit2 into the board making sure that the guide arrows lined up. I then ran the command line tool without parameters to get the help to display and had a look at what was available.

To get power to the board from the programmer you need to call the command line as follows:

pk2cmd -A3.3 -P -HK

The -A parameter sets the voltage to 3.3V, the -P parameter auto-detects the target device and the -HK keeps the command running until you hit a key.

What you then get is a program where the LEDs chase with the speed controlled by the variable resistor and the direction controlled by the push button.

Having got that going I fired up MPLAB to take a look and armed with the data sheets for the PIC and the demo board, I decided to try and get those LEDs to light up. It turned out to be pretty straightforward although it took a few goes to sort out the config settings and get them right for debugging. It wasn’t helped by the 887 vs 877 confusion!

I started by creating a new project using the category ‘Microchip Embedded’ and ‘Standalone Project’. After clicking ‘Next’ I chose the ‘Mid-Range 8-bit MCUs’ option and selected the ‘PIC16F887’ MCU. After clicking ‘Next’ I chose the PICKit2 device from under the PICKit2 category and clicked ‘Next’. I chose the XC8 tool chain, clicked ‘Next’ and gave the project the name ‘Simple LEDs’. I clicked ‘Finish’ and my project was created.

The project is created without any files so the next thing was to add a source file. I did this by right clicking on the ‘Source Files’ folder in the ‘Projects’ tab on the left and selecting ‘New’ followed by ‘C Source File’. From there I created a file called main.c.

Having done that I included the pic header.

#include <pic.h>

I then generated the configuration information for the project which is done using a series of #pragma directives in the source code. Fortunately there is a cunning tool in the IDE that generates the code for you so you can paste it into a source file. To open the tool, click on the ‘Window’ menu and select ‘PIC Memory Views’ and ‘Configuration Bits’. This pops up the screen below in the IDE.

PIC Configuration Settings

PIC Configuration Settings

I made a couple of changes to the default configuration by setting FOSC to INTRC_NOCLKOUT as I wanted to use the internal oscillator (there isn’t an external one on the demo board) and I switched off LVP because the first time I tried debugging a program MPLAB complained about it.

Generated Settings Code

Generated Settings Code

Once I’d done that I hit the ‘Generate Source Code to Output’ button and transferred the generated code to my main.c file as below.

#include <pic.h>

// PIC16F887 Configuration Bit Settings

// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

The next thing to do was to add a main function which is defined as void with no parameters as follows.

void main()
{
   
}

Right, now for the interesting bit which is to get those LEDs lit up so time to open up those data sheets.

The first sheet I looked at was the one for the demo board because although I could sort of see the tracks on the board connecting them to port D, I wanted to be sure. The relevant part of the diagram is shown below and as you can see, the LEDs are most definitely connected to port D.

PIC Demo Board LEDs

PIC Demo Board LEDs

The next thing then was to grab the PIC16F887 data sheet and look at what we need to do to get port D working.

Well it turns out to be pretty easy. We simply need to configure the TRISD register to make all of the pins output pins and then write to the PORTD register to set the states.

The TRISD register is 8 bits wide and each bit represents one of the pins. Setting a bit to 0 makes it an output whereas setting it to 1 makes it an input. We want all of our pins to be outputs so that’s pretty easy, we just set the register to 0. To make all of the LEDs light up we need to write 1 to all of the pins so that’s pretty easy too, we just set the PORTD register to 0xff.

The last thing that needs to happen is to add in an infinite loop because we don’t want an embedded program to stop executing and that’s easily achieved by using an infinite while loop.

The final code for main.c then ends up looking like this:

#include <pic.h>

// PIC16F887 Configuration Bit Settings

// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

void main()
{
    // configure port d as output
    TRISD = 0;

    // set the pins high to display the leds
    PORTD = 0xff;

    // loop forever
    while(1){}
}

Finally I made sure that the project was the ‘main’ project by right clicking on it in the ‘Projects’ view and selecting ‘Set as Main Project’ and then ran it by clicking on the ‘Debug’ menu and selecting ‘Debug Main Project’. A few moments later all eight of the LEDs on my board were alight. Success!

Having done that I thought it might be cool to try to replicate the demo program by writing from scratch using the data sheets for reference and this will be the subject of my next few posts.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: