25
MICROBOARD ADVANCED MANUAL Revised and edited by David Zeibin, Summer 2001 Based on documents by Ben Bathgate, Mike Cumming, Patrick Pilarski, and Paul Bartosek Special thanks to Dr Chris Backhouse

MICROBOARD ADVANCED ANUAL - University of …ee401/resource/manuals/MicroBoardAdv.pdf · HOW TO USE THIS MANUAL Designed to supplement the MicroBoard Manual, the MicroBoard Advanced

Embed Size (px)

Citation preview

MICROBOARD ADVANCED MANUAL

Revised and edited by David Zeibin, Summer 2001

Based on documents by

Ben Bathgate, Mike Cumming, Patrick Pilarski, and Paul Bartosek

Special thanks to Dr Chris Backhouse

HOW TO USE THIS MANUALDesigned to supplement the MicroBoard Manual, the MicroBoard Advanced Manual showcases the new incarnationof the MicroBoard, explains LCD interfacing and low-level PIC programming, and introduces a novel approach toprogramming: artificial neural networks.

Section 1 introduces the newest addition to the MicroBoard family: a bleeding edge micro-controller boardbased on Microchip’s PIC16F877, the grand daddy of the PICs. The new board makes previously difficulttasks relatively easy and opens up a new chapter in PIC-related applications.

Section 2 touches on a subject that, if not given a hand, could take you weeks to get working flawlessly onyour own. Interfacing the PIC with an LCD screen can be a formidable task, but the EE401 team has designeda method that can be implemented fairly easily on either board. In fact, the new MicroBoard has beendesigned to interface with an LCD daughter board using only 14-pin ribbon cable (the subroutines have beenprogrammed into DEBUG877.HEX.

Section 3 introduces some really low-level programming. But as far as programming in assembler code goes,this manual contains nothing extra from that contained in the PIC16F87x data sheet (available athttp://www.ee.ualberta.ca/~ee401/datasheets/PIC16F87x.pdf). The built-in modules featured on the PIC suchas the UART, the ADC, and the PWM, including all three built-in timers are outlined here and the followingsections explain how each module is controlled at the base level allowing you to program the PIC to suit yourneeds exactly.

Section 4 is a short one but could be extremely useful: an explanation of interrupt programming on the PIC.Interrupts can be used in your project as an elegant alternative to never-ending loops.

Section 5 is the king of clever PIC programming. Using a brilliant program written by Gregory Stevens, youcan bypass a fair amount of logic programming. An artificial neural network, when given a set of input dataand its corresponding set of output data, “trains” your robot and gives it the skills to anticipate and respond todata it has never seen before.

This manual, however, holds no guarantees: if you choose to venture here, you do so at your own risk. The TAs willnot be expected to understand everything in here and neither will you. The basic MicroBoard Manual will instillenough knowledge in you to attain a great mark. But if you’re willing to take a chance and experiment, or are just eagerto learn more, this manual should help you on your way.

Be forewarned though, I’ve jumped straight into the lingo and there is not much cross-referencing. This manual has notreceived the same scrutinizing eye of design. It is a collection of pieces with minimal order. Before you go any further,read the entire MicroBoard Manual; you’re going to need the background.

Again, good luck.

David Zeibin

August 2001

TABLE OF CONTENTS1 THE NEW MICROBOARD (PIC16F877)...............................................................................................11.1 Design & Assembly.......................................................................................................................11.2 Programming................................................................................................................................1

2 LCD SCREEN....................................................................................................................................32.1 Using the LCD Screen with the PIC16F873 MicroBoard ..............................................................3Using the LCD Screen with the PIC16F877 MicroBoard..........................................................................32.3 A Few Things to Try......................................................................................................................42.3.1 Writing to the LCD Screen in Hosted Mode.......................................................................................42.3.2 Writing to the LCD Screen in Autonomous Mode...............................................................................4

3 PIC BUILT-IN MODULES....................................................................................................................63.1 Timer Modules..............................................................................................................................63.1.1 Timer 0........................................................................................................................................63.1.2 Timer 1........................................................................................................................................63.1.3 Timer 2........................................................................................................................................73.2 UART.............................................................................................................................................73.3 Pulse Width Modulator.................................................................................................................83.4 Analog-to-Digital Converter.......................................................................................................103.5 Serial Peripheral Interface.........................................................................................................10

4 INTERRUPT PROGRAMMING ..............................................................................................................12

5 ARTIFICIAL NEURAL NETWORKS: AN INTRODUCTION ............................................................................135.1 Getting Things Ready.................................................................................................................135.2 Setting Up and Training Nets .....................................................................................................135.3 Connecting the External Hardware............................................................................................145.4 More Ideas .................................................................................................................................14

APPENDICESAPPENDIX A. MICROBOARD (PIC16F877) SCHEMATIC................................................................................15APPENDIX B. MICROBOARD (PIC16F877) BOARD LAYOUT ..........................................................................16APPENDIX C. UART SAMPLE CODE.............................................................................................................17APPENDIX D. ADC SAMPLE CODE...............................................................................................................18APPENDIX E. SPI PROGRAMMING – GAMEPAD CONTROLLER ..........................................................................20

Section 1 – The New Microboard (PIC16F877) Page 1

1 THE NEW MICROBOARD (PIC16F877)Believe it or not, the second-generationMicroBoard is a much more capable controlsystem outfitted with many of the same featuresbut designed in a more elegant fashion. Thisbleeding-edge board, driven by a MicroChipPIC16F877, has a dedicated SPI connector,programming capabilities, 8kB of programmemory (in contrast with the PIC16F873’s 4kB),eleven extra I/O pins (banks D and E), and easyintegration with an SK10 board.

Although the old board is extremely capable, thenew board is a considerable refinement.Connecting an LCD screen or setting up an SPIbus are much easier tasks, and the addition of aprogramming module allows the newMicroBoard to program other PICs or beprogrammed by another PIC16F877-basedMicroBoard.

Figure 1-1: PIC16F877 pin-out diagram

1.1 DESIGN & ASSEMBLY

For a full schematic and board layout, refer to Appendices A and B.

Of course, this being the MicroBoard Advanced Manual, the documentation on the new MicroBoard is sparse at best.One who decides to use this board must understand the schematic and board layout, and know what each part doesand how it interacts with the other parts. As such, there is no step-by-step walkthrough explaining how to put thePIC16F877-based MicroBoard together. However, given a parts list (the instructor should be able to give you one withthe kit) and the schematic and board layout, one should have relatively few problems constructing this robust piece ofhardware.

1.2 PROGRAMMING

The PIC16F877 is programmed using a PICSTART Plus programmer in almost the exact same manner as thePIC16F873. Be sure to select the appropriate chip from the pull-down menu before you begin programming the PIC.You may also need to change the header in the program you’re compiling.

A DEBUG program has been written for the new MicroBoard also. Fear not, however; it operates in the exact samemanner as the previous version of DEBUG.HEX. See the MicroBoard Manual for the complete list of Hosted modecommands.

One of the greatest strengths of the new MicroBoard, however, is its ability to program other MicroBoards through theHosted mode. Using a 7-pin ribbon cable, connect the programming pin-out on a DEBUG enabled MicroBoard to theprogramming pin-out of the MicroBoard that is to be programmed. The following chart describes the function of eachprogramming pin:

Section 1 – The New Microboard (PIC16F877) Page 2

Connector Pin Programmer Board Connection Connection on Application Board

1 RB3 – Low Voltage Programming Control RB3 – If low voltage programming isdesired (optional) 2 3

2 RB6 – Program Clock RB6 – Program Clock In 2

3 RB7 – Program Data RB7 – Program Data In 2

4 Direct Connection to MCLR MCLR

5 Programming MCLR Output No Connection

6 GND GND

7 VCC – 5V power supply VCC 1

1 The programmer board can supply power to the application PIC chip, but beware that the output power through to the application boardshould be limited to 100mA .2 The connections to RB3, RB6, and RB7 on the application board should be disconnected from other application circuitry during programming.The sole connections should be to the programming board only.3 See Microchip’s documentation website for a description of Programming Modes.

Using low-voltage programming mode means that the board you’re programming does not need to be connected to anexternal power source.

Once everything is connected, attach the serial cable to the DEBUG-enabled MicroBoard, start up a HyperTerminalsession, and plug in the power to the boards (or to just the one board if you’re going to use low-voltage programmingmode).

The “Help” screen should appear. Enter prog to begin the programming routine (or lprog to begin low-voltageprogramming). The program will display the prompt Send file…. A hex file can now be sent as an ASCII text file.Choose Transfer>Send Text File… and select the hex file to send. The transfer in hex file will be displayed on the screenwhile the programming process is underway.

Once programming has finished, disconnect the programming ribbon cable and power up the application board. Thenewly programmed circuit should begin executing the newly installed program.

Section 2 – LCD Screen Page 3

2 LCD SCREENUsing the SPI bus and only three output pins on the PIC, the LCD helper board makes attaching an LCD screen to eitherMicroBoard a relatively painless task.

The schematic in Figure 2-1 shows the pin-outs on the LCD helper board (all resistors are 10kΩ):

Figure 2-1: LCD Screen Helper Board Schematic

For reference, see the LCD screen data sheet and Section 6.4 – Adding Additional Outputs Using Shift Registers in theMicroBoard Manual. For the EAGLE schematic and board layout, see the “Advanced” directory on the EE401 web site:http://www.ee.ualberta.ca/~ee401/advanced/

2.1 USING THE LCD SCREEN WITH THE PIC16F873 MICROBOARD

1 Connect a length of 14-pin ribbon cable to the SPI connector on the LCD board. Be sure to match up the pinassignment correctly (pin 1 on the ribbon cable is signified by a small arrow).

2 Using four lengths of wire, connect RC0 to pin 14 on the other end of the ribbon cable, RC3 to pin 12, and RC5 to pin13. If you want to use the LCD screen with other SPI devices, pin 9 is the chip select line (which will allow you tosend data to the 595 shift register on the LCD board). Keep in mind that the chip select line on shift registers is activelow (if you’re not using any other SPI devices, connect pin 9 to ground or not at all).

3 With DEBUG.HEX programmed onto your PIC, start up a HyperTerminal session. To start up the LCD, enterlcdinit. An initialization message should appear. Use the LCD commands in the MicroBoard manual to controlthe LCD screen.

2.2 USING THE LCD SCREEN WITH THE PIC16F877 MICROBOARD

To the right is the SPI bus pin-out diagram on the new MicroBoard. To connect the LCDscreen, all you need to do is run a 14-pin ribbon cable from the MicroBoard SPI to the SPIconnector on the LCD board. Start up the MicroBoard with DEBUG877.HEX, typelcdinit, and you’re on your way!

RC0 14 13 RC5

RC3 12 11 RC4

RD0 10 9 RD3

RD1 8 7 RD2

GND 6 5 +12V

GND 4 3 -12V

GND 2 1 Vcc

Section 2 – LCD Screen Page 4

2.3 A FEW THINGS TO TRY

There are three parts to this example. The first task will be to simply print “hello world!!” to the LCD screen in hostmode. This quickly becomes a fairly trivial exercise given that the functions for the LCD are already written for you (thistutorial assumes you have already burned DEBUG.HEX onto the PIC).

2.3.1 WRITING TO THE LCD SCREEN IN HOSTED MODE

1 Begin by hooking up the LCD screen to the MicroBoard as described above.

2 Start a HyperTerminal session to begin communication with the MicroBoard (refer to Section 4 of the MicroBoardManual for details).

3 Enter the following commands at the prompt to activate the LCD screen:

>> lcdinit ; this displays the ee401 screen on the LCD>> lcdclear ; clears the initialization message>> lcdput hello ; writes “hello” to the first line>> lcdline2 ; moves the cursor to the second line>> lcdput world!! ; writes “world!!” to the second line

The output on the LCD screen will be something like

helloworld!!

NOTE: The code is not capable of outputting capital letters. Any commands entered with capitals are converted to alllowercase strings before they are parsed. However, direct calls of the subroutines allow upper or lower case.

2.3.2 WRITING TO THE LCD SCREEN IN AUTONOMOUS MODE

Now, we would like to perform the same feat but using the MicroBoard in Autonomous mode. All this requires isDEBUG.HEX and a little tweaking. Make sure the LCD screen is connected as in the above example.

In the start initialization routine, add the lines call cmdLCDInit and call cmdLCDClear. Remove the main code,and replace it with the code shown below (the full source code for this example can be found athttp://www.ee.ualberta.ca/~ee401/examples/lcd/helloworld.asm).

main

startpagesel PAGE1call initializeChip ; initialize the entire Chip to known statepagesel PAGE0

call cmdLCDInit ; initialize the LCD screen and print test pagecall cmdLCDClear ; clear the screen for us

mainLoop

pagesel PAGE1 ; select upper memory so we can access the lcd; functions

; send “hello” to the first line of the LCD

movlw 0x80 ; Set output to first linecall sendLCDCmd

Section 2 – LCD Screen Page 5

movlw 'H' ; send "Hello" to the first line by movingcall sendLCDChar ; each character to the W register and calling

; "sendLCDchar"movlw 'E'call sendLCDCharmovlw 'L'call sendLCDCharmovlw 'L'call sendLCDCharmovlw 'O'call sendLCDChar

movlw 0xC0 ; set output(DDRam) to second line of the LCD; screen (character 41 I think)

call sendLCDCmd

; Send "world!!" to the second line in the same manner

movlw 'W'call sendLCDCharmovlw 'O'call sendLCDCharmovlw 'R'call sendLCDCharmovlw 'L'call sendLCDCharmovlw 'D'call sendLCDCharmovlw '!'call sendLCDCharmovlw '!'call sendLCDChar

pagesel PAGE0 ; return to lower memory

goto mainLoop ; repeat main loop

Compile your edited source code and burn it onto the PIC. Plug the PIC back into the board, connect the power and youshould see the message appear.

Section 3 – PIC Built-In Modules Page 6

3 PIC BUILT-IN MODULESTo make your programming less stressful, the wonderful folks over at Microchip have built several modules into thePIC. These modules automate certain processes such as timing, serial communication, pulse width modulation, andanalog-to-digital conversion. Each of these modules have their own registers to control their operation; once they are set,your code will continue to execute in parallel with the operation of the modules.

What you should know before reading: How to read/write from/to registers across multiple memory pages and howto test registers for single bit and entire byte values.

3.1 TIMER MODULES

There are three timer modules built into the PIC, each of which has it’s own uses. Timer 0 is a general-purpose 8-bittimer/counter. Timer 1 is a 16-bit counter that can be used as a counter for the capture/compare/PWM module. Finally,Timer 2 is an 8-bit timer that can provide a clock signal to the PWM module.

3.1.1 TIMER 0

Timer 0 can function as either a timer or a counter, as a timer it uses Fosc/4 as a reference, and as a counter it counts thenumber of rising/falling edges (user-defined) on the RA4 pin.

This timer module is controlled using the OPTION_REG register. The current value of the timer/counter can be set or readusing the register TMR0. The timer can be scaled using a pre-scale value in the range 20 to 28. Timer 0 can also cause aninterrupt when the value rolls over from FFh to 00h. The following code sample initializes the Timer 0 module to countthe number of rising edges on pin RA4 and assert an interrupt when it counts 1024 of them.

bsf OPTION_REG,T0CS ; count pulses on RA4bcf OPTION_REG,T0SE ; count rising edgesbcf OPTION_REG,PSA ; use watchdog timer prescalerbcf OPTION_REG,PS2 ; use a prescaler of 1:4bsf OPTION_REG,PS1bcf OPTION_REG,PS0

clrf TMR0 ; zero the counter

bcf INTCON,T0IF ; clear any stale interruptsbsf INTCON,T0IE ; enable timer 0 interruptbsf INTCON,PEIE ; enable peripheral interruptsbsf INTCON,GIE ; enable global interrupts

3.1.2 TIMER 1

Similar to Timer 0, Timer 1 can operate as either a timer or counter, although this module has 16-bits of resolution. Usingthe RC0 pin the timer module can count rising edges only. The Timer 1 module is controller with the T1CON register.Since Timer 1 is a 16-bit counter, it has two registers that hold the current count value: TMR1H and TMR1L, hold the highand low byte of the counter, respectively. Another difference is that Timer 1 only has four pre-scale values in the range 20

to 23. When the timer value overflows from FFFFh to 0000h, an interrupt can be produced if the TMR1E bit is set in PIE1.

The distinguishing feature of this timer module is that an external crystal oscillator can be added to provide highlyaccurate timing, up to 200kHz or 5µs, even while the PIC is in sleep mode. The following example shows how to use theTimer 1 module to count an arbitrary number of instruction cycles, 20000 in this case:

movlw 0xB1 ; preload the timer counter withmovwf TMR1H ; 65535 - 20000

Section 3 – PIC Built-In Modules Page 7

movlw 0xFFmovwf TMR1L

bcf T1CON,T1CKPS1 ; use prescale of 1:1bcf T1CON,T1CKPS0bcf T1CON,T1OSCEN ; disable internal oscillatorbcf T1CON,TMR1CS ; select internal clockbsf T1CON,TMR1ON ; turn timer on

bcf PIR1,TMR1F ; clear any stale interruptsbsf PIE1,TMR1E ; enable timer 1 interruptbsf INTCON,PEIE ; enable peripheral interruptsbsf INTCON,GIE ; enable global interrupts

3.1.3 TIMER 2

Timer 2 is an 8-bit module and can only be used as a timer: its intended use is to provide a time base for the PWMmodule. When enabled, the timer counts up until it matches the value in the PR2 register, initializes to FFh on reset, andresets back to 00h. The counter can be pre-scaled by 1:1, 1:4, or 1:16. For every 1, 4 or 16 instruction cycles (Fosc/4) thecounter will increment by 1. Then a post-scaler can be applied to the output of the counter. For every 1-16 times thecounter reaches the value in PR2 an interrupt will be asserted.

The following code initializes the timer to count up to 50 and reset back to zero. Every third time it reaches 50, it willcause an interrupt:

movlw 0x32 ; 0x32 = 50movwf PR2

clrf TMR2 ; reset counter to zero

bcf T2CON,TOUTPS3 ; set postscaler to 1:3bcf T2CON,TOUTPS2bsf T2CON,TOUTPS1bcf T2CON,TOUTPS0bcf T2CON,TMR2ON ; turn timer 2 onbcf T2CON,T2CKPS1 ; set prescaler to 1:1bcf T2CON,T2CKPS0

bcf PIR1,TMR2IF ; clear stale interruptsbsf PIE1,TMR2IE ; enable timer 2 interruptbsf INTCON,PEIE ; enable peripheral interruptsbsf INTCON,GIE ; enable global interrupts

3.2 UART

The Universal Asynchronous Receiver/Transmitter (UART) module communicates through two pins on the PIC: RC6and RC7, the transmit and receive pins, respectively. While the UART is operating these two pins cannot be used asgeneral I/O pins and must be configured as inputs (high-input impedance).

Most likely you will be connecting this communications port to a desktop computer that uses RS-232 logic levels (thePIC uses TTL/CMOS logic levels). By this point in your education, you should know that RS-232 voltage ranges from –15V to +15V and TTL/CMOS ranges from 0V to +5V. To allow the PIC to communicate with such devices an RS-232transceiver is required (the MAX232 chip on the MicroBoard).

Initialization of the UART should be done using the following procedure:

1 Set pins RC6 and RC7 as inputs by setting bits 7 and 6 in TRISC to “1”.2 Write to the TXSTA register with your desired configuration; then write to the RCSTA register.

Section 3 – PIC Built-In Modules Page 8

3 Configure the baud rate generator using the SPBRG register to the desire baud rate (see the PIC data sheet for atable of values for SPBRG).

4 Finally, if you want to use interrupts to communicate, enable them by setting the RCIE and TXIE bits in the PIE1register.

At this point the UART should be properly configured to communicate with the outside world. To transmit data youmust ensure that UART is not busy by checking if the TXIF bit in PIR1 is set. Next, simply write the byte you wish totransmit to TXREG and the UART will take care of the rest. The UART has received data when the RCIF bit in PIR1 is set.The data is available in the RCREG register.

With interrupts enabled, the ISR will be called when either the RCIF or TXIF bits are set by the UART. The registersrelated to UART I/O are described in the table below. See Appendix E – UART Sample Code for initialization,transmission and reception sample code.

Address Name Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

Function

0Ch PIR1 RCIF TXIF Interrupt Status Register

18h RCSTA SPEN

RX9 CREN

FERR

OERR

RX9D

Receive Status Register

19h TXREG Transmit Buffer Data to Transmit

1Ah RCREG Receive Buffer Received Data

8Ch PIE1 RCIE TXIE Interrupt Enable Register

98h TXSTA TX9 TXEN

SYNC

BRGH

TRMT

TX9D

Transmit Status Register

99h SPBRG Baud Rate Register Internal Clock Control

Table 8-1: UART-related Registers

3.3 PULSE WIDTH MODULATOR

Two pins are available on the PIC with 10-bit resolution pulse-width-modulation capabilities (RC1 and RC2). These pinsalso have capture and compare abilities that will not be discussed here. Pulse width modulation is used to controlservomotors and with an external capacitor and resistor can be used as a crude digital-to-analog converter (see Section4.5.2).

The PWM module requires that the Timer 2 module supply a clock signal to it. This clock signal will be used to derivethe period of the PWM signal. Writing to the PR2 register can set the period of the signal.

Use the following formula to calculate the value of PR2 for the desired period:

Period = [PR2 + 1] * 4 * Tosc * (TMR2 Prescale Value)

Initialization of the PWM module is done using the following procedure:

1 Clear the control bits of RC1 and RC2 in TRISC to “0” to set them as outputs.2 Start the Timer 2 module by writing to T2CON.3 Set the period of the PWM signal by writing to PR2; both PWM output signals must have the same period.4 The duty cycle can be controlled individually using the CCPRxL registers for the upper 8 bits of the duty and the

CCPxX and CCPxY bits of CCPxCON are the lower two bits (x denotes the PWM module to be controlled, 1 or 2).5 Finally, enable the PWM modules using the CCP1CON and CCP2CON registers.

Section 3 – PIC Built-In Modules Page 9

To change the duty cycle while the PWM is in operation, write new values to the CCPRxL and CCPxCON registers. Thechanges will not take effect, however, until the current period ends and the next one begins. Furthermore, an interruptcan be generated once every time a new period starts by setting the TMR2IE bit in PIE1.

Address

Name Bit7

Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Function

0Ch PIR1 TMR2IF

Interrupt Status Register

11h TMR2 Timer 2 Counter Register Counter Register

12h T2CON TOUTPS3

TOUTPS2

TOUTPS1

TOUTPS0

TMR2ON

T2CKPS1

T2CKPS0

Control Register

15h CCPR1L

PWM Register 1 (LSB) Duty Cycle Register

16h CCPR1H

PWM Register 1 (MSB) Capture/CompareRegister

17h CCP1CON

CCP1X CCP1Y CCP1M3

CCP1M2

CCP1M1

CCP1M0

Module 1 ControlRegister

1Bh CCPR2L

PWM Register 2 (LSB) Duty Cycle Register

1Ch CCPR2H

PWM Register 2 (MSB) Capture/CompareRegister

1Dh CCP2CON

CCP2X CCP2Y CCP2M3

CCP2M2

CCP2M1

CCP2M0

Module 2 ControlRegister

8Ch PIE1 TM2IE Interrupt EnableRegister

Table 8-2: PWM Control Registers

As an example, we will create a PWM DAC like in the Hosted mode examples section. This code will start the PWMmodule and then enter a repeating loop that does nothing:

startbsf STATUS,RP0 ; switch to page 1bcf TRISC,2 ; set pin as output

movlw B'11111111' ; set PWM periodmovwf PR2bcf STATUS,RP0 ; switch to page 0

movlw B'10000000' ; set PWM duty cycle at ~50%movwf CCPR1Lbcf CCP1CON,5bcf CCP1CON,4

movlw B'00000110' ; start TIMER2movwf T2CON

bcf INTCON,GIE ; disable interrupts

movlw B'00001100' ; start PWMmovwf CCP1CON

loopgoto loop

end

Section 3 – PIC Built-In Modules Page 10

3.4 ANALOG-TO-DIGITAL CONVERTER

Built into the PIC16F873 is a 10-bit analog-to-digital converter with five input channels on pins RA0 through RA3 and RA5.Since the inputs are multiplexed together, the ADC can only sample one input at a time. Also, the RA2 and RA3 pins canbe used as voltage references if the signal being sampled is outside the range of the PIC supply voltage. Take thefollowing steps to configure the ADC module for operation:

1 Set the TRISA register to all “1”s to configure the pins as inputs.2 The ADCON0 register controls the conversion clock, ADC channel selection, and operating mode, configure it

appropriately. Note: Do not change ADC channels and start a new conversion in the same write operation.3 Similarly, the ADCON1 register selects the ADC output format and the configuration of the input pins.

Once this is done the ADC is ready to sample an incoming signal. To start a conversion, set the GO bit in the ADCON0register to “1”. If the ADC interrupt is enabled, an interrupt will be called when the conversion is complete. Otherwise,the user program can poll the GO bit in ADCON0; the ADC will set it to “0” when the conversion is complete. In thefollowing table, the registers that control the ADC are listed (see Appendix G – ADC Sample Code for initialization andoperation of the ADC).

Address Name Bit 7 Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

Function

0Ch PIR1 ADIF Interrupt Status Register

1Eh ADRESH ADC Result Register High Byte ADC Result

1Fh ADCON0 ADCS1

ADCS0

CHS2

CHS1

CHS0

GO ADON

Control register

8Ch PIE1 ADIE Interrupt Enable Register

9Eh ADRSEL ADC Result Register Low Byte ADC Result

9Fh ADCON1 ADFM

PCFG3

PCFG2

PCFG1

PCFG0

Internal Clock Control

Table 8-3: ADC Control Registers

3.5 SERIAL PERIPHERAL INTERFACE

Interfacing with other chips using SPI can drastically reduce the wire count in your project since all the devices will beconnected to a common bus. The SPI bus operates as a master-slave system with the master device controlling allcommunication on the SPI bus (it determines the clock signal and the chip select lines of the slave devices).

Three wires are used in the SPI bus: one input, one output, and one clock signal. Separate input and output lines allowfor synchronous communication between the master and slave (they can both send data at the same time). In a typicalcommunication cycle, the master would select the slave device it wants to communicate with and send eight pulses onthe clock line. On each rising or falling (user selectable) edge the master would shift out one data bit onto the output lineand shift in one data bit from the input line, which is being driven by the slave device.

The PIC can operate in either master or slave mode, in master mode it sends clock signals when it wants to communicatewith other chips but it must also ensure that the proper chip is selected. In slave mode the PIC will not communicateunless it’s slave select line is set. To enable the SPI module on the PIC:

1 Set the SSPSTAT register: it controls the clock edge (master mode only) and several I2C options.

Section 3 – PIC Built-In Modules Page 11

2 Set the SSPCON register: it enables the SPI module, selects master or slave mode, and selects the clock polarity(active high/low).

3 Enable or disable interrupts as desired using the SPIE bit in PIE1.4 Transmission in master mode is initiated by writing a byte to the SSPBUF register. When the transfer is

completed, the incoming data byte will be available in the same register.

Address Name Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

Function

0Ch PIR1 ADIF Interrupt StatusRegister

13h SSPBUF SPI Transfer Buffer Transceiver Register

14h SSPCON WCOL

SSPOV

SSPEN

CKP SSPM3

SSPM2

SSPM1

SSPM0

Control Register

94h SSPSTAT SMP CKE BF Control Register

Table 8-4: SPI Control Register

Section 4 – Interrupt Programming Page 12

4 INTERRUPT PROGRAMMINGInterrupt-based programming is a more efficient method than polling for events. Every time a selected event occurs, thePIC stops execution of the main program and jumps to the interrupt service routine. Once finished, the PIC returns towhere it left off.

Each of the built-in modules has the ability to cause an interrupt for one reason or another. The ADC, for example, cancause an interrupt when it has completed a conversion while the UART can produce an interrupt when its transmitbuffer is empty or when its receive buffer is full.

To enable these interrupts, the modules interrupt enable bit must be set in PIE1 or PIE2. Next, clear the PIR1 and PIR2registers to ensure that no stale interrupt flags cause an interrupt. Then, enable global interrupts by setting both the GIEand PEIE bits in the INTCON register.

When an interrupt occurs, the PIC jumps to the program memory location 0x0004, the interrupt vector. The programspace available in this location is very limited so it’s recommended that you place your interrupt service routine (ISR)elsewhere in program memory and just put a GOTO command in the interrupt vector space.

The same ISR gets called regardless of which event caused the interrupt; therefore, your program must check the PIR1and PIR2 registers to see why the ISR was called. Make sure that you clear these registers after the ISR is done otherwisethe PIC will start the ISR all over again.

The following program initializes the inputs RB7 to RB4 to assert an interrupt when the input level on them changes. TheISR toggles the output state of the PORTA register:

START CODE 0x0000movlw high startmovwf PCLATHgoto start

INT_VECTOR CODE 0x0004goto ISR ; the only command you should

; have here is a gotoMAIN CODEstart

bsf INTCON,GIE ; global interrupts enabledbsf INTCON,PEIE ; internal interrupts enabledbcf INTCON,PBIF ; clear interrupt flagbsf INTCON,RBIE ; enable RB7:RB4 interrupt

bsf STATUS,RP0 ; set the data port, PORTA, for output modeclrf TRISAbcf STATUS,RP0

.

.

.

ISR CODEISR

bcf INTCON,RBIF ; clear interrupt flagcomf PORTA,F ; toggle outputsretfie

Section 5 – Artificial Neural Networks: An Introduction Page 13

5 ARTIFICIAL NEURAL NETWORKS: AN INTRODUCTIONArtificial neural networks (ANNs) are amazingly simple solutions to very complex input/output problems. Throughthe use of an ANN you may take a set of input data and generate a fixed set of results based on that data. The beauty ofthe system is that you don't have to know the function that transforms the input to the output.

The network is "trained" much like you would train a dog or a mother-in-law. You provide it with a set of input dataand show it what it "should" display as output. By repeating the training routine for many different sets of data, thenetwork "learns" the proper function without you having to worry about the nitty-gritty math of the operation. What’smore, you can give the network a vague set of input data, and it will generalize and provide accurate solutions to data ithas never seen! It will adapt to changing circumstances, unlike more rigid digital systems.

More advanced nets (such as those found in competitive learning algorithms and kohonen maps) can learn withoutsupervision, thus classifying the input themselves and creating dynamically changing groupings. In this way, they can“learn as they go”. The more they experience, the more they will adapt and modify their internal generalizations.

Additional systems can be implemented to train the system based on the “pain” or “pleasure” it experiences. This allowsa net to figure out if its last action was correct, and modify its behaviour accordingly. ANNs have many far rangingapplications from image compression to voice recognition to autonomous vehicle control and navigation. Thepossibilities are endless! The human brain is the most complex example of a neural network (besides possibly dolphins,but it could be they just use theirs better), and look at all the twisted things it can accomplish!

5.1 GETTING THINGS READY

ANNs offer a simple way to eliminate the need for complex programming and free up a lot of time to focus ondesigning some elegant hardware. Although this section is written in an instruction-like form, all of this has beencompleted for you already. Used the code (available on the web site) as reference when working through this section; allcode modifications have been clearly documented so be sure to take some time to peruse the C and *.dat files.

Start by making a main program (BOD.c) that can be used by the HP-UX communication software by Dr Backhouse.This main program will allow you to test the board using C code as opposed to the low-level assembler used thus far.

Next, modify the Neural Network Utilities files by Gregory Stevens to allow interfacing with the MicroBoard. Create onefunction in the nndisplay.c file and one in the loadin.c file. Turn the nnwhere.c main function into anindependent function to be called from the BOD main program. This function passes a net by reference to be modifiedby the training routine. Another function takes this net and runs MicroBoard input data through the neurons, deliveringits output to the MicroBoard input pins.

5.2 SETTING UP AND TRAINING NETS

Setting the ANN up is fairly simple. At the beginning of the main nnwhere.c file (or BOD.c or any other mainnnutil.c file), there is a listing of any changes you need to make to the various libraries included. For the most part,you’ll only have to modify the files containing the size of the networks, the number of layers, and the number of inputtraining sets. These are well documented in the nnutils documentation ([in the zip file and ]at the top of each file).

Training the net also happens to be fairly easy. Once you’ve set the number of training sets in the file nninputs.c, editthe nninputs.c and nnouput.c files. Place the input test pattern (input data) and desired output (output data). Theprogram does not take formatting into account (you could have one big line of numbers), but for clarity’s sake, divideyour input/output data into matching blocks of input/output pairs. The main program will run through these files toformulate the best way to produce the output from the given input. You can set the number of times the net will be

Section 5 – Artificial Neural Networks: An Introduction Page 14

exposed to the training set at the top of the training program (nnwhere.c or BOD.c). Generally, more is better: thelonger you train a net, the more accurate the results. There is a point, however, where further training will not produce anoticeable effect on the output accuracy. If you can find this “saturation point,” you can get the most out of the net withthe least time expended.

5.3 CONNECTING THE EXTERNAL HARDWARE

Simply connect your external hardware’s output lines to the MicroBoard’s input lines and the inputs of the circuit to bemanipulated to the MicroBoard’s output lines. With the programming set aside, you are free to design great arrays ofhigh accuracy sensor hardware and complex motor/visualization devices.

5.4 MORE IDEAS

There are many much more advanced ANNs out there. Some can be designed to recognize faces, encrypt data, drivecars, control robotic arm position and dynamics, and even pick out good songs based on harmony.

ANNs allow you to take any input function and generate a corresponding output function; all the math is left up to thenet. With enough hidden layers it’s possible to perform absolutely all transforms.

The human retina uses a neural net to detect light and map that pattern to the corresponding part of the brain. The samecan be accomplished by an array of photocells connected to a MicroBoard (with a slight decrease in complexity ofcourse). Nets that train themselves using the input they see as desired outputs present another possibility: these nets areable to “remember” and reproduce things they have seen, even from incomplete or inaccurate input data. This allows abit of “smoothing” to be applied to your input data.

Example: Your robot sees a person enter the lab. If that person happens to be your TA, the robot knows it must launch asmall high-velocity projectile at his shiny forehead. A standard robot would refrain from shooting if your TA hadchanged his appearance in any way or if he was slightly off center in the robot’s field of view. With an ANN-trained bot,even though your TA actually shaved and changed his clothes, he’ll still be conked on the noggin by a small robot-launched projectile.

Be creative! You have a small primitive brain at your disposal (No, not your brain, the ANN). The possibilities areendless. New ANN software is being produced on a daily basis all around the world for free. A web search will turn upmore than enough information to get you started. I recommend Gregory Steven's NNUTIL V1.0 as a good startingpoint, as well as the book An Introduction to Neural Networks by Ben Krose and Patrick van der Smagt (free in PDFformat on the net).

For a few examples, browse through the basic_ann and snaketurret.ann folders in the EE401 web site’s“advanced” section: http://www.ee.ualberta.ca/~ee401/advanced/

Appendices Page 15

Appendix A. MICROBOARD (PIC16F877) SCHEMATIC

Appendices Page 16

Appendix B. MICROBOARD (PIC16F877) BOARD LAYOUT

Appendices Page 17

Appendix C. UART SAMPLE CODE

#include <p16f873.inc>

global InitUARTglobal PutUARTglobal GetUART

UART CODEInitUART

bsf STATUS,RP0

; set PORTC pins as inputs (high input impedance)bsf TRISC,6bsf TRISC,7

; disable uart interruptsbcf PIE1,RCIEbcf PIE1,TXIE

; initialize transmit and receive status registersmovlw B'00100100'movwf TXSTA

bcf STATUS,RP0movlw B'10010000'movwf RCSTAbsf STATUS,RP0

; init baud rate generatormovlw 25 ; 9600 baud (see table in pic16f873 datasheet)movwf SPBRG

bcf STATUS,RP0return

; Waits for the UART to clear the transmit buffer; and then sends a byte out; input: W -> char to transmitPutUART

bsf STATUS,RP0btfss TXSTA,TRMTgoto PutUARTbcf STATUS,RP0movwf TXREGreturn

; Waits for a byte to be received by the UART; output: W -> byte received by UARTGetUART

btfss PIR1,RCIFgoto GetUARTmovf RCREG,Wreturn

end

Appendices Page 18

Appendix D. ADC SAMPLE CODE

#include <p16F873.inc>

global GetADCglobal InitADC

variables UDATAadc_line res 1

ADC CODE

; Starts a conversion using the ADC and waits for; completion; input: W -> lower 3 bits determine which ADC line to use; output: result is available in ADRESH and ADRESLGetADC

movwf adc_line

bcf ADCON0,CHS0 ; select ADC line to usebtfsc adc_line,0bsf ADCON0,CHS0

bcf ADCON0,CHS1btfsc adc_line,1bsf ADCON0,CHS1

bcf ADCON0,CHS2btfsc adc_line,2bsf ADCON0,CHS2

movlw 1 ; wait for ADC input to settlecall Delay ; ~256 us

bsf ADCON0,GO ; start conversion

ADCLoopbtfsc ADCON0,GO ; wait for conversion to finishgoto ADCLoop

bcf PIR1,ADIF ; clear conversion complete flag

return

; Initialize ADC to use Fosc/2 and input line 000; input line can be selected on a per conversion basis; using GetADCInitADC

bsf STATUS,RP0

clrf TRISA ; setup PORT A for inputcomf TRISA

bcf PIE1,ADIE ; disable ADC interrupt

bcf STATUS,RP0

movlw B'00000001' ; initialize ADCmovwf ADCON0

bsf STATUS,RP0 ; put lower 8 bits of resultmovlw B'10000000' ; in ADRESL and upper 2 inmovwf ADCON1 ; ADRESHbcf STATUS,RP0

bcf PIR1,ADIF ; clear conversion complete flag

Appendices Page 19

return

; Delay function, uses timer0 to delay execution by an exact amount; input: W -> delay time (W*256*4/Fosc seconds)Delay

sublw 0xff ; move delay count to TMR0movwf TMR0

clrf INTCON ; initialize timerbsf STATUS,RP0movlw B'11010111' ; 1/256 prescale (TMR0)movwf OPTION_REGbcf STATUS,RP0

DelayLoopbtfss INTCON,T0IF ; wait for overflowgoto DelayLoop

bsf STATUS,RP0 ; shut timer offbsf OPTION_REG,T0CSbcf STATUS,RP0return

end

Appendices Page 20

Appendix E. SPI PROGRAMMING – GAMEPAD CONTROLLERThis is a sample program that accesses the PICs SPI system to communicate and get information from a SonyPlaystation Gamepad. The SPI section in the PIC16F87x datasheet should be read to gain an understanding of how theSPI registers are configured and used. The protocol used by gamepads for the Playstation is not well documented as itpertains to specific gamepads but an excellent document is located on the Internet(http://home.quicknet.com.au/andrewm/psx/psxcont/index.html). The are many versions of gamepads, from simpleones like the one used here to force feedback and rumble pack versions. DEBUG.HEX was used to view the datareturned from the gamepad. The following is a script file called to transfer the data:

spiinitoutput b4input b3clear b4spitrans 80spitrans 42spitrans ffspitrans ffspitrans ffspitrans ffspitrans ffspitrans ffset b4

The set of data returned by this script is similar but not exactly the same as what is in the documentation. An amount ofexperimentation will be required on a project using a gamepad of this type. The following is a code example using theprovided SPI subroutines in the debug code.

;************************************************************************; 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 interfaces a Sony Playstation Gamepad ; into the SPI (serial peripheral interface) connection on Port C.; The simple protocol used by the gamepad is found in the SonyPlay.txt ; file on the EE401 web site.;************************************************************************; Filename: SPIsample.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 ; list directive to define processor#include <p16f873.inc> ; processor specific variable definitions

; '__CONFIG' directive is used to embed configuration data within .asm file.; The labels following the directive are located in the respective .inc file.; See respective data sheet for additional information on configuration word.

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _XT_OSC &_WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

Appendices Page 21

errorlevel -302 ; These remove unwanted warningserrorlevel -305 ; from the compile information listingerrorlevel -306

;***** VARIABLE DEFINITIONS;**** General Variables; No variables

;********* CONSTANTS *************

;** Directive Data ConstantsBANK0 EQU 0x0000BANK1 EQU 0x0080BANK2 EQU 0x0100BANK3 EQU 0x0180

PAGE0 EQU 0x0000PAGE1 EQU 0x0800PAGE2 EQU 0x1000PAGE3 EQU 0x1800

TRUE EQU 1FALSE EQU 0

;**********************************************************************ORG 0x000 ; processor reset vectorclrf PCLATH ; ensure page bits are cleared

goto main ; go to beginning of program

main

startbanksel BANK1clrf TRISB ; Port B is used as an output display thoughbanksel BANK0 ; 16 buttons are available when reading theclrf PORTB ; data from the gamepad.

banksel BANK1bsf TRISD,1 ; Ack line signal from gamepadbcf TRISD,2 ; Att or /Enable line to signal gamepadbanksel BANK0bcf PORTD,1 ; Ack line, initializedbsf PORTD,2 ; Att line, normally high

pagesel PAGE1call initializeSPI ; Call to SPI init. routine in Page1 of Program

memorypagesel PAGE0

mainLoop

pagesel PAGE1bcf PORTD,2 ; Clear Att line to reset gamepad and begin

; transfermovlw 0x01call transferSPI ; return value is usually 0movlw 0x42call transferSPI ; return value is the type of controller

; many types are undocumentedmovlw 0xFFcall transferSPImovlw 0xFFcall transferSPIbsf PORTD,2 ; Set Att line end transfermovwf PORTBpagesel PAGE0

goto mainLoop ; Repeat main loop

Appendices Page 22

;****************************************************************;*** PAGE 1 Subroutines;****************************************************************

org PAGE1;****************************************************************

;*******************************************************************; SPI Module Subroutines - Master Mode only;*******************************************************************

;*******************************************************************; Function subroutine to initialize the SPI pins. The; communication protocol is set to perform data transfer on; a rising edge clock. See spec. sheet and the Mid-range; pic manual to see how to modify code to other protocols.; receives: nothing; uses: W; returns: nothing;*******************************************************************initializeSPI

banksel BANK1 ; Select Bank1bcf TRISC,3 ; SPI CLKbsf TRISC,4 ; SPI Data inbcf TRISC,5 ; SPI Data outclrf SSPSTAT ; SMP = 0, CKE = 0, and clear status bits

banksel BANK0 ; Select Bank0bcf PIE1,SSPIE ; Clear int-flags, Disable interruptsclrf INTCON ; Clear int-flags, Disable interruptsbsf PORTC,0 ; SPI chip selectbcf PORTC,3 ; SPI CLKbcf PORTC,4 ; SPI Data inbcf PORTC,5 ; SPI Data outmovlw 0x32 ; Set up SPI port, Master mode, CLK/64,movwf SSPCON ; Data xmit on rising edge (CKE=0 & CKP=1)

return

;*******************************************************************; Function subroutine to perform data transfer over SPI pins.; receives: W - data to be sent; uses: W; returns: W - data received;*******************************************************************transferSPI

movwf SSPBUF ; Start Transmission

banksel BANK1 ; Select Bank1btfss SSPSTAT, BF ; Has data been receivedgoto $ - 1 ; Nobanksel BANK0 ; Select Bank0

movf SSPBUF, W ; W register = contents of SSPBUF

bcf SSPCON,SSPEN ; disable SPI peripheralbsf SSPCON,SSPEN ; enable SPI peripheral

; The previous 2 bcf and bsf instructions are; are required for proper device operation; as per device errata.

return

END ; Directive 'end of program'; Code reaching this point may perform erratically.