PIC32 Tutorial 2 – Timers

advertisement
Tutorial 0 – Setting up http://www.eedesignlabs.com/pic32-tutorial-0-setting-up/#more-348
This tutorial will describe how to find what to connect to each other in order to be able to start a project.
Materials
 PICKit 3
 PIC32MX220F032B
 Breadboard
 Hookup wire
 Resistors (1 – 10K Ohm and 1 – 10 Ohm)
 Capacitors (4 – 0.1 μF and 1 – 0.01 μF)
 Crystal ( 1 – 10 MHz)
Datasheets
 PICKit 3 datasheet
 PIC32MX220F032B datasheet
Step 1 (Board Setup)
Place the Microcontroller onto the breadboard. Bend the chip’s legs inward slightly so they fit into the
breadboard. Push the PIC down to ensure a good connection. Make sure that the little circle on the chip is
in the upper left corner. This circle indicates PIN 1. I like placing the Microcontroller higher up on the
breadboard (provides me with
working space on the bottom.)
Next, I connect the left positive to the right positive and the left negative to the right negative.
Step 2 ( Powering the Chip)
Open up the PIC32MX220F032B Datasheet. On the second half of page 4 you should see:
This diagram will be used over and over throughout many tutorials.
Power and ground pins do not change at all. Once this
microcontroller as setup for use very little will change between
uses.
The following pins must be connected to Ground (Negative (-) ):
 PIN 8 (Vss)
 PIN 19 (Vss)
 PIN 27 (AVss)
The following pins must be connected to Positive (+) :
 PIN 13 (VDD)
 PIC 23 (VUSB)
Your layout should look something like:
Connect a 10K Ohm resistor between: PIN 1 (MCLR) and Positive (+). ( A 10K Ohm 5% resistor has the
colors Brown, Black, Orange, Gold.)
Connect a 10 Ohm resistor between: PIN 28 (AVDD) and Positive (+). ( A 10 Ohm 5% resistor has the
colors Brown, Black, Black, Gold.)
Add a 0.1 μF capacitor between:
 PIN 27 (AVss) and PIN 28 (AVDD)
 VDD and VSS on the left side
 VDD and VSS on the right side
 PIN 20 (VCAP) and Ground (-)
Add a 0.01 μF capacitor between:
 PIN 1 (MCLR) and Ground (-)
The result should look similar to :
Lastly connect the 10 MHz oscillator between:
 PIN 9 (OSC1) and PIN 10 (OSC2)
The PIC32MX220F032B is now connected and ready to be
programmed. Now we need to connect the programmer. (PICKit 3)
Step 3 ( Connecting the Programmer)
Now we need to pull up the PICKit3 Datasheet. The part that we are going to be using is at the top of page
15.
We have seen some of the same pin names before while connecting the PIC32. To connect this
programmer we connect:
Programmer PIN number
 PIN 1 (MCLR)
PIC32MX220F032B – PIN 1 (MCLR)
 PIN 2 (VDD)
Breadboard
– Positive (+)
 PIN 3 (VSS)
Breadboard
– Negative (-)
 PIN 4 (PGD)
PIC32MX220F032B – PIN 4 (PGED1)
 PIN 5 (PGC)
PIC32MX220F032B – PIN 5 (PGEC1)
 PIN 6 (PGM)
NC ( Not connected)
You might be asking yourself why I chose to used PIN 4 (PGED1) and PIN 5 (PGEC1) instead of using PIN
21 (PGED2) and PIN 22 (PGEC2) or PIN 2 (PGED3) and PIN 3 (PGEC3). Well… it doesn’t matter. You are
welcome to use which ever you want, just remember that you need to change the configuration bits to
follow your connections.
The space left open on the breadboard will now serve a purpose, I will use it to connect the programmer.
This configuration allows me to quickly disconnect and reconnect the programmer between projects.
Step 4 (Creating a Project)
Once you have MPLAB-X installed and PICKit 3 driver installed you are ready to verify that you have made
all the right connections.
1. Connect the programmer to your breadboard
2. Plug in the USB to the programmer and the other end to the computer
3. Open up MPLAB-X by Clicking Start > All programs > Microchip > MPLAB X IDE > MPLAB X
IDE V1.00
4. Click File > New Project
5. Select Microchip Embedded and Standalone Project
6. Press Next
7. Select 32-bit MCUs (PIC32) under the Family drop down menu.
8. Select PIC32MX220F032B under the Device drop down menu.
9. Select PICKit 3 and click Next
10. Choose the C32 (v2.02) [C:\Program Files (x86)\Microchip\mplabc32\v2.02\bin]installed and
click Next
11. Enter a Project Name: I chose tutorial
12. Enter a Project Location: I chose my desktop
13. Press Finish
14. Right click on Source Files > New > C Main File
15. Enter a File Name like “main” and select C from the Extension drop down menu, then Finish
16. Press
(Debug Project ) in the upper toolbar
In the Output window you should see:
Of course the PIC32 device is not recognized… we did not provide it any power. Lets do it now
17. In the Menu bar, select File > Project Properties (tutorial)
18. In the Project Properties window select PICkit 3 and choose Power from the drop down menu
19. Check the “Power target circuit from PICkit3″ and choose 3.25 from the voltage drop down menu.
20. Press Apply then OK
21. Press (Debug Project ) in the upper toolbar (again)
22. A new window should pop-up. Choose Yes. This WDT configuration bit will be fixed in the next step
so it will not arise again.
23. At the Output window you should see :
24. You have created your very first project. Congratulations.
Step 5 ( Configuration Bits)
The configuration bits will be explained as we use them throughout the tutorial. MPLAB-X generates the
configuration bits for us after we made our selections.
1. Navigate to Window > PIC Memory Views > Configuration Bits
2. In the Configuration Bits select each to match:
PMDL1WAY = OFF
IOL1WAY = OFF
FUSBIDIO = ON
FVBUSONIO = ON
FPLLIDIV = DIV_2
FPLLMUL = MUL_16
UPLLIDIV = DIV_5
UPLLEN = OFF
FPLLODIV = DIV_2
FNOSC = PRIPLL
FSOSCEN = OFF
IESO = OFF
POSCMOD = HS
OSCIOFNC = OFF
FPBDIV = DIV_2
FCKSM = CSDCMD
WDTPS = PS1
WINDIS = OFF
FWDTEN = OFF
FWDTWINSZ = WISZ_25
JTAGEN = OFF
ICESEL = ICS_PGx1
PWP = OFF
BWP = OFF
CP = OFF
Tutorial 1-Blinking LED
In this tutorial we will learn how to change the direction and output of a pin. It is expected that you
are able to connect the PIC32MX220F032B and start a project. You are welcome to follow PIC32
Tutorial 0-Setting up so that you are ready to follow this one.
Materials Everything from PIC32 Tutorial 0-Setting up and: An LED (Light Emitting Diode)
A 330 Ω resistor
Datasheets
PIC32MX220F032B datasheet
LED Datasheet (Not required)
Step 1 ( Choosing a Pin )
From the PIC32MX220F032B Datasheet. On the second half of page 4 you should see:
Choosing a pin to use is not very difficult during this stage. The pins we are currently using to power
and program the microcontroller are:
1
MCLR – The programmer uses this pin to reset the controller
4
PGED1 – The Programmer programs the microcontroller through this pin and PGEC1
5
PGEC1 – The Programmer programs the microcontroller through this pin and PGED1
8
VSS – Ground (-)
9
OSC1 – One of the oscillator’s legs
10
OSC2 – The other oscillator leg
13
VDD – Positive (+)
19
VSS – Ground (-)
20
VCAP – Capacitor
23
VUSB – Voltage for USB ( we are not using USB so it must be connected to VDD)
27
AVSS – Ground (-) ( used as a negative voltage reference for the Analog to Digital Converter (ADC))
28
AVDD – Positive (+) ( used as a positive voltage reference for the Analog to Digital Converter (ADC))
I will choose to use PIN 16 – RB7. (There is a lot of room in that area of the board)
Step 2 ( Connecting the LED)Connect the 330 Ω resister to RB7 and and unused line on the
breadboard. The connect the LED between the resistor line and Ground (-). The longer leg of the LED
must be connected to positive. Here is how your board should look like
: Step 3 ( Code)
Hardware is good to have but useless unless it is working. In the previous tutorial we setup an empty project that
can just compile but does not actually do anything. We will now add to the empty project and control the LED.
I learn the quickest by trying an example and then trying to understand how the code achieves it. I shall do the
same here:#include <p32xxxx.h>
#include <plib.h>
int main() {mPORTBDirection(0);while (1){mPORTBToggleBits(BIT_7);}return (EXIT_SUCCESS);}
Copy the above code to your project. ( Make sure you place this code after all the #pragma config
…
Configuration Bits.) Now you can press the Debug Project
. Do not forget to power your device as
shown in PIC32 Tutorial 0-Setting up. You should see that the LED is constantly on. To stop the LED press
the Reset button then Stop Debugger Session. Now lets examine the simple code.
#include <plib.h> – Includes a library with many functions and macros which makes our programming much
simpler and easier to read.
mPORTBDirection(0); – is a macro that configures all of PORTB as Output. ( o is for Output and 1is for Input)
while() – is a function that repeats over and over when the condition inside is true. Because we would like the
loop to always continue we set the condition to be 1 (TRUE)
mPORTBToggleBits(BIT_7) – is a macro that Toggles Bit 7 in PORTB. On when its off and off when its on.
Why is the LED always on if the macro is supposed to Toggle the pin? Well actually the pin is being toggled, but
it is happening at such a fast rate that your brain believes its constantly on ( at half brightness.) How do I know
that it is actually toggling?
As you can
see, that pin is switching ON then OFF at 4 MHz or four million times per second. That is quick!!!
We can slow down this by adding a function that takes time. How about a while loop. We need to add a few
lines. The new main() function will look like:
#include <plib.h>
int main() {
int count=0;
mPORTBDirection(0);
while (1)
{
mPORTBToggleBits(BIT_7);
while(count)
{
count–;
}
count=100000;
}
return (EXIT_SUCCESS);
}
Debug and watch how the LED blinks. You can see it blinks quickly. The int count=0; initializes an integer and
sets the value to 0. The while(count) is TRUE until count =0. count– subtracts 1 from itself. That while loop
counts down to 0 and then count is set to 100000. To slow down the speed of the blinking we would need to
raise the value of count. When count=100000 the frequency of the blinking LED is 18.12 Hz, 18.12 times a
second.
Other Useful Macros
mPORTBSetBits(BIT_0|BIT_2) – Sets BIT_0 and BIT_2 to high (Positive.) That only works after you assign that pin as output.
mPORTBClearBits(BIT_0|BIT2) – Sets BIT_0 and BIT_2 to high (Positive.) That only works after you assign that pin as output.
mPORTBSetPinsDigitalOut(BIT_0) - Sets BIT_0 as a digital output. Same as mPORTBDirection(0)
mPORTBSetPinsDigitalIn(BIT_0) - Sets BIT_0 as a digital Input. Same as mPORTBDirection(1)
mPORTBReadBits(BIT_0) – Returns the value that BIT_0 is supposed to be at, 0 or 1. (low or high)
mPORTBReadLatchBits(BIT_0) – Returns the value that BIT_0 is at, 0 or 1.( low or high)
Can you do it?
Can you make 2 different LEDs blink together?
Can you make 2 different LEDs alternate blinks?
Can you make one LED toggle every 1 second?
Can you make the LED turn on for 1 second and off for 2?
You can do it!
PIC32 Tutorial 2-Timers is your next step. Timers allow you to make precise time calculation
and keep tasks time managed.
PIC32 Tutorial 2 – Timers
Posted by Janusz on October 10, 2012
Posted in: Tutorials. Tagged: 32 bit microcontroller, blinking led, getting started, microcontroller, pic
microcontroller,PIC32 Timers, PIC32MX150F128B, tutorial. 2 comments
Tutorial 2 – Timers
In this tutorial we will explore how to use the timer peripheral on the PIC32 microcontroller. For this project it
is expected that you already completed tutorials 0 and 1.
Materials
Everything from Tutorial 1.
Introduction
The first step in using a timer is to understand how a timer works. The particular microcontroller we
are using (PIC32MX150F128B) has 5 – 16bit timers. The first question you may be asking is: what is a
timer? A simple and short answer to that question is a counting device. A more elaborate answer is a
peripheral device that increases its count on every clock cycle of the PIC. Once a timer reaches its
maximum vale it rolls over and start counting again. Each timer is controlled by a set of registers that define
how the timer operates. Please note that each timer may have extra functionality in addition to its base
features to simplify certain tasks, or it might be used by another peripheral for its timing services, anyway
the datasheet is the best source to find out more. In this tutorial we be using timer 1, to demonstrate its
operation. Timer 2, 3, 4 and 5 is the same with an exception that timers (2, 3) and (4, 5) can be combined to
create a 32 bit timer giving you greater range for counting. This classification combined with the ability to
have a special event trigger is called Type B timer in the Microchip datasheet. Timer 1 on the other hand is
a Type A timer, the benefit of type A timer is the ability to be clocked externally and the possibility to
operate during sleep mode, but it cannot be combined to create a 32 bit timer pair. Each microcontroller will
have at least 1 Type A timer, in our case its Timer 1.
Timer 1 – Registers
Timer 1 is controlled by T1CON register, this register is a 32 bits in size and each bit controls certain
functionally of the timer. A picture of the register and its bits is shown below, this is taken directly from the
PIC32 Ref datasheet.
As you can see from the above picture, to configure a timer it’s pretty straight forward
. The bits of
interests are those with names, the ones with a dash are not used and are reserved, therefore you should
not write to them or read them as they might be used in the future, but for now they have no meaning. To
configure the timer we first must determine what do we want our period to be, for this example we will
assume that we want the period of 200 ms. In other words we will flash the LED, 200 ms on & 200 ms off
then repeat. To do this we must know what is our Peripheral clock frequency. In the last tutorial the speed
of the PIC was 40 Mhz and the peripheral clock was set to 20 Mhz.
Before we move any further we first must discus what is a pre-scale and how it’s used. Using the above
peripheral clock as an example, if the pre-scale is 1:1 the timer will see a 20 Mhz clock at its input, this
means it will count at the rate of 20,000,000 times a second – this is too quick for most applications. To
slow down the timer clock, a pre-scale is used, a pre-scale of 1:2 means that for every 2 ticks of the main
clock the output clock will increase by 1. This reduces the rate of the output by 50%, so for our example a
20Mhz clock will become a 10Mhz clock to the Timer input. In general the formula is 1:X where X signify
how many cycles it takes for the output to increase by 1 as compared to the Input clock. For example 1:4 ->
for every 4 ticks of main clock the output will increase by1 or in another words the input is divided by 4. 1:8 > the input is divided by 8 and so on. Please note that the available pre-scales are stated in the datasheet
of the device.
Since now we know our required period and how a pre-scale works we are ready to determine how to setup
a timer.
Period = 1 / frequency
Accuracy = 1 / f_input , (for 20Mhz clock we get accuracy of 50 ns.)
Resolution = XX bits*accuracy (16bit for Timer 1 = 65,536) = 65,536 * 50ns = 3.2768 ms.
So our precision is 50 ns and resolution of 3.2768 ms, this means we are able to count up to 3.2768 ms
with just using a timer itself and nothing else, if we use a pre-scale we lose precision as the expense of
higher resolution. Depending on your needs, choose those accordingly.
For our example we want a period of 200 ms, therefore a clock of 20Mhz and pre-scale 1:1 is not good for
us, fortunately we can determine what pre-scale to use as shown below:
Pre-Scale
Accuracy
Resolution
Meets requirement
1:1
50 ns
3.2786 ms
NO
1:8
400 ns
26.2144 ms
NO
1:64
3.2 us
209.71 ms
Yes
1:256
12.8 us
838.86 ms
Yes
Based on the table above we can conclude that a pre-scale of 1:64 and 1:256 meets our requirement of
200 ms period. The question you might be asking is which one to use? A simple answer is the one that gets
you closer to the desired period!
1:64 pre-scale
200 / (64 / 20Mhz ) = 62,500
1:256 pre-scale
200 / (256 / 20Mhz ) = 15,625
In this case both are equally good so choose the one that suits you more as sometimes when you do the
division you will get a number of 62.5 and you can’t count a 0.5 so there will be error introduced. Please
note that the number you get is the number the counter must count up to, for a 16 bit timer maximum is
65,536 so if you get a number that is higher the max allowed, you did something wrong so try a new prescale.
Setting Timer 1
Now it’s time to actually set the timer control register and start counting. For this you have two options: 1 set
each bit individually by using the datasheet, or 2 use the macros provided by Microchip include file. For this
tutorial we will be using the macros since it’s faster.
The macros for Timer 1 we will use are:
void OpenTimer1(unsigned int config, unsigned int period);
void CloseTimer1() ;
unsigned int ReadTimer1(void) ;
void WriteTimer1(unsigned int value) ;
Version 1:
#include <plib.h>
int main(int argc, char** argv)
{
//Configure the I/O – To flash the LED on PORT B pin 8, RB8
PORTSetPinsDigitalOut(IOPORT_B, BIT_8);
PORTClearBits(IOPORT_B, BIT_8);//From the Table derived earlier and Equation 1 we set the period to
62500
unsigned int gui_TimerCount = 0;
//Open Timer 1 and configure it
OpenTimer1(T1_ON | T1_IDLE_CON | T1_PS_1_64 | T1_SOURCE_INT, 62500);
while(1)
{
//read the timer value and act accordingly
gui_TimerCount = ReadTimer1();
if(gui_TimerCount == 62500)
{
//invert the RB8 port state
mPORTBToggleBits( BIT_8);
WriteTimer1(0);}
}
return (EXIT_SUCCESS);
}
The code above will blink the LED on RB8 at 200 ms ON & OFF. First lest discuss OpenTimer1() macro.
OpenTimer1(T1_ON | T1_IDLE_CON | T1_PS_1_64 | T1_SOURCE_INT, 62500);
The first parameter takes the options of how to setup your timer, those are nothing more than a “define” for
each bit from the T1CON register. For example T1_ON & T1_OFF controls bit 15 in T1CON Register
setting it to 1 or 0, either enabling Timer 1 or turning it off. The T1_IDLE_XXX flag is a bit that controls
whatever timer will run in sleep mode or not, in our case T1_IDLE_CON means it will and T1_IDLE_STOP
will make it stop if the PIC enters sleep mode. The other flags are explained below:
T1_PS_1_64 – Sets the pre-scale value to 1:64. T1_PS_1_XX sets it to a different pre-scale check the
datasheet for available pre-scale values.
T1_SOURCE_INT – Sets the Timer 1 Clock input to Internal, since we are using the internal peripheral
clock and not external one.
62,500 – This is the period that we calculated before required for the 200 ms On & OFF timing. Please note
we are not using it right now, setting this to 0 will have no effect on the result but soon I will explain how to
use it to optimize our code.
gui_TimerCount = ReadTimer1();
if(gui_TimerCount == 62500)
{
//invert the RB8 port state
mPORTBToggleBits( BIT_8);
WriteTimer1(0);
}
In this section of the code we first read the timer 1 count register, then check if its equal to our period. If the
count matches we Toggle Port B pin 8 and set the count to 0. If it does not match we wait for another read
in the next loop irritation. We can optimize this code and free some CPU cycles by changing the above
code to this:
Version 2:
if(mT1GetIntFlag())
{
//invert the RB8 port state
mPORTBToggleBits( BIT_8);
mT1ClearIntFlag();
}
Why is this faster? Simply put even thou we are not using any interrupts the flags still get set when a match
happens except the PIC ignores it. We can still use it, sometimes this method is called software pooling but
don’t quote me on that. In this case when we used OpenTimer() macro, the 2nd parameter is a period
parameter and its used to set the PR1 register for Timer 1. The PIC hardware constantly compares the
Count register (TMR1) with this Period register (PR1) and if a match is found it sets the INT flag
independent of the user software. We then just check if the Flag was set, if it was, our Count register
reached our desired value of 62500 and so we toggle the LED. Also note that the hardware automatically
clears the Count register on a period match so we don’t have to do it as before. The only thing we must do
is clear the Int Flag bit so that we can get the next match at the correct time, otherwise it will be set all the
time and our if statement will always be true. This concludes Timers tutorial. Next time we will cover
Interrupts and how they apply to timers among many things.
Other Useful Functions
 unsigned int ReadPeriod1(); – Reads the period register of the Timer 1, ReadPeriodX() – Reads the
Period register of Timer module X
 void WritePeriod1(unsigned int v) – Writes the period register of Timer 1, WritePeriodX(unsigned int
v) – Writes the Period register of Timer Module X.
Full Source Code
#include <stdio.h>
#include <stdlib.h>
#include <p32xxxx.h>
#include <plib.h>
//config bits
// DEVCFG3
// USERID = No Setting
#pragma config PMDL1WAY = OFF
// Peripheral Module Disable Configuration (Allow only one reconfiguration)
#pragma config IOL1WAY = OFF
// Peripheral Pin Select Configuration (Allow only one reconfiguration)
#pragma config FUSBIDIO = OFF
// USB USID Selection (Controlled by Port Function)
#pragma config FVBUSONIO = OFF
// USB VBUS ON Selection (Controlled by Port Function)
// DEVCFG2
#pragma config FPLLIDIV = DIV_4
// PLL Input Divider (1x Divider)
#pragma config FPLLMUL = MUL_16
// PLL Multiplier (16x Multiplier)
#pragma config FPLLODIV = DIV_2
// System PLL Output Clock Divider (PLL Divide by 2)
// DEVCFG1
#pragma config FNOSC = PRIPLL
// Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = OFF
// Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF
// Internal/External Switch Over (Disabled)
#pragma config POSCMOD = HS
// Primary Oscillator Configuration (HS osc mode)
#pragma config OSCIOFNC = OFF
// CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_2
// Peripheral Clock Divisor (Pb_Clk is Sys_Clk/2)
#pragma config FCKSM = CSDCMD
// Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576
// Watchdog Timer Postscaler (1:1048576)
#pragma config WINDIS = OFF
// Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF
// Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FWDTWINSZ = WISZ_25
// Watchdog Timer Window Size (Window Size is 25%)
// DEVCFG0
#pragma config JTAGEN = OFF
// JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx1
// ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1)
#pragma config PWP = OFF
// Program Flash Write Protect (Disable)
#pragma config BWP = OFF
// Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF
// Code Protect (Protection Disabled)
int main(int argc, char** argv)
{
//Config the I/O – To flash the LED on PORT B pin 8, RB8
PORTSetPinsDigitalOut(IOPORT_B, BIT_8);
PORTClearBits(IOPORT_B, BIT_8);
//Calculate the required period
//with a prescale of 1:64 we need 200 ms so count to 62,500 starting at 0
OpenTimer1(T1_ON | T1_IDLE_CON | T1_PS_1_64 | T1_SOURCE_INT, 62500);
while(1)
{
//Check the Timer Value Int Flag to check for a match
if(mT1GetIntFlag())
{
//invert the RB8 port state
mPORTBToggleBits( BIT_8);
mT1ClearIntFlag();
}
}
CloseTimer1();
return (EXIT_SUCCESS);
}
To test this code connect an LED to the PIC (PIN 17 – RB8). Don’t forget a resistor
Can you do it?
 Blink the LED at 100, 500 ms ON & OFF ?
 Blink the LED at 1 sec Interval ? (HINT: Try 32 bit timer pair)
 Blink 2 LED’S at Different rate ? (HINT: Try 2 Timers)
Good Luck!
PIC32 Tutorial 4-UART Communication
Posted by Manor on February 24, 2012
Posted in: Tutorials. Tagged: 32 bit microcontroller, array, baud, baudrate, c, c
programming, CAN, character,characters, communication, ft232, ft232r, ft232rl, getting
started, guide, MPLAB, pic microcontroller, pic32,pic32mx220, pic32mx220f032, pic32mx220f032b, pickit
3, pickit3, programming, rate, serial, serial communication,started, string, tutorial, uart, uart1, uart2. 12
comments
Tutorial 4-UART Communication
UART is a type of serial protocol used to communicated between devices. It is especially useful when you
are learning to program. It can be used for debugging purposes. For example, you programed your PIC32
to interrupt every time Timer 1 refreshes (1 Hz) and in the interrupt routine you are toggling an LED. Your
code seems to be properly designed but the LED is not Blinking. One way to debug the issue is to send the
value of Timer 1 to UART so you can see if it actually counting. Another application can be have multiple
Microcontrollers working together to achieve a larger task ( a robot, helicopter , and so on). UART is also
used to receive sensor information. Other Serial communications that are used today are I2C, CAN, 1-Wire,
and SPI.
Materials
Everything from PIC32 Tutorial 0-Setting up and:
 FT232RL USB to Serial
 Extra USB mini-B cable
 Male Headers
Datasheets
 PIC32MX220F032B datasheet
 PIC32MX Family Reference Manual
 FT232RL Datasheet
Software
 Realterm 2.0.0.57 (Freeware-direct download)
Step 1 ( Preparing the FT232RL )
Solder in 4 header pins to the GND, RX-I, TX-O, and 3.3V. You will probably not need to use any other pinouts from the board. I chose to have the LEDs facing upwards so I could see when information is being sent
and received. You can power the PIC32MX220F032B from this breakout board by connecting the 3.3V to
the positive (+) bus and GND to the negative (-) bus (Make sure to uncheck the setting in MPLAB-X “Power
Target Circuit from PICKit3″ shown in PIC32 Tutorial 0-Setting up.)
Next you should connect the USB cable to your computer and make sure the Serial Converter Driver
installs properly. (Windows 7 does all the work for us.)
Step 2 ( Choosing pins for UART )
The PIC32MX220F032B has 2 UART modules (I will use UART1.) Because there are only 28 pins on this
device Microchip could not dedicated pins just for these modules, they allow multiple modules to use the
same pins at different times. We need to assign pins before we are able to configure the module. The pins
that are allowed to be assigned to are represented by RPXX where XX are the pin. An Example would be
RPB4 (Pin 11) and RBA4 (Pin 12). There are other pins that available for assigning, but we need the
chosen pins to be linked to UART1. That information is found again in the PIC32MX220F032B datasheet on
pages 146 and 148. These snippets provide us with relevant information.
UART1 RX
UART1 TX
It turns out that the pins I used for example before can be used as U1RX and U1TX. Surprised? RPB4 (Pin
11) is going to be used as U1TX and RPA4 (Pin 12) is going to be used as U1RX. You can now connect the
RX-I from the FT232RL breakout board to U1TX (Pin 11) on the PIC32MX220F032B. Next you can connect
the TX-O from the FT232RL breakout board to U1RX (Pin 12).
Step 3 ( Code )
You can create a new project for this tutorial by following PIC32 Tutorial 0-Setting up. In the configuration
bits there are two bits that are of interest to us right now, the “PMDL1WAY” and “IOL1WAY”. These
configuration settings are set to “OFF”. This indicates that once the device is restarted the user (us) is
allowed to change module-pins only ONCE. Choosing “ON” for these bits will allow us to reconfigure the
pins and modules while the microcontroller is operating. There is a particular sequence that must be
performed in the correct order to achieve this. In this tutorial we will leave these as OFF.
Configuring the pins to be used with the UART1 module is demonstrated below
int main()
{
// Create a UART TX/RX Pin
SYSKEY = 0xAA996655;
// Write Key1 to SYSKEY
SYSKEY = 0x556699AA;
// Write Key2 to SYSKEY
//All Pin configurations should start here
RPB4Rbits.RPB4R=1;
//Sets RPB4 as U1TX. (pin 11)
U1RXRbits.U1RXR=2;
//Sets RPA4 as U1RX. (pin 12)
//All Pin configuration should end here
SYSKEY = 0;
// Locks the pin Configurations
//End UART TX/RX Pin
As you can see the first few command in main() are configuring the pins. The pin configuration MUST be
the first to be configured.
Next we need to configure the UART to function at our preferences: Baud rate 9600. (The rest can be left
on default)
//Initilize UART1
int PB_CLOCK=20000000;
int BAUD=9600;
OpenUART1(UART_EN|UART_BRGH_FOUR, UART_RX_ENABLE | UART_TX_ENABLE, PB_CLOCK / (4 * BAUD) – 1);
//END UART1 Initialization
We set the Peripheral clock to be half of the system clock (40,000,000 / 2 = 20,000,000.) The desired
BAUD rate is 9600. Microchip has provided us with a macro to open and configure
UART1. OpenUART1(UART_EN|UART_BRGH_FOUR, UART_RX_ENABLE | UART_TX_ENABLE,
PB_CLOCK / (4 * BAUD) – 1) :
 Enables the module
 Sets BRGH = 1 which uses this equation found on page 720 of the PIC32MX Family Reference
Manual.
 Enables the RX part of the module
 Enables the TX part of the module
 Provides the value of U1BRG ( this value is not the BAUD rate but will generate the correct BAUD
rate)
 Turn on the module
UART1 is now ready to transmit and receive information. Plug in your USB from the FT232RL breakout
board. Then open up Realterm with administrative rights ( right click the icon and select “Run as
Administrator”.) In the Display tab choose “Ansi” and check “newLine Mode”. In the Port tab choose 9600
for BAUD and select your proper port ( it should be the only one selected. Mine is 3) Make sure you click on
“Change”. If you do not click on change you have not made any changes in the program. Your terminal
should look similar to :
Lets paste the next snippet of code:
char filename[50] ;
//Array of 50 chars
memset(filename,0,50*sizeof(char));
//Clears the Array
sprintf(filename, “EEDesignLabs.com\nTutorial 4 – UART Communication\n”);
//Places the String into the Array
// “\n” is a special char which is defined as a newline
putsUART1(filename);
//Sends the Array over UART1
This code will output:
If you place the above code in the While(1) loop you will see that UART1 is constantly sending the same
lines over and over again. As expected! You can now send strings over UART!! Lets try sending a variable
that the PIC32 is changing. The next snippet of code :
char filename[50] ;
//Array of 50 chars
memset(filename,0,50*sizeof(char));
//Clears the Array
sprintf(filename, “Tutorial 4 – UART Communication\nIncrementing Variable\n”); //Places the String into the Array
putsUART1(filename);
//Sends the Array over UART1
int variable=0;
int index=0;
while (1)
{
sprintf(filename, “%d\n”,variable); //%d will get the value of the next argument in the function and place it in the string
putsUART1(filename);
//Sends the Array over UART1
variable++;
//Increments the variable by 1
for(index=0;index<4000000;index++) //a dummy function ot delay the loop
{
Nop(); // no operation for this cycle
}
}
Will produce:
The PIC can send all kinds of information but can we send information for processing? Of course!
We can send information over to the PIC using Realterm’s Send tab. Type in anything you wish in the text
window and press ” Send ASCII”. Nothing happens. The PIC receiver what you sent but it doesn’t know
what to do with that information. We can fix that! We can send anything from the PIC to the computer but
we do not see what the microcontroller is receiving when we send it a string. If we could only send the
computer EXACTLY what we receive… Guess what? We can. In fact it is called a Loop-Back. Replace the
previous snippet code with this one.
char filename[50] ;
//Array of 50 chars
memset(filename,0,50*sizeof(char));
//Clears the Array
sprintf(filename, “Tutorial 4 – UART Communication\nLoopBack\n”); //Places the String into the Array
putsUART1(filename);
//Sends the Array over UART1
memset(filename,0,50*sizeof(char));
//Clears the Array
while (1)
{
while(U1STAbits.URXDA)
{
getsUART1(50, filename, 123); //Receives up to 50 characters from UART 1 and stores it in “filename” array
U1STAbits.URXDA =0;
//Clears the URXDA bit so the UART continues to receive
U1STAbits.OERR = 0;
//Clears the OERR bit so UART clears buffer and receives new characters
putsUART1(filename);
//send the buffer, filename, over UART1
memset(filename,0,50*sizeof(char)); //Clears the buffer
}
}
Try sending something now. You should see something similar to: ( your strings will be different)
UART communication is a VERY powerful tool. It can be used in many applications and debugging. I use
UART for debugging in EVERY project.
Try It Out
Hints are in [ ]
* Advanced
 Using Timers have the PIC send out the Current time in 1 sec increments. Then 0.1 sec increment.
Then 0.01 increments. [Have the user give the Current time. Then the PIC can update and send the
new current time. Use %f to display float variables. You might need to increase the BAUD rate on
the PIC and Realterm]
 Control an LED over UART. [Send a pin number,1 or 0. A command to send would be "16,1" to turn
on pin 16 while "16,0" would be turning it off]
 Make your PIC32MX220F032B a UART calculator. [Have PIC send a menu of commands like : add,
subtract, multiply, and divide. User chooses an operation. PIC asks for values then responds with a
solution[You will need to look up functions that can convert strings to actual values atoi atof ...]]
 * Make your PIC32 a telephone book [Use EEPROM to store information so when you power down
the information is stored. Another communication protocol might need to be used]
Useful Libraries
Search for these in your Microchip folder. Skim them for a full list of functions and arguments.
 uart_leacy.h
 string.h
 stdlib.h
Download