Professional Documents
Culture Documents
The MicroBoard: Design, Assembly and Maintenance This section breaks down the parts of the MicroBoard
and explains what each does. An assembly guide and testing procedures follow this. Finally, the section finishes
off with a short tutorial to complete the initial programming of the MicroBoards onboard micro-controller.
Everyone will need this information, if only as a reference.
II
Getting Started: Hosted Mode The second part introduces operation of the MicroBoard in the Hosted mode and
will outline some of the methods you can use to test drive your board and also demonstrate some very simple
examples. This section will also introduce you to some very basic programming of the PIC, which will consist of
(typically) nothing more than cutting, pasting, and thus, utilizing code that has already been written for you. To
attain any sort of marks in the course, you will need to use this section. To attain great marks, it is possible to stop
with the documentation at this point; however, you will need to design some pretty fancy electronics to
complement the simple code.
III
Beyond Getting Started: Autonomous Mode & Advanced Programming Techniques This section opens a
new chapter that will allow you to unleash the full capabilities of the MicroBoard. Along with in-depth
programming documentation (allowing you to tailor the PICs program to suit your exact needs), this section
contains detailed examples and is complemented by bits of usable sample code, schematic diagrams, and board
layouts. The hand-holding ends with this section and those who venture beyond here will seldom find step-bystep procedures but will be applauded for their ambition and persistence!
IV
Examples: Both Simple and Complex Sample projects possessing some commonly used input/output traits
have been designed and documented for you. The documentation is available for your perusal, complete with
code, diagrams, and explanations.
Appendices These are referenced by the four previous parts. Feel free to detach the appendices from the bulk of
this manual; you will likely refer to them often.
Using this manual not only as a reference but also as a guide should make the journey much more interesting if not truly
enjoyable. I would sincerely recommend taking the time to read the entire manual from beginning to end; the things you
will learn along the way will be integral when it comes to designing your own project. Be aware, however, that
completion of this manual will merely lay the groundwork for more interesting, albeit more useful, applications of the
MicroBoard.
Keep in mind that the MicroBoard is just the central nervous system of your project. You are responsible for the design of
the extraneous circuits that your project will utilize (sensors, motors, etc). It would be prudent to make your initial circuit
designs on an SK10 board, then later transfer your design to a computer using EAGLE to have it milled into a clean PCB.
In general, rats nests of wires dont hold up very well and, in accordance with Murphys Law, will inevitably let you
down when you need them the most (during demonstrations of course!).
Good luck.
David Zeibin
August 2001
TABLE OF CONTENTS
Part I
1
1.1
1.2
1.3
1.4
1.5
1.6
INTRODUCTION ................................................................................................................................2
Specifications ...............................................................................................................................2
Functional Description .................................................................................................................3
DC Power Supplies .......................................................................................................................3
RS-232 Serial Peripheral Interface (SPI).....................................................................................4
The Micro-Controller ....................................................................................................................5
PIC Micro-Controller Chip Diagrams (PIC16F873) ......................................................................6
Part II
4
4.1
4.2
4.3
5
5.1
5.2
5.3
5.3.1
5.4
5.5
5.6
5.7
5.8
5.9
5.10
6
6.1
6.2
6.3
6.4
6.5
6.5.1
6.5.2
6.5.3
Part III
7
7.1
7.1.1
7.1.2
7.1.3
7.2
7.3
8
DEBUG.HEX ................................................................................................................................31
8.1
Code Map....................................................................................................................................31
8.2
Upper-Page Subroutines ............................................................................................................32
8.2.1
Global Subroutines ...................................................................................................................... 32
8.2.2
UART Module Subroutines............................................................................................................ 32
8.2.3
ADC Module Subroutines.............................................................................................................. 32
8.2.4
PWM Module Subroutines ............................................................................................................ 32
8.2.5
SPI Module Subroutines (Master Mode Only).................................................................................. 33
8.2.6
LCD Module Subroutines .............................................................................................................. 33
8.2.7
Programming Module Subroutines (only available on the PIC16F877)................................................ 33
8.2.8
Programming Utility Subroutines ................................................................................................... 34
8.2.9
Help Function ............................................................................................................................. 35
8.2.10
IR Module Subroutines ................................................................................................................ 35
9
9.1
9.2
10
10.1
11
11.1
Part IV
12
12.1
12.1.1
12.1.2
12.2
12.2.1
12.2.2
12.3
12.4
Part V
APPENDIX A.
APPENDIX B.
APPENDIX C.
APPENDIX D.
Appendices
MICROBOARD SCHEMATIC DIAGRAM .........................................................................................69
COMPONENT AND SOLDER SIDE OF BOARD..................................................................................70
ASSEMBLING A MILLED BOARD (PLUS HOW TO SOLDER)...............................................................71
CHECKLISTS: COMPONENTS, POWER, AND INTEGRATED CIRCUITS..................................................73
Part I
The MicroBoard: Design, Assembly, and Maintenance
Page 1
1 INTRODUCTION
The first-generation MicroBoard is a compact low-power controller board based on the Microchip Technologies
PIC16F873 micro-controller. The PIC is the heart and soul of the MicroBoard, acting as the central processing unit for the
board. The MicroBoard is used in the EE401 project course and will be common to most projects, while the addition of
student-designed-and-built circuits combined with customized software will complete individual projects.
Realized by way of an in-house design, the MicroBoard is an inexpensive alternative to the previously used Handy Board.
However, this does not mean the MicroBoard is inferior to its predecessor. In fact, the onboard PIC can perform up to 1
MIPS (million instructions per second) making the MicroBoard nearly 1000 times faster than the Handyboard, which
operated on a millisecond time scale (due to the fact that the Handyboard executed commands through interpreted C).
Every MicroBoard comes loaded with the following features:
Support for Three Built-in Motor Drivers: Each capable of driving a stepper motor, two bi-directional DC
motors, or four unidirectional DC motors.
Communication Interfaces: RS-232 communication with a PC; SPI and I2C buses for communicating with other
chips; and standard 5V CMOS digital I/O for anything else.
Extra Features: Five-channel analog-to-digital converter and two pulse-width-modulated outputs for servo
motors or other uses.
Two modes of operation are available for the MicroBoard:
Hosted mode: The MicroBoard runs a program allowing control of most of its functions through a serial link to a
desktop PC (see Part II). HyperTerminal is used to communicate with the MicroBoard in a command-prompt
fashion. It is also possible to write and compile a C program that will communicate with the MicroBoard for you
using commands you have defined (see Section 5.10).
Autonomous mode: More powerful than hosted mode, autonomous mode uses assembly code you have
compiled and then burned onto the PIC (see Part III). The code need not be hand-written from scratch; there
are many available subroutines you can call directly from the main portion of DEBUG.HEX, the Hosted mode
control program.
Complete with a relatively powerful processor and large I/O capability, the MicroBoard is an impressive control system.
The range of projects is virtually limitless: you can control robotics, perform wireless communication, carry out digital
signal processing, or even connect your MicroBoard to the Internet. The only real limit is your own imagination.
1.1 SPECIFICATIONS
This table lists the electrical characteristics of the MicroBoard; exceeding maximum or minimum values may damage
your board very quickly:
Maximum Input Voltage
18 Vdc
6 Vdc
22
5 (multiplexed)
Page 2
20 mA @ 7.2 Vdc
500 mA
500 mA
50 mA
20mA
1A
PIC16F873
Micro-Controller
Interface
Connectors
to the Rest
of Project
DC Power Supplies
Page 3
Diodes D1 and D2 provide some reverse polarity protection and power supply transient isolation. Capacitors C1 and C2
provide power supply bulk charge storage while C3 - C6 provide additional power supply transient isolation for their
respective supplies.
IC1 regulates the bulk supply to the +5Vdc needed for the PIC micro-controller and logic devices (logic side of the L293 and
MAX232). IC2 and its associated components regulate the bulk supply for the voltage inverter, IC3, and are only installed
if IC3 is to be used. IC3, an ICL7662P, and capacitors C9-C14 provide a negative voltage for analog circuits (dual supply
op-amps).
You will notice that the polarized capacitors have a non-polarized capacitor in parallel with them. This is not always
necessary in designs but is here. The reasoning is that real capacitors are not ideal capacitors: larger capacitors tend to have
greater amounts of intrinsic inductance associated with them due to their construction. This greater inductance gives them
poorer high frequency performance. Smaller capacitors tend to have better high frequency performance. Therefore,
multiple real capacitors are used to approximate the required ideal capacitor performance.
Page 4
Page 5
Page 6
Solder the IC sockets into the board; plug the ICs into their sockets.
Part I The MicroBoard: Design, Assembly, and Maintenance
Page 7
Before installing any ICs, test the board for proper power connections. Continue with the Power Checklist in Appendix
D. Once all the power checks have been tested and are correct, continue with the IC Checklist.
After your board is completely assembled, the next section will aid you in actually installing some software on to the
PIC.
Page 8
Page 9
Figure 3-2
Click on the Configuration Bits button. A new window should open; select the following options from each of the
drop boxes:
Finally, click Program in the PICSTART Plus Device Programmer window to burn your program onto the PIC.
The program will tell you if the program was transferred onto the chip successfully.
Take the chip out of the programmer, plug it into your MicroBoard, and youre ready for business.
Page 10
Part II
Getting Started: Hosted Mode
Page 11
4 HOSTED MODE
DEBUG.HEX allows you to control most of the functions of the MicroBoard without writing a single line of code. You can
even automate operations using Hosted mode by writing C programs for the PC that will control the MicroBoard (see
Section 5.10). DEBUG.HEX provides only the bare essentials available on the MicroBoard. To really make use of the
MicroBoard, youll need to write your own code (using DEBUG.HEXs pre-written subroutines or from scratch if youre up
to the challenge) and burn it onto the chip.
You will use a terminal program (HyperTerminal on the Windows systems and Seyon on the HP-UX systems) to
communicate with the MicroBoard through the serial port. DEBUG.HEX uses a command prompt interface; all the
commands available to you are outlined in Section 5.
Open a HyperTerminal session with the desktop icon EE401.ht. If the icon isnt there, you can start HyperTerminal using
the Start Menu (Start>Programs>Accessories>Communications>HyperTerminal).
Page 12
When Seyon starts up, the Seyon Command Center will pop up. To configure Seyon, click on SET and select
CTS/RTS. Seyon should already be configured properly, but to make sure, choose the appropriate settings under each
button: 9600bps, 8 data bits, no parity, 1 stop bit (8-N-1), hardware flow control disabled (unless your MicroBoard has
hardware flow control enabled; refer to Section 5.9), etc.
NOTE: To change the flow control, go to the SET menu and choose RTS/CTS (hardware flow control) or None (no
flow control).
Connect the power and the serial cable to the MicroBoard; you should be greeted with the Help Screen. Like in
HyperTerminal, this screen will be shown if you type help at the command prompt.
NOTE: Only one Seyon terminal session can be launched on a machine at a time.
Page 13
Page 14
pwmstart1
pwmperiod ff
pwmduty1 40
pwmstop1
NOTE: On the PIC, pin c2 corresponds to PWM1 while pin c1 corresponds to PWM2.
If you hook up an LED to the PWM, you can change the brightness by varying the duty cycle and period.
NOTE: After running adcinit, all five channels are enabled. You may have problems if you want to turn only one of the five
off. By running an input or output command on any of the five pins (thus turning a pin into a digital line), all five ADC
channels will turn off automatically.
5.3.1 MAXIMUM ADC VALUES
All five ADC ports have a limited amount of diode protection to
prevent input voltages outside of the Vdd to Vss range. A better way to
make sure your PIC doesnt get fried by stray analog voltages though,
is to set up a small circuit before the signal reaches the ADC pin similar
to the one to the right. This circuit will not let any voltage hit the ADC
pin unless it is between 0 and 5V and doesnt depend on the PICs
limited protection.
The PIC16F87x data sheet also recommends that the maximum input
impedance of an analog source be less than 10k and that any current
on any pin should not exceed 20mA.
+5V
1k
4.7k
ADC line
PIC16F873
MicroBoard
On older MicroBoards, a pull-up resistor is required between the a4 pin and the power.
Page 15
>> spiinit
>> spitrans 28
val=92
To use the SPI, you must use pins c0, c3, and c5 on the PIC. Pin c5 sends data out while pin c3 takes care of the SPI clock.
Pin c0 is used to send a clock pulse out to the SPI devices, usually used to update the data sent through pin c5. Pin c4 is used
as an SPI input if your SPI device returns pertinent data. For a more detailed explanation of the SPI refer to Sections 6.3 and
6.4. For an example using the SPI input, see Section ELSEWHERE.
Vcc
47 5%
5V
47F
GND
Vout
GND
Vout
IR Receiver
(IS1U60
Figure 5-1:
lcdinit
lcdput hello
lcdline2
lcdput world!!
lcdclear
Page 16
Add two 470 resistors at positions R33 and R34 beside the
MAX232 chip.
Solder a wire between the end of the resistor closest to the DB9
connector in R34 and pin b1 on the PIC
Solder a wire between the end of the resistor closest to the DB9
connector in R33 and pin b2 on the PIC.
To create a script, simply save to a text file the set of commands in the
order you would like them carried out. Start a HyperTerminal session
and select Transfer>Send Text File. Choose your saved script. The
commands will be sent to the PIC and performed one by one (see
Section 6.1 for a scripted example).
Please note that this diagram is incorrect. The wires are crossed.
5.10 PROGRAMMING IN C
An interface program has been written that, when executed, is able to communicate with the MicroBoard using nearly all of
the commands available in Hosted mode. Since logic structures can be developed in C much more easily than in assembly
language, projects that dont require extreme mobility and thus, dont require Autonomous mode programming, can simply
use DEBUG.HEX pre-programmed on the PIC and a C program running on an HP-UX terminal (refer to Patrick Pilarskis
Guide to the HP-UX Systems for a quick tour of the system).
The skeleton interface program was originally written by Dr Chris Backhouse but has gone through various stages of
debugging and development. If you run into any problems with the original code, please report the problem immediately so
that it can be remedied as soon as possible.
Get the code here: http://www.ee.ualberta.ca/~ee401/debug/both.c
Part II Getting Started: Hosted Mode
Page 17
WARNING! Always make sure that you connect a 470 currentlimiting resistor in series with an LED! Simply solder an LED onto a
resistor so that you have two free leads. Not using a resistor in series
will surely destroy the LED and will likely damage the MicroBoard!
Connect your MicroBoard to a PC, start up HyperTerminal, and power up your MicroBoard in Hosted mode. To flash the
LED you need to turn pin c0 into an output using the output command, then you can switch the LED on and off using the
set and clear commands:
>> output C0
>> set C0
>> clear C0
Still using Hosted mode (and ensuring that your board has hardware flow control enabled; see Section 5.9), you can use a
script to perform the same task. Make a *.txt file containing the following commands and send it to the MicroBoard using
the Transfer>Send Text File command. Add as many repetitions as you see fit (dont include the comments on the right;
those are there for your understanding only):
output c0
set c0
delay 96
clear c0
delay 96
sets
turn
wait
turn
wait
pin
LED
for
LED
c0 as an output
on
1.5 seconds
off
set c0
delay 96
clear c0
delay 96
set c0
delay 96
clear c0
delay 96
- repeat ad nauseum
When you send the file, youll see each command pop up in the terminal window as they are processed (if you leave a line in
the script blank, the MicroBoard will simply skip to the next command).
Part II Getting Started: Hosted Mode
Page 18
To finally beat this example to death, the LED can be controlled using a C program as an interface between you, the user, and
the MicroBoard. Using the general C interface program, both.c (http://www.ee..ualberta.ca/~ee401/debug/both.c), written
by Dr Backhouse, plop in this main function to automate the process completely:
main () {
// begin initialization routine
long t; int j;
struct termios oldtio;
Initialize(&comm_port,&oldtio);
// end initialization routine
// begin main code
output("c0");
on LED
one second
off LED
again
RC1
or
RC2
Analog
Output
10F
PIC16F87x
Figure 6-1:
Choosing two components with the appropriate values forms a low-pass filter with the necessary time constant for creating
an analog signal from the PWM output. The values shown are merely a suggestion; youll need to make sure that the PWM
period is sufficiently short compared to the RC time constant or ripple will be evident. The output of this signal is controlled
by the duty cycle of the PWM signal: to increase the voltage, increase the duty cycle and vice versa. Shown below is a set of
commands that will control the output of the PWM DAC:
>>
>>
>>
>>
>>
startpwm1
pwmperiod ff
pwmduty1 00
pwmduty1 80
pwmduty1 ff
Page 19
PIC16F873
+5V
LTC1448
1 CLK
2 D
in
3 CS
4
VREF
14
SCK C3
16
SDO C5
13
Chip Select C2
VoutB
Vcc
GND
VoutA
8
7
6
5
schematic:
Figure 6-2: LTC1448 circuit schematic
The LTC1448 is a 12-bit, 2-channel DAC utilizing an SPI interface. When you write to the DAC you have to update both
channels at the same time, which means you have to write 2 x 12 (or 24) bits, with the upper 12 bits corresponding to VoutA and
the low 12 bits corresponding to VoutB. The PIC transfers 8 bits at a time in SPI mode so you will need three write cycles to set
the DAC.
Below is a sequence of Hosted mode commands that will select the DAC, write 24 bits to it, and then deselect it:
>>
>>
>>
>>
>>
>>
>>
spiinit
output c2
clear c2
spitrans 12
spitrans 34
spitrans 56
set c2
Notice that the chip select line on the DAC is active low so you need to clear it when you want to select the DAC. Once you
have typed in these commands, the outputs VoutA and VoutB should be 0x123 (1.35V) and 0x456 (0.35V) respectively.
There are many SPI devices available from digital signal processors (ADCs and DACs for example) to memory (RAM and
EEPROMs) to other micro-controllers. There is even an MP3 decoder chip available that uses an SPI interface. Since SPI is an
easily implemented interface, many companies find it advantageous to use it.
Page 20
24
25
26
RC0
11
RC3/SCK
14
+5V
+5V
16
10
14
RC5/SDO
11 12
8
11 12
15
8
11 12
9
74HC595
15
16
10
13
14
74HC595
+5V
16
10
13
14
74HC595
15
16
10
13
11 12
PIC16F873
+5V
13
14
74HC595
15
16
>> output b3
>> output b4
>> output b5
>> set b3
>> set b5
>> clear b4
>> spitrans 9f
>> set b4
>> set c0
>> clear c0
Part II Getting Started: Hosted Mode
>> clear b5
>> spitrans b2
>> spitrans 0d
>> set b5
>> set c0
>> clear c0
Using pin c4, the SPI input line, one could hook up SPI input devices and use a similar process to select an input device on
the SPI bus and clock data in on the SDI line (pin c4).
Grabber
Motor
12 RC1
13 RC2
6
3
11
14
GND
L293D
-
11 RC0
14 RC3
7
2
21 RB0
24
RB3
PIC16F873
MicroBoard
Right
Motor
10
15
Left
Motor
pwmstart1
pwmstart2
pwmduty1 00
pwmduty2 00
output b0
output b3
output c0
output c3
Move Forward
>>
>>
>>
>>
pwmduty2 00
set c0
set c3
pwmduty2 hh
Move Left
>>
>>
>>
>>
pwmduty2 00
clear c0
set c3
pwmduty2 hh
Move Right
Part II Getting Started: Hosted Mode
Stop Motion
>> pwmduty2 00
Open Grabber
>>
>>
>>
>>
pwmduty1 00
set b0
clear b3
pwmduty1 hh
Close Grabber
>>
>>
>>
>>
pwmduty1 00
clear b0
set b3
pwmduty1 hh
Stop Arm
>> pwmduty1 00
>>
>>
>>
>>
pwmduty2 00
set c0
clear c3
pwmduty2 hh
MOVEFORWARD.txt
pwmduty2 00
set c0
set c3
pwmduty2 hh
MOVELEFT.txt
pwmduty2 00
clear c0
set c3
pwmduty2 hh
STOP.txt
pwmduty2 00
OPENGRABBER.txt
pwmduty1 00
set b0
clear b3
pwmduty1 hh
CLOSEGRABBER.txt
pwmduty1 00
clear b0
set b3
pwmduty1 hh
STOPGRABBER.txt
pwmduty1 00
MOVERIGHT.txt
Pwmduty2 00
Set c0
Clear c3
Pwmduty2 hh
Page 23
pwmduty1(0);
pwmduty2(0);
int choice=0;
int motorspeed=0;
int clawspeed=0;
while(1) {
printf("Select an option:\n");
printf("-----------------\n");
printf("1: Forward\n");
printf("2: Stop\n");
printf("3: Left\n");
printf("4: Right\n");
printf("5: Open Claw\n");
printf("6: Close Claw\n");
printf("7: Stop Claw\n");
printf("8: Change Wheel Speed\n");
printf("9: Change Claw speed\n");
printf("0: Exit\n\n")
printf("What is your choice?");
cin >> choice;
if ( choice == 0 ) break;
// exit on 0
switch (choice) {
case 1:
pwmduty2(0);
set_pin("c0");
set_pin("c3");
pwmduty2(motorspeed);
break;
case 2:
pwmduty2(0);
break;
case 3:
pwmduty2(0);
clear_pin("c0");
set_pin("c3");
pwmduty2(motorspeed);
Part II Getting Started: Hosted Mode
Page 24
break;
case 4:
// move right
pwmduty2(0);
set_pin("c0");
clear_pin("c3");
pwmduty2(motorspeed);
break;
case 5:
// open grabber
pwmduty1(0);
set_pin("b0");
clear_pin("b3");
pwmduty1(clawspeed);
break;
case 6:
// close grabber
pwmduty1(0);
clear_pin("b0");
set_pin("b3");
pwmduty1(clawspeed);
break;
case 7:
// stop grabber
pwmduty1(0);
break;
case 8:
// change motor speed
printf("\nWhat speed (0-100)?");
cin >> choice;
motorspeed=choice;
break;
case 9:
// change grabber speed
printf("\nWhat speed (0-100)?");
cin >> choice;
clawspeed=choice;
break;
default:
printf("unknown command");
break;
}
}
}
Hook up the HP-UX's serial cable, compile the interface program (with your new main function shown here) with g++ or
another compiler, and run the new executable. Enter the commands to operate the GrabberBot.
Page 25
Part III
Beyond Getting Started: Autonomous Mode
and Advanced Programming Techniques
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 26
7 AUTONOMOUS MODE
Using the MicroBoard in Autonomous mode is a much more powerful manner of doing things and will let you unleash
its full potential, but youll likely need to get your fingers a little bit dirty and play around with some real, live assembly
code. Before reading any further, you are advised to browse through the PIC16F87x data sheet
(http://www.ee.ualberta.ca/~ee401/datasheets/PIC16F87x.pdf); what follows is intended to supplement that data sheet.
Use MPLAB (Start>Programs>Microchip MPLAB>MPLAB) to write and compile your code. If youd like to download
MPLAB, it is available on the EE401 web site at http://www.ee.ualberta.ca/~ee401/software/microchip/MPL51100.exe.
The following will introduce several concepts involved in developing systems using the PIC, specifically assembly
language code structure and intricacies using MPLAB, digital I/O, and downloading your code to the PIC itself.
Before parsing through this section, make sure you are familiar with assembly language basics and the PIC instruction set,
available in the aforementioned data sheet.
Notes:
Address Range
Notes
Bank0 Registers
000h-07Fh RMem
Bank1 Registers
080h-0FFh RMem
Bank2 Registers
100h-17Fh RMem
Bank3 Registers
180h-1FFh RMem
0000h-07FFh PMem
0800h-0FFFh PMem
Page 27
NOTE: Many of the register locations are reserved and should not be used by the users program and general-purpose
storage. See the memory map in Figure 2-3 of the PIC data sheet for more details.
There are two methods of addressing memory: direct and indirect mode. Direct mode is bound by the values of the RP0
and RP1 bits and can only address the currently selected register page. This is the normal mode where individual
operations can access separate registers using commands such as
clrf
foo
The other method of accessing registers does not depend on the value of RP0 or RP1, instead IRP is used to select either the
range 00h to FFh or 100h to 1FFh. Using the indirect addressing method, the lower byte of the address of the register to be
accessed is written into the FSR register. On the next instruction cycle the contents of the selected register are available in
the INDF register, ready for reading or writing.
To access a variable using this method you could use the following code:
movlw
movwf
clrf
bar
FSR
INDF
Obviously, the direct addressing method is faster. When it is necessary to move data from one page to another, however,
the indirect method is much faster than the direct method.
7.1.2 MATHEMATICAL OPERATIONS
Since the PIC is RISC-based, there are very few mathematical operations available. For example, there are no hardware
floating-point operations, or even multiplication or division for that matter. Two add and two subtract instructions are
available though. If you require this functionality in your code, Microchip does offer some software emulation libraries for
these operations (check out the subset of pertinent project ideas on the Project Suggestions page of the EE401 web site).
One tricky part when using the built-in math operations lies in the subtraction op-codes sublw and subwf. Care must be
taken when using these operations to ensure that the operation performed is indeed the operation desired.
Example:
subwf
sublw
foo,W
d30
; W = foo - W
; W = 30 W
The first command is fairly straightforward; the second, on the other hand, can be counterintuitive.
An alternative to actually performing the calculations is a look-up table. For example, instead of performing the same
calculation over and over, a Celsius to Fahrenheit conversion table could be made listing all the corresponding Fahrenheit
temperatures for 0 to 100C. Choose a method that will work best for your particular application.
7.1.3 FLOW CONTROL
There are four op-codes that provide conditional branches: btfss, btfsc, incfsz, and decfsz. The first two test a single
bit in a register and skip the next instruction depending on the instruction used and the value of the bit. The last two
increment and decrement the operand, respectively, and skip the next instruction if the value of the register after the
operation is zero.
Three examples of code are shown below to demonstrate commonly used comparison operations:
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 28
foo,W
bar,W
STATUS,Z
FALSE
TRUE
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
foo,W
bar,W
STATUS,C
FALSE
TRUE
foo,W
bar,W
STATUS,C
FALSE
TRUE
The values of foo and bar are being compared: if the condition being tested is true, the program will jump to the label
TRUE; otherwise, it will jump to the label FALSE.
Address
Name
Bit 7
Bit 6
Bit 5
Bit 4
Bit 3
Bit 2
Bit 1
Bit 0
05h
PORTA
RA5
RA4
RA3
RA2
RA1
RA0
85h
TRISA
06h, 106h
PORTB
RB7
RB6
86h, 186h
TRISB
07h
PORTC
87h
TRISC
RB4
RB3
RB2
RB1
Transmit/Receive Selection
RB0
RC6
RC5
RC4
RC3
RC2
Function
Data Transfer
Data Transfer
Transmit/Receive Selection
RC1
RC0
Data Transfer
Transmit/Receive Selection
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 29
The following code demonstrates I/O operation using the same example as in the hosted mode: turning an LED on and
off. Unfortunately, the human eye will not be able to see the LED flashing since the frequency is about 250 kHz. You can
use an oscilloscope to view the output though:
start
bsf
bcf
bcf
STATUS,RP0
TRISC,0
STATUS,RP0
loop
bsf
bcf
PORTC,0
PORTC,0
; turn LED on
; turn LED off
goto
loop
end
7.3 LIMITATIONS
As mentioned previously, the PIC has a limited set of functions. There are no multiply or divide instructions available and
there is no floating-point math either.
The PICs you were given are rated to run at 4MHz; this may prove to be too slow if you are making any processor
intensive applications. A 20MHz version is available, however.
There are 192 bytes of RAM and 128 bytes of EEPROM available on the PIC. For most applications that should be plenty,
but it may not be enough for storing large amounts of data. Additional memory chips can be connected to the PIC should
the need arise.
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 30
8 DEBUG.HEX
If you require Autonomous mode (many will), youll need to either write your program from scratch, or modify an
existing program. DEBUG.HEX contains many subroutines that you can reuse in your own project. As long as youre
familiar with the PIC instruction set and the basics of assembler language, programming the PIC to suit your needs should
be a relatively painless procedure: just simply call the subroutines that have already been written for you. The majority of
the grunt work has been done; its up to you, however, to design the logic structure of your program.
DEBUG.HEX is described below. You can get the full source code
(http://www.ee.ualberta.ca/~ee401/debug/debug.asm).
on
the EE401
web site
Variable and constant declarations: It will be important to look at this section in conjunction with any code
samples from DEBUG.HEX you choose to copy to make sure you also copy any required variables and constants
into your code.
Command input subroutines (user interface display and parsing): This code displays a prompt on the terminal
screen, allows a user to type in a command and input data, then calls for its execution. If the command is
recognized then the appropriate calls are made to command subroutines in the next section of code to execute the
command. The interface section contains general interface code and a set of subroutines starting with the word
parse_. If a command is not recognized then Unknown Command is displayed on the terminal screen and
the prompt is redisplayed. This code is useful to examine, but unless you are planning an interactive user interface
for your project, it is unlikely you will need to understand the details of this section. Given that a valid command
is entered, the command is stored in ASCII format in a set of variable locations starting at the input variable
location in the first bank of register memory.
Command execution subroutines: The names of these subroutines each begin with the letters cmd_. These
subroutines serve two purposes: The first is to parse the input data included with many of the commands to
identify incorrect input data and to use that data to make the appropriate call to the implementation subroutines
in the next section. The second is to display the results of the call to the implementation subroutines. Though you
will probably want to write your own code to call the implementation subroutines, the code here will give you a
good example of what youll need to do to call commands in an appropriate order and set variables to required
values.
Low-level device implementation subroutines: These routines initialize and manipulate the registers and data
necessary to perform a desired process in the PIC processor. All these subroutines are located in the upper page of
program memory. Though most of the code in this section does not need to be changed to include it into a users
program, several of the routines contain display components that the user may want to change or delete. Note
that the routines putUART and putHexByteToTerm sends data contained in W to the terminal and can be
replaced by user code that performs operations on this data or transfers it to other variables for later use.
Parts 1 through 3 are located in the lower memory page (page 0 for both devices), and part 4 is located in the upper
memory page (page 1 for the PIC16F873 and page 3 for the PIC16F877).
Keep in mind that DEBUG.HEX contains much programming dedicated to receiving and parsing input in Hosted mode.
Thus, there is a lot in DEBUG.HEX that you simply will not need since a project running in Autonomous mode doesnt
receive any user input. Make sure you understand what something does before you cut it out of the program though;
everything can be pieced back together if you lose something, but this is time consuming and, of course, causes unwanted
frustration. You can safely cut Parts 2 and 3 without any lost functionality (save for communication via Hosted mode). If
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 31
you are planning to do a lot of low-level programming, you may consider starting with the Autonomous flashing LED
code outlined in Section 9.2.
getUART
Gets a byte from the Rx line and stores it in W.
putUART
Puts the byte in W on the Tx line.
Receives: nothing
Uses: W
Returns: nothing
Receives: nothing
Uses: W
Returns: W (ASCII value read from terminal)
Receives: W (ASCII value read from terminal)
Uses: W
Returns: nothing
Receives: nothing
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 32
Uses: W
Returns: nothing
setPWMDutyX
Sets the value of the duty cycle on the PWM1 (pin RC2) or Receives: W
PWM2 (pin RC1). The value must be less than the value of Uses: W
the period or the duty cycle will be 100%. The duty cycle is Returns: nothing
determined by the ratio:
duty/period = % duty cycle
setPWMperiod
Sets the value of the period on both PWM pins. The value Receives: W
can be 0 to 0xFF and is the value of the period of both Uses: W
PWM pins. This is because the PIC circuit uses Timer 2 to Returns: nothing
set the period for both pins.
8.2.5 SPI MODULE SUBROUTINES (MASTER MODE ONLY)
initializeSPI
Initializes the SPI pins. The communication protocol is set to Receives: nothing
perform data transfer on a rising edge clock. See the Uses: W
PIC16F87x data sheet and the Mid-Range PIC Manual to Returns: nothing
see how to modify code to other protocols.
transferSPI
Performs concurrent send and receive data transfer over Receives: W (data to be sent)
the SPI pins.
Uses: W
Returns: W (data received)
8.2.6 LCD MODULE SUBROUTINES
initializeLCD
Initializes the LCD to run an Optrex 2x20 LCD display over Receives: nothing
the SPI. Refer to Section 4.1 of the MicroBoard Advanced Uses: W, temp
Manual for hookup diagrams and other important details. Returns: nothing
sendLCDChar
Sends an ASCII character contained in W to the SPI.
Receives: W
Uses: W, char, temp
Returns: nothing
sendLCDCmd
Sends a command byte contained in W to the LCD on the Receives: W
SPI.
Uses: W, char, temp
Returns: nothing
LCDDelay
Performs delays during LCD initialization.
Page 33
setHighVoltageProgrammingMode
Places an external application PIC connected to the Receives: nothing
MicroBoard into programming mode using the standard Uses: W, temp
ICSP (In-Circuit Serial Programming) method. See the Returns: nothing
Microchip application notes on ICSP for more information.
setLowVoltageProgrammingMode
Places an external application PIC connected to the Receives: nothing
MicroBoard into programming mode using the low- Uses: W, temp
voltage ICSP (In-Circuit Serial Programming) method. See Returns: nothing
the Microchip application notes on ICSP for more
information.
programmingPrompt
Displays a Send File prompt on the terminal when Receives: nothing
waiting for a *.HEX file during programming.
Uses: nothing
Returns: nothing
clearProgrammingMode
Sets the external application PIC (the one that was just Receives: nothing
programmed) into a standard running mode after Uses: W, temp
programming.
Returns: nothing
beginProgramming
Decodes a *.HEX file and transfers it to the program Receives: nothing
memory of an external application PIC.
Uses: W, temp, appPCLow, appPCHigh, byteCount,
lineCheckSum, addressHigh, addressLow, recordType,
DCOUNT1,
DCOUNT2,
addrIncrementLow,
addrIncrementHigh, hexOutDataHigh, hexOutDataLow,
hexDataHigh, hexDataLow
Returns: W (1 on error)
sendProgrammerData
Sends a 14-bit word (plus start and stop bits) to the memory Receives: hexOutDataHigh, hexOutDataLow
of an external application PIC.
Uses: W, temp, hexOutDataHigh, hexOutDataLow
Returns: nothing
receiveProgrammerData
Receives a 14-bit word (plus start and stop bits) to the Receives: nothing
memory of an external application PIC. NOTE: This Uses: W, temp, hexOutDataHigh, hexOutDataLow
function is not yet implemented in the user interface.
Returns: hexInDataHigh, hexInDataLow
sendProgrammerCommand
Sends a 6-bit word to an external application PIC.
Receives: hexOutDataLow
Uses: W, temp, hexOutDataLow
Returns: nothing
Page 34
putHexByteToTerm
Converts a two-digit hex value in W into 2 ASCII values Receives: W
and send them to the terminal.
Uses: W, temp
Returns: W
programmerDelay
The programmer delay is a fixed delay used only by the Receives: nothing
programming subroutines.
Uses: W, DCOUNT1, DCOUNT2
Returns: W
8.2.9 HELP FUNCTION
help
Displays the Help Screen to the terminal. Reads = as row Receives: nothing
of - and 0 as END.
Uses: W, DCOUNT1
Returns: nothing
8.2.10 IR MODULE SUBROUTINES
getIR
Function subroutine to do an example of reading the input Receives: nothing
from a universal TV remote on RB0 and displaying it to the Uses: W, IRCOUNTER, BYTE1, BYTE2, BYTE3
terminal. NOTE: The program will wait indefinitely until Returns: BYTE1, BYTE2, BYTE3
some signal is received.
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 35
Select File>Save As and save the template as your own file. You will be editing the code in this file and coming
back to it often so choose an appropriate file name and directory.
Select Project>New Project. Choose a file name and save it to the same directory as in Step 3. The project and the
projects files must be in the same directory.
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 36
Set all the options in the Node Properties window as shown in Figure 9-3. Click OK when youre finished.
Select the file you created and click Add Node to add your file to your project.
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 37
You now have a working piece of code that you can build onto. When you are ready to assemble your program click on
Project>Build All.
Take a look at p16f873.inc to see how the assembler converts labels to register addresses and arguments.
list p=16f873
#include <p16f873.inc>
When you programmed your PIC with the Host program in Part II, you were shown how to manually set the
configuration bits. This is how to set them in your code. Change your code as below (note the changes made):
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON &
_LVP_OFF & _CPD_OFF
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 38
These are variables and their register address assignment. w_temp resides in register memory location 0x20. This is the first
location of the General Purpose Registers (data RAM). Add three more variables as shown (temp0, temp1, and
temp2):
;***** VARIABLE DEFINITIONS
w_temp EQU 0x20
status_temp EQU 0x21
temp0 EQU 0x22
temp1 EQU 0x23
temp2 EQU 0x24
;**********************************************************************
ORG
0x000
; processor reset vector
clrf
PCLATH
; ensure page bits are cleared
goto
main
; go to beginning of program
Comment out this section or delete it (it has been deleted in the source code file):
;
;
;
;
;
ORG
movwf
movf
bcf
movwf
0x004
w_temp
STATUS,w
STATUS,RP0
status_temp
;
;
;
;
;
;
bcf
movf
movwf
swapf
swapf
retfie
STATUS,RP0
status_temp,w
STATUS
w_temp,f
w_temp,w
;
;
;
;
;
main
STATUS,RP0
STATUS,RP1
b11111110
TRISC
bcf
STATUS,RP0
LOOP
btfsz
bsf
call
bcf
call
goto
PORTC,1
PORTC,0
onesec
PORTC,0
onesec
LOOP
;
;
;
;
;
;
Page 39
movlw
movwf
onesec_a
decfsz
goto
decfsz
goto
decfsz
goto
return
END
d250
temp2
temp2,F
onesec_a
temp1,F
onesec_a
temp0,F
onesec_a
;
;
;
;
;
;
;
After the END directive, the assembler stops looking at the file. Any code after this point is ignored. Save and compile this
program.
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 40
10 MPLAB SIMULATOR
MPLAB has a built-in microprocessor simulator. If you compile assembly code you can test its operation by simulating
what it does. The simulator is designed to step through your code to view registers, stimulate pins, etc to debug your
code. Remember, however, the simulator does have limitations.
shows
the
assembler
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 41
Now we want to assign an action to the button. Rightclick on the RC1 (P) button in the Asynchronous
Stimulus Dialog window and select Toggle.
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 42
Next, well start stepping through your code. Press F6 (Reset) or select Debug>Run>Reset. If you feel you need to
start over at any time, just press F6.
10 In your source file a line is highlighted indicating the next instruction to be executed. The highlighted text should be
clrf PCLATH.
11 In the Debug>Run>Step window you will notice F7 single steps through your program. Slowly step through your
program by repetitively pressing F7. Note that the PCL register is highlighted in red as the simulator steps through the
program memory and changes to the program memory location (the value is the location highlighted in the Program
Memory Window).
See menu Debug>Run for running, stopping, single stepping, and reset commands.
Set breakpoints by right clicking on a line of code, and selecting Breakpoint.
The stopwatch under Window>Stopwatch is useful for timing how long code takes to run. Set breakpoints before and
after, then run it.
Other important areas not covered here include Trace, Arm Counter, Stimulus from a File, and Environment Setup.
These items are explained in the MPLAB Users Guide, the MPLAB Help Files, and on the Microchip web site
(http://www.microchip.com). The simulator is also discussed in Microchips PICSTART PLUS Mechatronics Getting
Started Guide (http://www.ee.ualberta.ca/~ee401/reference/PICmech.pdf).
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 43
;************************************************************************
;
Program Header
;
- Documentation about your program is very important for not
;
only your information but also to guide the person marking your project
;
through your thought process.
;
;
The following program is a simple version of a volt meter. The
;
program takes analog input from RA1 and displays a binary readout on
;
the 8 Port B pins. The input is a voltage from any supply between GND
;
and VCC. It is wise to use a current limiting 470 Ohm resistor on the input.
;
The output from each pin can be run through a 470 Ohm resistor- LED pair
;
or collectively as the input to an LED digit display.
;
;************************************************************************
;
Filename:
ADCsample.asm
;
Start Date:
July 10, 2001
;
Last Revision Date:
July 11, 2001
;
File Version:
1.0
;
;
Author:
Michael Cumming
;
Company:
University of Alberta
;************************************************************************
;
Files required:
P16F873.inc
;
16F873.lkr
;************************************************************************
;
Notes:
;************************************************************************
list p=16f873
#include <p16f873.inc>
Page 44
EQU
EQU
EQU
EQU
0x0000
0x0800
0x1000
0x1800
TRUE
FALSE
EQU
EQU
1
0
;**********************************************************************
ORG
0x000
; processor reset vector
clrf
PCLATH
; ensure page bits are cleared
goto
main
; go to beginning of program
main
start
banksel
clrf
banksel
clrf
BANK1
TRISB
BANK0
PORTB
pagesel
call
pagesel
PAGE1
initADC
PAGE0
mainLoop
pagesel
movlw
call
pagesel
PAGE1
0x01
readADC
PAGE0
movf
movwf
newData,W
PORTB
mainLoop
goto
;****************************************************************
;***
PAGE 1 Subroutines
;****************************************************************
org
PAGE1
;****************************************************************
;*******************************************************************
;
ADC Module Subroutines
;*******************************************************************
;*******************************************************************
;
Function subroutine to initialize RA0 as an ADC input.
;
Sets the (right justified) data flag.
; receives: nothing
; uses: W
; returns: nothing
;*******************************************************************
initADC
banksel
BANK1
; Move to Bank 1
;
movlw
0x82
movlw
0x02
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 45
ADCON1
banksel
BANK0
; Move to Bank 0
movlw
movwf
0x01
ADCON0
movf
andlw
movwf
PORTA,W
0x10
PORTA
banksel
bcf
BANK1
PIE1,ADIE
; Set to bank1
; Disable A/D interrupt
movf
iorlw
movwf
TRISA,W
0x2f
TRISA
banksel
BANK0
; Move to Bank 0
bcf
PIR1,ADIF
return
;*******************************************************************
;
Function subroutine to initiate a read of ADC port pins
;
which stores its value in ADRESH, and ADRESL (right justified)
; receives: W - <0 to 4> pin to read
; uses: W, char
; returns: nothing
;*******************************************************************
readADC
;
;
;
;
;
;
;
;
;
;
;
;
movwf
char
swapf
bcf
rrf
bsf
movf
char
STATUS,C
char
char,0
char,W
movwf
ADCON0
bsf
ADCON0,GO
btfsc
goto
ADCON0,GO
$ - 1
bcf
PIR1,ADIF
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
movlw
call
d'13'
putUART
d'10'
putUART
'V'
putUART
'a'
putUART
'l'
putUART
'='
putUART
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 46
movf
ADRESH,W
call
putHexByteToTerm
;
;
;
banksel BANK1
movf ADRESL,W
banksel BANK0
call
putHexByteToTerm
return
END
Part III Beyond Getting Started: Autonomous Mode and Advanced Programming Techniques
Page 47
Part IV
Examples: Both Simple and Complex
Page 48
12 WORKING EXAMPLES
This is the beginning of the last section. Contained are a number of examples with code available for your use as either a
complete operational module or a starting point for your own ideas.
With the exception of the Motor Speed Controller and the Shaft Encoder, all of these examples should be functional in
both Hosted mode and Autonomous mode.
Connect the servos red wire to the 5V source on the auxiliary power connector on the MicroBoard (these are the six
pins near the top of the board. Pin 6 is the 5V source). Connect the servos black wire to ground (pin 2 or 3 on the
auxiliary power connector). If youre worried about causing a brownout, use an external 5V source to supply the
servo with power.
Connect the PWM1 output (PWM1 is RC2 on the PIC which corresponds to pin 13) to one end of an orange wire.
Tap the free end of the orange wire against the yellow servo control wire. If the servo jumps to it's maximum range
and starts screaming, remove the wire immediately! Check your duty cycle to make sure that its within the
allowed range.
Page 49
If the servo moves to the 0 point (the desired response), plug the orange wire in all the way.
You can change the servos position by changing the duty cycle using the pwmduty1 command:
>> pwmduty1 hh
PAGE1
initializeChip
PAGE0
pagesel
call
pagesel
PAGE1
startPWM1
PAGE0
pagesel
PAGE1
movlw h'75'
call
pagesel
setPWMDuty1
PAGE0
banksel
bsf
bsf
bsf
bsf
banksel
BANK1
PORTB,4
PORTB,5
PORTB,6
PORTB,7
BANK0
;
;
;
;
set duty
h'7f' is
h'30' is
set PWM1
mainLoop
; NOTE: These values may be nowhere NEAR the actual angles!
; They are, however, within the safe movement range of h'30' - h'a0'
; Exceeding these values will blow up your servo!
movlw
btfsc
movlw
btfsc
movlw
btfsc
movlw
btfsc
movlw
movwf
h'75'
PORTB,4
h'35'
PORTB,5
h'5C'
PORTB,6
h'84'
PORTB,7
h'9f'
temp
pagesel
movf
PAGE1
temp,W
via temp
via temp
call
;
;
;
;
setPWMDuty1 ;
pagesel
PAGE0
via temp
goto
mainLoop
Connect power to the MicroBoard. Connect the orange wire to the yellow input as before (again, if the servo begins to
scream, remove the wire). The servo should move to the 0 position. If not, unplug everything and examine your
setup thoroughly.
The servo position can be changed by setting pins b4 to b7 high using the set and clear commands or by taking
inputs from an external circuit. The servo will remain in position as long as the line is held high, returning to 0 when
the input stops.
470
Logic Diagram
+5V
16
15
14
13
1
12
11
16 RC5
21 RB0
11 RC0
14 RC3
6
7
8
595
Shift
Register
10
ALL
RED ON
h07
RED +
YELLOW
h3F
ALL
ON
hFF
RED +
YELLOW
h3F
PIC16F873
MicroBoard
NOTE: Remember to connect a resistor in series with all outputs of the PIC to limit current and protect the PIC.
12.2.1 SPI BAR GRAPH IN HOSTED MODE
1
Connect the shift register and LED array using the above diagram.
Connect the serial cable and power and begin a HyperTerminal session.
Type the following (this will initialize the SPI unit and make sure all the LEDs are off):
>>
>>
>>
>>
>>
>>
spiinit
output c0
clear c0
spitrans 00
set c0
clear c0
Cycle through the light levels as you wish. Try out different hexadecimal values:
>> clear c0
>> spitrans hh
>> set c0
>> clear c0
For a bar-graph-esque illumination, use the values 00, 01, 03, 07, 0f, 1f, 3f, 7f, and ff. This will light all the LEDs
in order from red to green (calculate it out if you can't figure out why these values work: 1 hex digit = 4 binary digits.
Example: h03 = b00000011, h1f = b00011111, etc).
PAGE1
initializeChip
PAGE0
cmdSPIInit
temp
movlw
movwf
h'07'
temp
pagesel
movf
call
pagesel
PAGE1
temp,W
transferSPI
PAGE0
;
;
;
;
bsf
bcf
PORTC,0
PORTC,0
call
DelayLong
movlw
movwf
h'1f'
temp
pagesel
movf
call
pagesel
PAGE1
temp,W
transferSPI
PAGE0
;
;
;
;
bsf
bcf
PORTC,0
PORTC,0
call
DelayLong
movlw
movwf
h'ff'
temp
pagesel
movf
call
PAGE1
temp,W
transferSPI
call
clrf
mainLoop
Page 52
pagesel
PAGE0
; back to lower
bsf
bcf
PORTC,0
PORTC,0
call
DelayLong
movlw
movwf
h'1f'
temp
pagesel
movf
call
pagesel
PAGE1
temp,W
transferSPI
PAGE0
;
;
;
;
bsf
bcf
PORTC,0
PORTC,0
call
DelayLong
goto
mainLoop
;**********************************************************************
DelayA
TenMs
movlw
movwf
movlw
movwf
d'13
COUNTH
d'250'
COUNTL
Ten_1
decfsz
goto
decfsz
goto
COUNTL,F
Ten_1
COUNTH,F
Ten_1
; Inner Loop
; Outer Loop
return
;**********************************************************************
DelayLong
LongMs
;movlw
;movwf
d'3'
COUNTH2
Ten_2
decfsz
goto
COUNTH2,F
Ten_3
; Loop
return
Ten_3
call
goto
DelayA
Ten_2
A much better algorithm can be made by applying a logical shift operation (LSL to fans of the 68000-series processors),
using the PIC's rotate function and a bsf command like so:
clrf
call
bsf
call
rlf
temp
LightItUp
temp,0
LightItUp
temp,F
bsf
call
rlf
temp,0
LightItUp
temp,F
bsf
call
temp,0
LightItUp
;
;
;
;
;
;
;
temp
temp
turn
temp
temp
temp
turn
= 0000 0010
STATUS,C = 0
= 0000 0011
STATUS,C = 0
on lights based on temp
is rotated left, and stored back in itself
= 0000 0110
STATUS,C = 0
= 0000 0111
STATUS,C = 0
on lights based on temp
Get the idea? This would sequentially light the first two LEDs in your array. Use rrf to reverse the process.
If a 1 is shifted out of the register (either left or right) it will be moved to the carry register. This allows you to test if the
register is full and execute operations accordingly (if your bar graph is maxed out, then start decrementing values). The
value of the carry register is rotated to the front of the register, so keep this in mind if you have other operations that might
affect the STATUS register. You can implement a technique similar to this to light only one LED and have it move back and
forth along the row (PIC-LED Pong perhaps?).
Init PWM
Init ADC
Main Loop
Duty
Down
Read
ADC
ADRESH - 02
C=1
C=1
Z=1
ADRESL - 00
Z=1
C=0
C=0
Duty
Up
Done
<2.5V
Increase
Duty Cycle
>2.5V
Check
ADC
Decrease
Duty Cycle
=2.5V
Check ADC
Flow Chart
Output
Speed
Page 54
7
L293D
Motor _
In
Motor _
+ Out
12 RC1/PWM2
13 RC2
14 RC3
21 GND
2 RA0
PIC16F873
MicroBoard
Figure 12-2:
Motor Box (with inputs and outputs) and Motor Speed Controller Schematic
The program below checks the voltage on the ADC port, samples it against a hexadecimal value that should be equivalent
to 2.5V, and then adjusts the duty cycle such that it brings the ADC value closer to the 2.5V mark. The code assumes that
the motor will output 0V (hexadecimal 0000) at its stopped speed, and 5V (hexadecimal 03ff) at its maximum speed. If the
motor only outputs to a certain ADC range (say 0100 to 02ff), the code would need to be modified to check for that.
The code also assumes that the delay is long enough to allow the ADC to catch up with the changes in the motor speed;
this may not be the case. In terms of writing the output to the screen, the adcread command automatically prints to the
UART when it is called.
**** ADDED VARIABLE DECLARATIONS ****
COUNTH
COUNTL
EQU
EQU
0x56
0x57
initializeChip
initializeChip
PAGE0
pagesel
call
pagesel
initializeUART
initializeUART
PAGE0
pagesel
call
pagesel
PAGE1
startPWM2
PAGE0
pagesel
movlw
call
pagesel
PAGE1
0xff
setPWMperiod
PAGE0
pagesel
call
PAGE1
initADC
Page 55
pagesel
PAGE0
banksel
bcf
bcf
banksel
BANK1
TRISC,2
TRISC,3
BANK0
mainLoop
bcf
bcf
call
call
PORTC,2
PORTC,3
Delay
cmdADCRead
testhi
movlw
subwf
h'02'
ADRESH,W
btfsc
goto
btfss
goto
goto
STATUS,Z
testlo
STATUS,C
DUTYup
DUTYdown
;
;
;
;
;
testlo
banksel
movlw
BANK1
h'00'
subwf
banksel
ADRESL,W
BANK0
btfsc
goto
goto
STATUS,Z
mainLoop
DUTYdown
;
;
;
;
bsf
pagesel
movlw
addwf
pagesel
PORTC,2
PAGE1
d'1'
CPR2L,F
PAGE0
goto
mainLoop
bsf
pagesel
movlw
subwf
pagesel
PORTC,3
PAGE1
d'1'
CCPR2L,F
PAGE0
goto
mainLoop
DUTYup
DUTYdown
This entire routine can be performed step-by-step in Host mode. Read the ADC line using the adcreadx command
(where x is and ADC line 0 to 4), and then modify the PWM duty cycle accordingly using pwmduty2 hh:
>> pwmstart2
>> pwmperiod ff
>> adcinit
>> adcread0
Page 56
1f0
>> pwmduty2 82
>> adcread0
10k
330
Top
10k
Bottom
LED
phototransistor
21 RB0
22 RB1
23 RB2
24 RB3
Vout
330
PIC16F873
10k
+5V
MicroBoard
Page 57
Figure 12-4:
The code below checks the status of the top and bottom switches and stores them in the two least significant bits of the
W_STAT_NEW register. It checks these against the same bits of the W_STAT register. They are compared following the flow
chart in Figure 12-4. The W_STAT register is then set with the values in the W_STAT_NEW register, and the direction
calculated is stored in the third bit (bit 2) of W_STAT.
******* NEW VARIABLE DECLARATIONS *******
COUNTH
COUNTL
W_STAT
EQU
EQU
EQU
0x56
0x57
0x58
W_TURNS
W_POWER
W_STAT_NEW
EQU
EQU
EQU
0x59
0x5A
0x5B
initializeChip
initializeChip
PAGE0
;
; Initialize the entire Chip to known state
banksel
bsf
bsf
bcf
bcf
BANK1
TRISB,0
TRISB,1
TRISB,2
TRISB,3
bcf
TRISC,1
Page 58
;
;
bcf
TRISC,2
banksel
BANK0
bcf
bcf
PORTC,1
PORTC,2
clrf
clrf
clrf
W_TURNS
W_POWER
W_STAT
bcf
bcf
PORTB,2
PORTB,3
mainLoop
call
call
call
CheckSensors
DirectionDisp
Delay
goto
mainLoop
CheckSensors
clrf
W_STAT_NEW
btfsc
bsf
bcf
PORTB,1
W_STAT,1
W_STAT,1
btfsc
bsf
bcf
PORTB,0
W_STAT_NEW,0
W_STAT_NEW,0
btfsc
goto
goto
W_STAT_NEW,0
NewTopOn
NewTopOff
btfss
return
W_STAT,0
bcf
W_STAT,0
btfsc
bsf
bcf
W_STAT,1
W_STAT,2
W_STAT,2
goto
checkend
btfsc
return
W_STAT,0
bsf
W_STAT,0
btfsc
bcf
bsf
W_STAT,1
W_STAT,2
W_STAT,2
goto
checkend
NewTopOff
NewTopOn
Page 59
checkend
return
DirectionDisp
bcf
bcf
PORTB,2
PORTB,3
btfsc
bsf
bsf
W_STAT,2
PORTB,2
PORTB,3
return
DUTYchange
pagesel
PAGE1
movf
btfsc
movwf
movwf
W_POWER,W
W_STAT,3
CCPR2L
CCPR1L
pagesel
PAGE0
return
;**********************************************************************
Delay
TenMs
movlw
movwf
movlw
movwf
d'13'
COUNTH
d'250'
COUNTL
Ten_1
decfsz
goto
decfsz
goto
COUNTL,F
Ten_1
COUNTH,F
Ten_1
; inner Loop
; outer Loop
return
This example leaves a turn counter to be implemented (fairly trivial, just increment/decrement the W_TURNS register
every time the W_STAT,2 bit is calculated). One could also use this program to control the speed and direction of a motor
using the PWM, the full code to do this is not included but some functions and registers have been set up and commented
out. Also, it is assumed no debouncing is needed; this may be something to investigate.
Page 60
Page 61
A modified H-bridge mounting assembly allows the 7.2V input voltage to be converted to a 3V steady power source for
the motors. It is possible that 5V motors could be inserted in place of the 3V, in which case you would need to modify the
resistor ratio on the 3V-regulator board. This board employs an LM317 chip (variable voltage regulator) which takes an
input voltage and converts it to a Vout between 1.25V and 30V. The ratio of the two resistors on the board determines what
this value will be. Check the LM317 or LM117 data sheet for more information.
The capacitors between the input and output voltages and the ground help keep a nice accurate output voltage. The Hbridge plugs into a socket on this board, which in turn plugs into the MicroBoards H-bridge socket (piggyback style).
Pin 8 (the supply voltage pin) connects to the 3V regulator output, thus bypassing the MicroBoards H-bridge supply
voltage trace.
13.4 QUIRKS
There is a threshold value in the sound recognition function, which allows you to cut out all lower power noise and not
use it in the evaluation process. Currently, the entire sound system runs by comparing only the eight most significant bits
of the input; this will be improved in the next version by checking all 16 input bits. The sound equipment also produces a
fair amount of noise, which could possibly be removed with more advanced filtering hardware.
3V motors are a little too weak for the current application. A 5V motor of the same size could easily replace the current
motors and provide a much stronger and more versatile locomotion system.
You may notice that three of the PSP pull-up resistors have been attached at only one end. This mainly serves to bridge the
gaps in the very small IR sensor output traces. Connecting these resistors puts far too great a load on the IR sensors,
causing erratic behaviour.
Eagle board and schematic files for the 5V to 3V H-bridge supply board
microphone_setup.brd Eagle board and schematic files for the microphone multiplexing/rectifying
microphone_setup.sch
pspboard.brd
pspboard.sch
Eagle board and schematic files for the sensor expansion board
phoenix.brd
phoenix.sch
assembler/hex files for primitive version of final PIC code (pin-outs for sensors in this file under
their declarations)
Page 62
14.2 QUIRKS
One major problem with Snake Turret is the power consumption of the large base motor. This motor cannot take
advantage of the turrets PWM correction for small beacon angles. A 50% duty cycle does not provide enough juice to
keep the big motor going.
Page 63
The skeleton robot is not limited to IR beacons; it could be made to track magnetic field strength, sound, light, TAs,
whatever your imagination can devise. All it requires is a little sensor building on your part, and a few small changes in
the assembler code. Experiment!
Pin #
RB0
RB1
RB2
RB3
RB4
21
22
23
24
25
Motors
Up
Down
Left
Right
Pin #
RC3
RC2
RC0
RC1
14
13
11
12
Lights
Red
Yellow
Green
Pin #
RB5
RB6
RB7
26
27
28
Buzzer
RA1
snakehead.brd
snakerouter.brd
Page 64
15 LINE FOLLOWER
The Line Follower is capable of following a set path given that the line it is to follow is somewhat reflective compared to its
background (for example, white tape on black or dark grey floor). And since this robot has been programmed with short
term memory, it will interpolate between breaks in the line and follow turns that are too sharp for its turning radius.
Pin #
RB0
RB3
RB4
RB5
RB6
21
24
25
26
27
Motors
Pin #
Brown to blue RC0
White to green RC1
Steering
Pin #
Blue to blue
RC3
White to green RC4
11
12
14
15
Power
Sensor 5V
Sensor GND
Pin #
6 aux power conn
2 aux power conn
Power Switches
Side 1
TYCO 6V to NiCd 7.2V
Side 2
barrel connector (+)
Batt GND
TYCO GND to barrel (-)
Other connections made: vias to H-bridge from lines c0, c1, c2, c3
Page 65
program files for autonomous line follower operation (assembler and hex)
lineboard.brd
lineboard.sch
Page 66
1 Cut four pieces of blue (or any other colour except red or black) wire. These will be your control lines.
Solder one end of each wire to each of the four donuts. Make sure your solder joints do NOT contact the rockers .
Cut a piece of black wire and solder one end to the ball of solder directly above the ground plate of the battery
connector.
Solder vias between your PIC and the PORTC H-bridge (resistor locations R17, R18, R19, R20)
Solder the other end of one of the blue wires to the RC0 output of the H-bridge. Do the same for RC1, RC2, and RC3.
Solder the black wire to the ground of the MicroBoard. This creates a common ground
Connect a 6V battery or power supply (your choice) to the red and black wires protruding from the receiver board.
Make sure the antenna is securely fastened to the board with a screw.
Solder your output circuitry to the steering and motor power wires. The motor power lines are the thick brown and
white wires, while the thin blue and white wires control the steering.
When there is no signal there will be no voltage drop across these wires. When a signal is received from the transmitter,
there will be a 6V drop across the affected pair, the polarity determined by the nature of the signal. The demo example has
LEDs connected across the wire pairs to indicate polarity.
Part IV Examples: Both Simple and Complex
Page 67
Burn the DEBUG.HEX file onto the PIC16F873. Connect the serial cable and power to the MicroBoard.
output
output
output
output
set c0
set c1
set c2
set c3
c0
c1
c2
c3
This will set up the board for use by setting PORTC to output. Since the donuts are active low (the rockers are
grounded) we set all the output lines to 9V (the power supply voltage going through the H-bridge. 12V might ruin
the transmitter, so stick to 9V or less). This step ensures that the transmitter is in the off state.
Put the 9V battery into the transmitter unit. If you do this step before initializing the board, the H-bridge output will be
low and the transmitter will begin sending signals with unpredictable results.
To activate individual outputs on the receiver, simply clear the desired PORTC output line. On the demo example you
can control the steering by clearing lines RC0 and RC1, and the motor power with lines RC2 and RC3. You can
deactivate the receiver outputs by setting the desired PORTC line in HyperTerminal.
>> clear c0
>> set c0
If your MicroBoard is set up with hardware flow control, you can run script files. Try the blinking light example over the
RC link.
Page 68
Section V Appendices
Page 69
Section V Appendices
Page 70
Appendix C.
DB9 connector mounting holes and 2.1mm power connector #32 (0.116 inch)
Diodes, voltage regulators and SIP connectors #60 (0.040 inch)
All other component holes #67 (0.032inch)
After using the drill, clean up the mess you have created.
Soldering
Turn soldering iron on and allow time for the iron to heat up. While the iron is heating up, ensure that the sponge is damp
as youll need to clean the tip of the iron prior to soldering. To clean the soldering iron tip, simply wipe the heated tip of the
soldering iron against the damp sponge. The tip should have a bright silvery appearance after you have cleaned it.
1
Insert the component lead into the proper position on the printed circuit board. Dont pull the component too tight
against the board; the component must be able to expand as the temperature changes.
Section V Appendices
Page 71
Use the hot soldering iron held at a 45 angle. The irons tip should come in contact with both the component lead and
the circuit board. Let the iron heat up the component lead and component pad.
Try not to touch the solder to the soldering iron. Touch the solder to the component lead and let the heated lead melt
the solder. Allow the solder to melt and spread around the entire connection. After the solder flows around and
adheres to the part being connected, remove the soldering iron.
Examine the solder connection. If the connection appears to be cone shaped, the proper temperature was reached; bad
solder appears grayish and round.
Cut the components wire lead, leaving a bit of wire protruding from the solder.
Examine the area around the connection and remove any excess solder.
Section V Appendices
Page 72
Appendix D.
Your MicroBoard kit should include the following (do a quick check to make sure):
Qty
1
6
2
5
1
1
1
1
1
1
1
4
3
2
1
2
2
1
1
1
Description
Part Number
C1
C2, C5, C7, C17, C22, C23
C3 plus one for testing
C24-C28
CN1
CN6
D1
IC1
IC4
IC5
IC8
R1, R29, R30 plus one for testing
R23, R24 plus one for testing
R31, R32
Y1
sockets for IC4
sockets for IC5 and IC8
plus one for testing
The assembly checklist begins here (soldering the components in this order would be a good idea):
Description
Part Number(s)
Notes
IN400x diode
D1
R1
R29
R30
470 -watt resistors
330 -watt resistors
R23
R24
R31
R32
01F 50V mono-caps
C24
C25
C26
C27
C28
001F 50V mono-caps
C2
C5
C7
C17
C22
C23
Two 14-pin IC sockets for IC4
Section V Appendices
Y1
CN1
CN6
100F 25V
C1
10F 25V
C3
LM7805
IC1
Before installing any ICs, test the board for proper power connections:
Probe connections
Desired
Value
> 500k
Vcc
+5Vdc
+5Vdc
+5Vdc
+5Vdc
+5Vdc
+5Vdc
+5Vdc
+5Vdc
+10Vdc
-10Vdc
9 Test
Use a DMM to measure resistance. Check for a short circuit from Vcc to
ground (auxiliary power connection pin 1 to pin 3; the auxillary power
connector is the collection of six pads on the top side of the board).
Plug the wall adapter in and connect it to the 2.1mm barrel connector.
Vcc
If, and only if, all the power checks are correct, continue on:
Insert the MAX232 in the IC8 socket. Pin 1 is furthest away from the
DB9 serial connector.
Section V Appendices
Page 74