Microcontroller Code

advertisement
Microcontroller Code Example Explanation and Words of Wisdom
For Senior Design
For use with the following equipment:
• PIC16F877
• QikStart Development Board
• ICD2 Debugger
• MPLAB Environment
• exampleMain.c and exampleLCD.c
Project Build Instructions:
To get this example program working with MPLAB take the following steps:
1. Create a new folder in your Z: drive titled Example Code.
2. Copy the exampleMain.c and exampleLCD.c files into the folder.
3. Open MPLAB and select Project -> Project Wizard.
4. Follow the wizard selecting the PIC16F877.
5. Select the HI-TECH Universal ToolSuite and click NEXT.
6. Browse to select your Example Code folder and name your project.
7. Click NEXT and add the two .c files to the list.
8. Click the A next to each of the added files and make sure they change to a U.
9. Finish the wizard.
10. If nothing appears automatically select View-> Project and double-click the .c files in the
window that appears.
Project Run Instructions:
1. Make sure your board is powered and connected to the computer through the ICD2 debugger.
2. Select Debugger-> Select Tool-> MPLAB ICD 2.
3. Click the black Build icon on the toolbar to build the code.
4. Once the build is finished click the Program Target Device icon on the toolbar.
5. Wait for the device to be programmed (this takes some time) and then click the Run button on
the toolbar.
6. The program should be running on the QikStart board now.
Using the Program:
This program does a number of things that can be seen and interacted with on the QikStart board. Upon
running the program you should notice the array of LEDs on the right blinking on and off every 0.5
seconds. The LCD screen should also read “BLINK” on the first line and “PRESS ENTER” on the second
line.
Follow the directions on the LCD screen by pressing and holding the ENTER button on the board. Notice
that the program does not change until you release the button. Once the button is release the lights will
stop blinking and the LCD will display “A/D CONVERT” on the first line and “TURN RP1” on the second
line. Again, follow the directions and turn the RP1 potentiometer back and forth. Notice that now,
instead of blinking, the LEDs turn on or off in sequence with the turning of the potentiometer.
Pressing the ENTER button again brings the program back to the original LCD message and the blinking
LEDs. The program that runs the board this way is relatively simple, but demonstrates a number of
useful embedded programming techniques and tools. Look at the code in the exampleMain.c file in
MPLAB. You will notice that it is broken down into functions. Each function serves a specific purpose and
fulfills a need of the overall program. The functions will all be broken down to their components by this
paper, but it is important to note that understanding them will require considerable cross-reference to
both the PIC16F877 datasheet and the QikStart board schematic. A serviceable amount of C
programming language competency is required to follow what is going on and it is strongly
recommended that you read up on C code if you are unfamiliar with the language.
Top of the Code:
Look at the exampleMain.c from the top. The first part is commented instructions and should be read,
but have no effect on the program. Next comes the #include statements. These are standard and should
be in every program you right for PICs. They specify the library of terms the microcontroller will
recognize. The __CONFIG() function serves to setup some of the basic components of the PIC. The only
one that might be changed by programs you write is the XT. This refers to the type of oscillator input and
should be changed to RC if a 555 timer circuit is used instead of a crystal oscillator.
The #define that comes next demonstrates how this functionality of the C language can be used to
assign useful names to heavily used registers. This can make it easier to remember what your program is
doing during debugging. The top of the code is rounded out by function and global variable declarations,
which should be familiar to you.
Initialization Code:
Skip down to where the comments say Initial Subroutine. This is the initialization function. This is run
once after the microcontroller is reset. The initialization routine defines starting parameters for the A/D
converter, the input/output state of almost every pin on the PIC, the on-board timers, interrupts, and
initial values of variables. The initialization routine is extremely important to the program. When writing
code make sure all of your important registers are initialized correctly. Many problems can be solved by
taking care that your registers are setup correctly!
The following registers are very important to get right in the initialization:
•
•
•
•
•
ADCON1 – This register is responsible for setting up which pins can do A/D conversion. Use the
information about this register in the datasheet to set the appropriate binary number for the
number of analog signals.
ADCS0 – This bit finishes the initialization of the oscillator for A/D conversion.
TRISA-E – These registers define whether a pin is an input or an output. Use the pinout diagram
in the datasheet to determine which pins need to be inputs/outputs. Set an 8 digit binary
number for each of these, where the each bit of the number correspond to their respective pin
in of the port. Set a 1 for an input and a 0 for an output.
PR2/T2CON – This sets up TIMER2 and the TIMER2 interrupt, which is beyond the scope of
these instructions (read the datasheet).
INTCON – This sets up interrupts on the PIC. The default for this program is to have them
enabled, but only timing interrupts are used.
The Main Program Loop:
Skip down to the bottom of the program and find the main function. This function is where everything
starts and eventually returns to. It calls the Initial function the first time it runs, and then enters a
continuous FOR loop. This FOR loop runs through its function calls until the PIC is reset. Using this
technique the PIC is able to continuously monitor the various inputs and output of the peripheral
functions and service events as they occur.
The Button Push Function:
This is the first function called in the FOR loop of the main function. It serves to monitor the state of the
ENTER button. The first IF statement is satisfied when the button is pressed. ENTER_BUTTON becomes
equal to 0 and the code sets the ChangState flag to remember the event. The function then returns to
main. The function will continue to do this every time it is called, until the button is released.
Once the button is released the first IF statement is no longer satisfied, so it moves onto the next one.
This IF statement is satisfied when it sees that the ChangeState flag is set. The body of this IF statement
resets the ChangeState flag and increments the mode counter. It also resets the mode counter if the
final mode is active at the time. Try to figure out which parts of the IF statement are accomplishing this.
The Blink Function:
This is a simple function designed to turn the array of LEDs on/off on a specific time interval. When it is
called it uses the bit toggle assignment operator (^=) to change all of the bits of PORTD to the opposite
of whatever their current state is. The function then waits for 0.5 seconds by calling the 10 ms LoopTime
routine 50 times. This makes the LEDs blink just about every 0.5 seconds. This is not exact, because the
program actually runs through another cycle, but this takes very little time compared to the 0.5 second
wait.
The LCD Function:
This function uses the DisplayC function from the exampleLCD.c file to write strings to the LCD screen.
The first IF statement determines whether there needs to be a change in the LCD display, based on what
the program wants displayed. If no change is needed the function returns to main to save time. If a
change is needed it first clears the resetLCD flag that signals that need for change. It then calls the
clear_display function from the exampleLCD.c file, which makes the LCD blank to avoid residual
characters.
The function then checks the DispMode variable to decide what to display. The DisplayC function is
used to write to the LCD. It takes a position parameter and a string parameter. The position parameter
to start writing at the top left is 0x80 and the bottom left is 0xC0.
The ADConvert Function:
This function takes an analog voltage level coming in from one of the pins and converts it to a digital
level in A/D counts. This description assumes the reader has previous experience with A/D conversion
and only explains the microcontroller implementation. The converter on the PIC16F877 is a 10-bit on
board converter. More information is available in the datasheet.
The assignments to CHS0-2 at the beginning of the function sets the analog input that will be converted.
The ADON bit is part of the ADCON0 register and setting it to 1 turns the A/D converter on for
conversion. The FOR loop is required to allow time for the converter to settle after being turned on. It
takes roughly 30 us. Setting ADGO to 1 begins the A/D conversions and while(ADGO) waits until the
conversion is finished before moving on. The assignment following takes the two A/D conversion results
registers and combines them into one 10-bit value. Read the datasheet regarding how the results of the
A/D converter are stored for more information. The final assignment of the ADON bit is to turn off the
A/D converter, which saves power.
The ShowAD Function:
This function is intended to display the level of the analog signal acquired by the A/D converter. The
structure of this function is a long IF statement with a number of possible cases. The statement runs
through and checks whether the adValue is less than a particular threshold. If the adValue is below the
threshold it sets the appropriate number of LEDs to on. If the adValue is above the threshold it moves
on to check the next threshold.
Wrap Up:
This document describes the basic function of this relatively simple program. The techniques covered
are important to know for programming microcontrollers. Now that you know basically what is going on
take time to go through and thoroughly find the connections between what is happening in the code,
and how it uses the circuit shown in the schematic. Use this code as a jumping off point for developing
your own programs. Some of the routines can be cut and pasted and expanded into much more complex
functions. This microcontroller can be programmed to do much more than has been shown and the
datasheet has information for all of it. Combine knowledge of the circuit you are using with knowledge
about how the microcontroller works and your programs will work. Use your imagination and do not
feel constrained to using only what has been demonstrated.
Note: This document did not cover specifics of the exampleLCD program, but you are definitely
encouraged to take a look and try to figure out what is happening.
Download