Designing Embedded Systems with PIC Microcontrollers - Principles & Applications

Book Support Page

Home (Embedded Know-How)

This page carries support information on the book, links to useful sites, and errata. The book is available in original English, and in Chinese Translation.

Why I Wrote this Book

About the Book

Table of Contents

Support for Instructors/Lecturers using this Book

Buy from the Internet

Support Information, by Chapter




Publicity about the Chinese edition.

Buy from the Internet


Why I Wrote this Book

Every year I found myself supervising a number of student projects which involved the design of some sort of AGV (Autonomous Guided Vehicle). Too many of these projects never "got off the ground", as students made non-optimum design decisions in areas like vehicle geometry, motor and power supply selection, and so on. From this sense of frustration the Derbot project arose. The aim of the Derbot was to give students a core AGV design, which gave them the basic chassis and electronics, but then allowed them flexibility to customise in the way they saw fit. Later I starting approaching publishers with the idea of writing a book which used the Derbot as the main example design. The first goal was to write a short book. However ideas kept getting added, leading to what is now a pretty solid book.  In its final form the book brings together both the experience we have had with the Derbot, alongside a wealth of professional embedded design experience.

About the Book
This book is a hands-on introduction to the principles and practice of embedded system design using the PIC microcontroller. Packed with helpful examples and illustrations, it gives an in-depth treatment of microcontroller design, programming in both assembly language and C, and features advanced topics such as networking and real-time operating systems. It is accompanied by a CD-ROM containing copies of all programs and software tools used in the text and a 'student' version of the C complier.

Designing Embedded Systems with PIC Microcontrollers: Principles and Applications is ideal for students of electronics, mechatronics and computer engineering. Engineers in industry and informed hobbyists will also find this book a valuable resource when designing and implementing both simple and sophisticated embedded systems using the PIC Microcontroller.

* Gain the knowledge and skills required for developing today's embedded systems, through use of the PIC microcontroller.

* Explore in detail the 16F84A, 16F873A and 18F242 microcontrollers as examples of the wider PIC family.

* Learn how to program in Assembler and C.

* Work through sample designs and design ideas, including a robot in the form of an autonomous guided vehicle (the Derbot).

* Accompanied by a CD-ROM containing copies of all programs and software tools used in the text and a 'student' version of the C complier.


Buy the Book through the Internet

from Elsevier Catalogue  

from Amazon (UK)

from Amazon (USA)

from Amazon (Canada)     

from Amazon (Germany)

from Amazon (France) 

from Amazon (Japan)

from Turing Books (Chinese Edition)

Support Information, by Chapter
All information on building the Derbot AGV appears in the Derbot site section.
Errata (except for tiny typos) appear in chapter sections.

Select the chapter you want to go to. 

Chapter 1 Chapter 7 Chapter 13 Chapter 19
Chapter 2 Chapter 8 Chapter 14 Chapter 20
Chapter 3 Chapter 9 Chapter 15 Appendix 2
Chapter 4 Chapter 10 Chapter 16 Appendix 3
Chapter 5 Chapter 11 Chapter 17 Appendix 5
Chapter 6 Chapter 12 Chapter 18 Book CD


Chapter 1
The book was completed just before Microchip entered the world of Digital Signal Processing, or of 16- and 32-bit microcontrollers. Therefore Section 1.5 is a little dated now. Go here for an up-to-date overview of Microchip microcontroller products.

Chapter 3

Page 60, 4th line: the last word should read "crystal", not "capacitor".

Page 57: In equation (3.4) and the equation directly above which leads into it, ROH should be replaced by ROL.

Figure 1.3 in the book shows a picture of the pingpong circuit made using a pcb. The circuit diagram appears in Appendix 2. A more compact version, now with connection for PICkit 2 programming, is shown below left. It can also be constructed on stripboard, as shown below centre; a more compact component distribution is of course possible. Finally it can be built on a prototyping system, as below right (with thanks to Jim Wicks).  Click on any image to expand.


Find instructions to make this version here.

Chapter 4

Chapter 5

Programming Exercise 5.7
It is intended that this runs with the original Fibonacci program, i.e. Program Example 5.6. If run with the version of Program Example 5.7 a stopwatch value of 226us is reported.

A Note on Case Sensitivity in MPLAB
From Program Example 5.7 the book starts using Include Files, described on Page 106. From this point case sensitivity in MPLAB must be disabled, as the Include File uses symbols written in upper case, while the book programs are written in lower case. Access case sensitivity (in MPLAB ver. 7.22) by clicking Project -> Build Options -> Project ->MPASM Assembler (or Project -> Build Options -> project name). An example of Assembler errors if this is not done is seen in Development Tools: Frequently Asked Questions.

A Note on Trace Displays
Figure 5.9 in the book shows an MPLAB Version 7.20 screen print. It has the line numbers running from 0 to +142, where the breakpoint occurs.

More recent versions of MPLAB have the line numbers counting up from a negative number, to line 0, where the breakpoint occurs. Both versions display from top to bottom. The difference is that one ends on line 0, while the other starts there!

Another difference is that  the Trace display in Version 7.20 treats all branches as single line instructions, while later versions gives them two lines each. It's as if this version is actually showing the flow of instructions in the pipeline. Thus every branch instruction is accompanied by a NOP. Therefore, for the same Trace operation, there are more lines in a Version 7.4 Trace, compared to a Version 7.20 one.

The equivalent screen image for Figure 5.9, using Version 7.22, is shown below. Notice the NOP in line -5 which follows the GOTO instruction. The total number of lines in this Trace is 165. If you count all of these NOPs, and subtract that from 165, you get to the 142 lines of Figure 5.9. Interestingly, the number of cycles is the same in each print, except that the book print does not indicate that the final GOTO instruction will take 2 cycles.

Page 92: the explanation relating btfsc and btfss in the second to last paragraph is reversed.
Page 96: first line last paragraph, should read "The simple delay loop of Program Example 5.2...."
Page 108: Program Example 5.9, last two lines should read:

           bfbclr porta,4,wait ;go to wait if right paddle pressed
              bfbclr porta,3,wait ;go to wait if left paddle pressed

            (i.e. bfbclr macro used on both lines)

back to top

Chapter 6

Page 126, Simulation Exercise 6.1:
The reset state of the INTEDG bit and its effect is described "up side down" in this exercise. The reset state of the INTEDG bit is logic 1. The relevant sentences can be rewritten:

... Now “fire” the RB0 pin, setting RB0 high, and an interrupt sequence should be instigated as you single step further. See the Hardware Stack change, program execution transfer to the ISR, and on ISR completion the program resuming after the instruction where it was interrupted.  Fire the RB0 pin again (returning it to 0), and continue stepping. This will cause no change to program execution, as the interrupt edge response will be positive-edge triggered only (the INTEDG bit has been left at Reset value of 1). Try changing the INTEDG bit (to 0), as shown in the program....

Page 132, bottom paragraph: for better clarity, the first sentence should read “Suppose the Input signal of Fig. 6.5 was a stable 1kHz clock frequency.”

Page 136: Program Example 6.6 caption is misleading. Replace with Program Example 6.6: Using Timer 0 as a counter

Page 139: the last paragraph should reference Fig. 2.11, not Fig. 2.10.

back to top


Chapter 7

The last two lines of page 145 should read:

·        the architecture of the 16F87XA family, of which the 16F873A is a member,

·        the 16F87XA memory map and interrupt structure,

Page 163: replace ADCON0 with ADCON1
Caption of Fig. 7.15 should read:
Figure 7.15 Block diagram of Port A pin driver circuits. (a) ......

Page 168: bottom line, replace 125 ns with 250 ns.

Page 169: Caption of Fig. 7.19 should read: Figure 7.19 Oscillator traces from 16F873A devices. (a) RC oscillator, 800kHz nominal. (b) .....

Page 172: first line, replace "debugger" with "programmer"

back to top

Chapter 9

Using the Futaba S3003 Servo

This servo is power hungry, as mentioned in the first paragraph of 9.6.1. That's why in Program Example 9.3 we ramp it to move. However experience with a number of builds has shown that the values used still leave the performance "on edge". If battery voltage is on the low side, and/or alkaline batteries are not in use, and/or the voltage regulator goes into over-current shut-down too enthusiastically, then there is a dip in the 5V line, and Brown-out reset is invoked (this is left enabled in this Program in the version on the book CD).

To correct try one or more of the following:
* ensure battery voltages are adequate, and alkaline are used;
* introduce a voltage regulator just for the servo, drawing its input direct from the 9V line;
* slowing the ramp down in software - this will take a bit of thought, as at present it increments/decrements by one every time the PWM pulse is output, but it shouldn't be too difficult to halve it;
* introducing a larger value electrolytic capacitor (try 10,000 uF) between 5V and ground;
* switching off brown-out reset; as there are clear symptoms that the supply line is dipping this is of course not too clever, except as something to experiment with.
This is an interesting moment to apply a digital storage 'scope, if you have one, to observe the suspected voltage dip, either at battery terminals, and/or voltage regulator output.

Section 9.5.3, 1st line of 2nd para: "L913D" should read "L293D"

Using the SRF05 Ultrasound Ranger
Program Example 9.7 was written for the SRF04 ultrasonic ranger. If used with a SRF05 sensor, then it doesn't work, as there is a longer time delay between pulse input, and echo pulse output. The data sheet  indicates 700us, though measurements have returned higher values (approaching 800us). Therefore the 300us delay introduced in the program is inadequate. A simple program change is to remove the 300us delay, and insert these two lines, causing a wait until the echo pulse goes high:

          btfss portc,6 ;wait until echo pulse goes high
      goto $-1 

The later lines

;add in blanked 3cms (this derived experimentally)
        addlw 3

can also be removed or the added value adjusted.

back to top

Chapter 10

Page 267: 4th line: remove second "both" in this line.
Page 272: 3rd line from bottom: second "SDI" should read "SDO".
Page 294: Fig. 10.24: Label should read "Midpoint of Start bit".
Page 299: The key to Fig. 10.28 references
bits RCIF, RCIE twice. The correct reference is: For RCIF, RCIE, see Fig. 7.12.

Chapter 11

Program Example 9.7 is referenced on page 329 of this chapter. Check comments about it under Chapter 9.

Page 313: The first sentences should read "The input multiplexer, seen to the right of the diagram, has 5 channels for the 16F873A and ’F876A, and 8 for 16F874A and ’F877A. The inputs are shared with five of the six Port A bits, and three of the eight Port E (for 16F874 and ’F877) bits."
Page 313: The last sentence in the second to last paragraph should read: "
Best practice is therefore to set the ADC clock frequency such that it has a period equal to or just more than 1.6us."
Page 316: First paragraph: all references to "PGFC" should be to "PCFG"
Page 324:
Reference is made in the last two lines to rounding errors, while in fact it is truncation errors which are being forced in the data manipulation under discussion. A better wording would be “This depends on the rounding or truncation error introduced. The error in taking 1250 instead of 1250.048 is very small, …” See Section 11.4 of Reference 1.1 for a discussion of rounding and truncation errors.

back to top

Chapter 12

Page 340, 4th line of 5th paragraph: should read "...which signals an overflow of the two's complement 7-bit range..."
Page 342, Table 12.2: the two rotate left instructions should read rlcf, and rlncf.
Page 352, Section 12.6.2: second paragraph:  Replace the final sentence with "The instructions push and pop allow the programmer respectively to push the current Program Counter value onto the Stack, or to simply discard the top of stack, adjusting the Stack Pointer in each case. These are made available primarily to allow the user to set up and manage a software stack".

back to top

Chapter 14

Page 392, Section 14.2.6, 3rd paragraph: Extend first sentence to read: "Data names must start with a letter or underscore".
Page 396, Section 14.4.1: third line should read: "
TRISA = 0b10000110;  // initialise PORTA"
Page 406,
Table 14.4: caption should read “Example C18 general software library memory functions”.

back to top

Chapter 19

Section 19.8 is a very brief consideration of the issue of RTOS overheads. It is worth noting that the comments made apply primarily to small-scale programs, such as the ones we have considered in the book. For larger programs, it may be that these simple generalisations do not apply, i.e. that an RTOS-based program is inevitably longer than its sequentially-programmed equivalent. For example, for a program of 10-12 tasks, the code length may be actually shorter than its equivalent, written as a super-loop.

Page 485, bottom line: should be Table 19.2.
Page 487, Section 19.4.1, first paragraph, last line:  labels should be
Count_Task1 and Display_Task1
Page 487, Section 19.4.1, second paragraph, 4th line:  should be Table 19.2.
Page 494, first line of Section 19.5.2: Replace sfc18sfa.lib with sfc18sfm.lib
Page 497, Table 19.4: In left column OSECB( ) should be changed to OSECBP( ). This change should also be made in the cell opposite, where the reference to Table 18.2 should be to Table 19.2.
Page 500, second from last line: Reference should be to Section 8.6.5, not 18.6.5.

back to top

Appendix 3

Fig. A3.1: There are two R10's and two R17's in this diagram. A revised circuit diagram is available on the Derbot page.
Fig. A3.2: A pull-up resistor of value 4.7k
W should be shown, connected from pin 6 of the 16F873A to +5V. 

back to top

Book CD


Program Example 8.4 i)

In the initialisation an attempt is made to write to the PR2 SFR, with the bank select bits incorrectly set. This appears in the program section:

bcf        status,rp0   ;select bank 0
;set up PWM

      movlw      D'249'      ;sets PWM period. (alternative values can be used)
      movwf      pr2

The result of this is that the number D'249' is written to the T2CON register, which occupies the same location as PR2, in bank 0. This overwrites the setting previously placed in T2CON. In this case, D'249' = B'1111 1001. Checking the layout of T2CON (Fig 9.5 in book), we can see that, with bit 2 being 0, this turns Timer 2 off, and the PWM no longer functions. 

To fix, set bit rp0 to 1 before writing to PR2! The simplest way to do this is to move that write up to where the TRIS registers are being accessed; these lie in Bank 1. The code section then appears:

bcf       status,rp1
bsf       status,rp0      ;select memory bank 1
movlw     B'00000000'     ;set port A bits according to their function, 1=input, 0=output
movwf     trisa                      

movlw     D'249'          ;sets PWM period. (alternative values can be used)
movwf     pr2
bcf       status,rp0      ;select bank 0
;set up PWM


Program Example 8.4 ii)
The Delay1 subroutine was written for an 8MHz clock, but applied here with a 4MHz clock, without adjustment. In this program the delay introduced is not critical, so this error is not significant. The subroutine should be corrected if it is to be used in a context which is time critical. A correct version can be seen in other programs, e.g. Program Example 9.7.

Program Example 9.7
The I2C_send_stop subroutine has mysteriously lost its last two lines, although these appear in other programs which use this subroutine. Fortunately  the effect is minimal, as program execution proceeds on to the next subroutine, a short delay, and the program appears to right itself. The subroutine, as shown here in full, should of course be corrected if the program is to be used.

I2C_send_stop bsf status,rp0
        bsf sspcon2,pen         ;force stop bit.
        btfss sspstat,p         ;test for stop bit completion
        goto $-1
        bcf status,rp0

Program Example 11.3
Unfortunately the version for a slightly earlier Derbot has crept in. A change of two bits in the TRISB setting is required, as shown:

    movlw     B'00110000'
    movwf     trisb

Program Example 16.2
The word "rom" should be removed from line 14. The program appears correctly in the book.

back to top