Файл: Microcontroller Programming. Thi Micro Chip PIC (Julio Sanchez, 2007).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.06.2025
Просмотров: 8583
Скачиваний: 0
172 |
Chapter 9 |
The View menu contains several commands that provide useful features during program simulation and debugging. These include commands to program memory, file registers, EEPROM, and special function registers. One command in particular, named <Watch>, provides a way of inspecting the contents of FSRs and GPRs on the same screen. The <Watch> command displays a program window that contains references to all file registers used by the program. The user then selects which registers to view and these are shown in the Watch window. The Watch window is shown in Figure 9-9.
Figure 9-9 Use of Watch Window in MPLAB SIM
When the program is in the single-step mode or breakpoint modes, the contents of the various registers can be observed in the Watch window. Those that have changed since the last step or breakpoint are displayed in red. The user can click the corresponding arrows on the Watch window to display all the symbols or registers. The <Add Symbol> or <Add FSR> button is then used to display the item on the Watch screen. Four different Watch windows can be enabled, labeled Watch 1 to Watch 4 at the bottom of the screen in Figure 9-9.
Another valuable tool available from the View menu is the one labeled <Simulator Trace>. The Simulator Trace window provides a view of the machine instruction combined with a window that displays the source code. The Simulator Trace window is shown in Figure 9-10.
9.2.2 MPLAB Hardware Debuggers
A more powerful and versatile debugging tool is a hardware or in-circuit debugger. Hardware debuggers allow tracing, breakpointing, and single-stepping through code while the PIC is installed in the target circuit. The typical in-circuit debugger requires several hardware components, as shown in Figure 9-11.
PIC Programming: Tools and Techniques |
173 |
Figure 9-10 MPLAB SIM Simulator Trace Window
Power cable
Communications cable
Emulator pod
Processor
module
Cable to Logic circuit probe
connector
Adapter
Transition
socket
Figure 9-11 Components of a Typical Hardware Debugger
174 |
Chapter 9 |
The emulator pod with power supply and communications cable provides the basic communications and functionality of the debugger. The communications line between the PC and the debugger can be an RS-232, a USB, or a parallel port line. The processor module fits into a slot at the front of the pod module. The processor is de- vice-specific and provides these functions to the debugger. A flex cable connects the processor module to an interchangeable device adapter that allows connecting to the several PICs supported by the system. The transition socket allows connecting the device adapter to the target hardware. A separate socket allows connecting logic probes to the debugger.
Microchip provides two models of their in-circuit hardware debuggers, which they call In-Circuit Emulators, or ICEs. The ICE 2000 is designed to work with most PICs of the mid-range and lower series, while the ICE 4000 is for the PIC18x high-end family of PICs. Recently Microchip has released an in-circuit debugger designated as ICD 2 that offers many of the features of their full-fledged in-circuit emulators at a much reduced price. One of the disadvantages of the ICD 2 system is that it requires the exclusive use of some hardware and software resources in the target. Furthermore, the ICD requires that the system be fully functional. The ICEs, on the other hand, provide memory and clocks so that the processor can run code even if it is not connected to the application board.
9.2.3 A “Quick-and-Dirty” Debugger
The functionality of an actual hardware debugger can be replaced with a little ingenuity and a few lines of code. Most PICs are equipped with EEPROM memory. Programmers (covered in the following section) have the ability to read all the data stored in the PIC, including EEPROM. These two facts can be combined to obtain run-time information without resorting to a hardware debugger.
Suppose a defective application is suspected of not finding the expected value in a PIC port. The developer can write a few lines of code to store the port value on an EEPROM memory cell. An endless loop following this operation ensures that the stored value is not changed. Now the PIC is inserted in the circuit and the application executed. When the endless loop is reached, the PIC is removed from the circuit and placed back in the programmer. The value stored in EEPROM can now be inspected so as to determine the run-time state of the machine. In many cases, this simple trick is less complicated and time consuming than setting up a hardware debugger, even if such a device is available.
9.3 Programmers
In the context of microcontroller technology, a programmer is a device that allows transferring the program onto the chip. The process is called “burning” a PIC, or more commonly “blowing” a PIC. Most programmers have three components:
1.A software package that runs on the PC
2.A cable connecting the PC to the programmer
3.A programmer device
PIC Programming: Tools and Techniques |
175 |
Dozens of PIC programmers are available on the Internet. When Microchip released the programming specifications of the PIC to the public without requiring a nondisclosure agreement, they originated a cottage industry. The commercial programmers on the Internet range from a “no parts” PIC programmer that has been around since 1998, to sophisticated devices costing hundreds of dollars and providing many additional features and refinements. For the average new PIC user, a nice USB programmer with a ZIF (zero insertion-force) socket and the required software can be purchased for about $50.00. Build-it-yourself versions are available for about half this amount.
An alternative programmer is made possible by the fact that some of the newer flash-based PICs can write to their own program memory. This allows placing a small bootloader program in PIC memory which loads an application over the RS-232 or USB lines.
Figure 9-12 is a screen capture of the driver software for a popular programmer from MicroPro.
Figure 9-12 Control Program for the DIY MicroPro Programmer
9.4 Engineering PIC Software
The program developer’s main challenge is writing code that performs the task at hand. In this context this means writing a PIC assembly language program that assembles without errors (usually after some effort) and makes the circuit perform as intended. We have already reviewed the IDE (integrated development environment) and
176 |
Chapter 9 |
the various hardware components and software tools. We now focus on the various elements that are used in developing the program itself.
9.4.1 Using Program Comments
One of the first realizations of beginning programmers is how quickly we forget the reasoning and logic that went into our code. It is common that a few weeks, even a few hours, after we coded a routine we find that what was obvious then is now undecipherable and that the ideas that were clear in our minds a short time ago now evade our understanding. The only solution is to write good program comments that explain, not the elementary, but the trains of thought behind our code.
In PIC assembly language, the comment symbol is the semicolon (;). The presence of a semicolon indicates to the assembler that everything that follows, to the end of the line, must be ignored. Using comments judiciously and with good taste is the mark of the expert software engineer. Programs with few, cryptic, or confusing comments fall into the category of “spaghetti code.” In programming lingo, “spaghetti code” refers to a coding style that cannot be deciphered or understood. One of the worst offenses that can be said about one’s programming style is that it is spaghetti code.
How we use comments to explain our code or even to embellish it is a matter of personal preference. However, there are certain common sense rules that should always be considered:
1.Do not use program comments to explain the programming language or reflect on the obvious.
2.Abstain from humor in comments. Comedy has a place in the world but it is not in programs. By the same token, stay away from vulgarity, racial or sexist remarks, and anything that could be offensive. You can never anticipate who will read your code.
3.Write short, clear, readable comments that explain how the program works. Decorate or embellish your code using comments according to your tastes.
Program Header
Every program should have a commented header that contains the following information:
1.Program name
2.Programmer’s or software company’s name
3.Copyright notice, if pertinent
4.Target device or hardware
5.Development environment
6.Development dates
7.Program description
PIC Programming: Tools and Techniques |
177 |
Some of these elements allow various levels of detail. For example, the target device can be a simple reference to the PIC for which the program is written, a more-or-less detailed description of the target system, or a reference to a circuit diagram or board drawing. The development environment can also be described briefly or in detail. The date element can be a single entry that lists the first or the last program change, or a detailed description of all program changes, tests, and updates. The program description can be a short sentence or a mini-manual on using the application. In any case, the level of detail and the contents of each category are determined by the programmer’s style and the complexity and purpose of the application.
The following lines show the header of one of the programs developed for this book:
;File name: RTC2LCD.asm
;Last Update: June 6, 2006
;Author: Julio Sanchez
;Processor: 16F84A
;Description:
;Program to demonstrate use of the NJU6355 Real Time Clock
;IC. Program uses LCD to display results in hours, minutes,
;and seconds, as follows:
;
;Top LCD line: H:xx M:yy S:zz
;Initialization values are in #define statements that start
;with i, such as iYear, iMonth, etc.
;
;For LCD display parameters see the LCDTest2 program.
;WARNING:
;Code assumes 4Mhz clock. Delay routines must be
;edited for faster clock
Commented Banners
Often, we need to scroll through the code in search of a particular line or routine. Having banners that signal critical places in the program facilitates this search. Banners are created using comments and a framing symbol, as in the following code fragment:
;===============================
;first text string procedure ;=============================== storeMS1:
;Procedure to store in PIC RAM buffer the message
;contained in the code area labeled msg1
;ON ENTRY:
;variable pic_ad holds address of text buffer
;in PIC RAM
;w register hold offset into storage area
;msg1 is routine that returns the string characters
;and a zero terminator
;index is local variable that hold offset into
;text table. This variable is also used for
;temporary storage of offset into buffer
178 |
Chapter 9 |
Sometimes, the programmer needs to emphasize a program area with a large banner that extends from margin to margin, as follows:
;============================================================
;============================================================ ; L O C A L P R O C E D U R E S ;============================================================ ;============================================================
;==========================
;init LCD for 4-bit mode ;========================== initLCD:
;Initialization for Densitron LCD module as follows:
;4-bit interface
;2 display lines of 20 characters each
;cursor on
;left-to-right increment
;cursor shift right
;no display shift
Commented Bitmaps
It is also possible to use comments to signal the function of bit fields and individual bits of an operand, as in the following code fragment:
; OPTION_REG |
bitmap |
||||||||||
; |
7 |
6 |
5 |
4 |
3 |
2 1 0 <= OPTION bits |
|||||
; |
| |
| |
| |
| |
| |
|__|__|_____ |
PS2-PS0 (prescaler bits) |
||||
; |
| |
| |
| |
| |
| |
Values for Timer0 |
|||||
; |
| |
| |
| |
| |
| |
000 |
= 1:2 |
001 |
= 1:4 |
||
; |
| |
| |
| |
| |
| |
010 |
= 1:8 |
011 |
= 1:16 |
||
; |
| |
| |
| |
| |
| |
100 |
= 1:32 |
101 |
= 1:64 |
||
; |
| |
| |
| |
| |
| |
110 |
= 1:128 *111 |
= 1:256 |
|||
; |
| |
| |
| |
| |
|______________ |
PSA |
(prescaler assign) |
||||
; |
| |
| |
| |
| |
*1 |
= |
to WDT |
||||
; |
| |
| |
| |
| |
0 |
= |
to Timer0 |
||||
; |
| |
| |
| |
|_________________ |
TOSE (Timer0 edge select) |
||||||
; |
| |
| |
| |
*0 |
= |
increment on |
low-to-high |
||||
; |
| |
| |
| |
1 |
= |
increment in |
high-to-low |
||||
; |
| |
| |
|____________________ |
TOCS (TMR0 clock |
source) |
||||||
; |
| |
| |
*0 |
= |
internal clock |
||||||
; |
| |
| |
1 |
= |
RA4/TOCKI bit source |
||||||
; |
| |
|_______________________ |
INTEDG (Edge select) |
||||||||
; |
| |
*0 |
= |
falling edge |
|||||||
;|__________________________ RBPU (Pullup enable)
; |
*0 = enabled |
; |
1 = disabled |
; * indicates options selected |
|
movlw |
b’00001000’ ; Value installed |
movwf |
OPTION_REG |
Clearly commented bitmaps, banners, and many other code embellishments do not add to the quality and functionality of the code. It is quite possible to write very sober and functional programs without using them. The decision of how to comment and embellish programs is one of style.
PIC Programming: Tools and Techniques |
179 |
9.4.2 Defining Data Elements
Most programs require the use of general purpose file registers. These registers are allocated to memory addresses reserved for this purpose in the PIC architecture, as shown in Figure 8-8 and Figure 8-9. Since the areas at these memory locations are already reserved for use as GPRs, the program can access the location either by address or by assigning to that address a name. The equ (equate) directory performs this function, as follows:
var1 equ 0x0c ; Name var1 is assigned to location 0x0c
Actually, the name (in this case var1) becomes an alias for the memory address to which it is linked. From this point on, program code can access the memory cell at address 0x0c as follows:
movf var1,w ; Contents of var1 to w
or:
movf 0x0c,w ; Same variable to w
In addition to the equ directive, PIC assembly language recognizes the C-like #define directive, so the name assignation could be done as follows:
#define var1 0x0c
Although most of the time-named variables are to be preferred to hard-coding addresses, there are times when we need to access an internal element of some multi-byte structure. In these cases, the hard-coded form could be convenient, although not absolutely necessary.
The cblock Directive
Another way of defining memory data is by using one of the data directives available in PIC assembly language. Although there are several of these, perhaps the most useful is the cblock directive. The cblock directive specifies an address for the first item and other items listed are allocated from this first address. The group ends with the endc directive. The following code fragment shows the use of the cblock/endc directives.
;Reserve 20 bytes for string buffer cblock 0x20
strData endc
;Reserve three bytes for ASCII digits cblock 0x34
asc100
asc10
asc1 endc
In reality, the cblock directive defines a group of constants which are assigned consecutive addresses in RAM. In the previous code fragment the allocation of 20 bytes for the buffer named strData is illusory since no memory is actually reserved. The illusion works because the second cblock starts at address 0x34 which is 20 bytes after strData, and also because the programmer abstains from allocating other variables in the buffer space.
180 |
Chapter 9 |
9.4.3 Banking Techniques
Having to deal with memory banks is one of the aggravations of PIC programming. Banks are numbered starting with bank 0. All PICs of the mid-range family have at least two banks, so bank shifting operations are virtually unavoidable. The issue is more how to switch bank designation since there are several possible techniques.
Bank selection is by means of bit RP0 and RP1 in the STATUS register. In mid-range PICs with four banks, the various combinations are as shown in Table 9.1.
Table 9.1 |
|||||
STATUS Register Bank Selection Bits |
|||||
RP1 |
RP0 |
BANK |
ADDRESS RANGE |
||
1 |
1 |
*Bank 3 |
0x180 |
- 0x1ff |
|
1 |
0 |
*Bank 2 |
0x100 |
- 0xx17f |
|
0 |
1 |
Bank 1 |
0x80 |
- 0xff |
|
0 |
0 |
Bank 0 |
0x00 |
- 0x7f |
|
* RP1 bit is not used in devices with two banks
The most direct way to select the current bank is by clearing or setting the corresponding bits in the STATUS register. For example, to select bank 2 in a 4-bank device you could code:
bsf |
STATUS,6 |
; |
Set bit 6 |
in STATUS register |
bcf |
STATUS,5 |
; |
Clear bit |
5 |
The banksel Directive
Alternatively the application can use the banksel directive which selects the bank in which a particular register is located. For example, to select the bank in which the ADCON1 register is located code could be as follows:
banksel ADCON1
The banksel directive also works with registers defined by the user (GPRs).
Bank Selection Macros
An alternative way of performing bank selection is by coding the corresponding bank select macros. A macro is an assembler structure that allows defining a series of instructions inserted in the code every time the macro is referenced. The PIC macro language defines the following format:
label macro [arg1, arg2... argn]
.
.
.
endm
The ellipses are placeholders for the PIC instructions, assembler directives, macro directives, and macro calls. Macros are usually defined at the beginning of the program since forward references to macros are not allowed. The optional arguments passed to the macro (arg1, arg2, etc) are assigned values when the macro is