Program description

What does it do?

The output program shows you how to light up the LEDs. Once you know how to turn on lights, it's just as easy to turn on motors and other output devices.

New instructions

During this activity, you will learn about these microcontroller instructions:

goto jump to (or continue running the program) from a label
movlw 'move literal to W' - move a number (also known as a literal, or constant) into W (the working register)
movwf 'move W to file register' - move the number in W to a file register (a RAM location)
clrf 'clear file register' - clear the contents of a file register (a RAM location)
sleep stop the microcontroller clock, and shut down the processing unit

New directives

This program introduces many directives. Like instructions, directives are a part of the program. But, whereas instructions control the microcontroller, directives control the operation of the MPLAB assembler.

list lists the microcontroller type
include inserts a file into the program
__config sets up the hardware features of the microcontroller (dependent on a programmer that can read these settings)
org 'origin' - sets the starting program memory address for the next instruction
banksel 'bank select' - inserts instructions for the microcontroller to switch to the file register bank containing the specified file register
res 'reserve memory' - reserves the specified number of register addresses
end signifies the end of the program

Jumper positions

The CHRP jumpers need to be set to the following positions in order for this program to function.

J7 - serial receive - Ser. position
J8 - serial transmit - Ser. position
J9 - analogue input - n/a
J11 - power select - Cont. position
J13 - voltage divider - n/a

Output programming activity

Let's start programming the CHRP by making it turn on some LEDs. This program will also let you test all of your LEDs to make sure that they work.

What you should know before starting

CHRP related information

This program controls the LEDs connected to PORTB of the PIC microcontroller (see the CHRP 1.2 schematic to view the PORTB circuitry).

Microcontroller related information

PORTB is an 8-bit RAM register, known as a file register Microchip terminology, that connects the processing unit core to external I/O (input/output) pins. PORTB is an 8-bit port, so it can control 8 individual circuits. Each of the PORTB pins can be either an input or an output, depending on the value in the TRISB register.

TRISB (TRIState for port B) is an 8-bit file register (RAM memory location) that controls the input/output status of the PORTB pins. A value of 0 written into a TRISB bit makes the corresponding PORTB pin an output. A value of 1 written into a TRISB bit makes the corresponding PORTB pin an input. For example, writing the 8-bit number 00000111 into TRISB would cause the upper five PORTB pins to become outputs, and lower three PORTB pins to become inputs.

The PORTB and TRISB file registers are located in two different file register pages (RAM banks) inside the microcontroller (see the simplified PIC16F876 block diagram for an arthitectural overview of the microcontroller). The PIC's STATUS register controls access to the register banks, but we'll use the banksel directive (see New Directives at left for its description) to indirectly control the STATUS register and simplify our program.

Almost all math, logic and data movement instructions in the PIC microcontroller involve the use of W, the Working Register (see the simplified block diagram, above). This program, for example, lights the LEDs by moving a pattern from the program (stored in the program memory), to PORTB (in the file registers) by performing a two step move through the W register. The pattern is first loaded into W by one instruction, then a second instruction is required to move the pattern to its final destination in the RAM register. The simple architecture of the low- and mid-range PIC microcontrollers makes the two-step move a requirement.

Program requirements

To use this program you will need:

An assembled CHRP board.

A PIC16F876A microcontroller pre-programmed with the bootloader code (see the PIC info page) or PIC16F876A microcontroller and a stand-alone PIC programmer capable of programming it.

A Windows PC with the MPLAB IDE software.

The Windows downloader software (included with the bootloader code), and a 9-pin serial cable or USB to serial adapter if your computer does not have a serial port.

A 6-12V wall adapter, or a power supply, or batteries to power the CHRP.

Before you continue, you will need to know how to edit, assemble and simulate a program in MPLAB (MPLAB tutorial coming soon!).

Create the program

The entire OUTPUT.ASM program is shown below. Start a new MPLAB project, copy all of the OUTPUT.ASM code into the project, and assemble (make) the program.


;OUTPUT.ASM 	v1.2	Last modified on July 28, 2007
;===============================================================================
;Description:	Output test program. Lights up PORTB LEDs.

;Start of MPLAB and processor configuration.

	list	 p=16F876A		;Define processor type
	include	"p16f876a.inc"		;Include processor definitions

	__config  _CP_OFF & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _LP_OSC

;End of MPLAB and processor configuration.

	org	00h			;Start of program memory

		goto	Init_Ports	;Jump to initialize routine

	org	05h

Init_Ports	;Set Ports B and C to support CHRP digital circuitry.

		banksel	TRISB		;Switch to the TRISB register bank
		movlw	01010111b	;Enable Port B pull-ups, internal TMR0
		movwf	OPTION_REG	;clock with prescaler of 256
		clrf	TRISB		;Set all LED (Port B) pins as outputs
		movlw	10110000b	;Set up serial input and output pins,
		movwf	TRISC		;and set motor pins as outputs
		banksel	PORTB		;Return to PORTB register bank

Main		movlw	11000011b	;Send light pattern to
		movwf	PORTB		;Port B LEDs

		sleep			;Stop at end of program

	org	1F00h			;Start of bootloader code area
	res	256			;Reserve memory for bootloader

	end
		

If the program does not assemble, or generates errors or warnings during assembly, check that the entire __config directive is on one line, that you didn't accidentally miss any of the code, and that the project settings for the program disable case sensitivity and use decimal as the default radix (see the MPLAB tutorial).

Once the Output program builds successfully, program it into your microcontroller to see it work. Four lights should be lit—the top two (LED2 and LED3), and the bottom two (LED8 and LED9).

How the program works

This program, like most programs, starts with some comments. In MPLAB, anything following a semi-colon (;) is a comment and is ignored by the assembler.

You might want to reference the simplified PIC16F876 block diagram to help visualize what happens inside the microcontroller during the following explanations.

Comments and directives


;OUTPUT.ASM 	v1.2	Last modified on July 28, 2007
;===============================================================================
;Description:	Output test program. Lights up PORTB LEDs.

;Start of MPLAB and processor configuration.

	list	 p=16F876A		;Define processor type
	include	"p16f876a.inc"		;Include processor definitions

	__config  _CP_OFF & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _LP_OSC

;End of MPLAB and processor configuration.

	org	00h			;Start of program memory

		goto	Init_Ports	;Jump to initialize routine

	org	05h
		

The list, include, and __config directives prepare MPLAB to read and assemble the program by setting the processor type, inserting a file containing information about the processor, and configuring the processor hardware features, respectively. Directives are read and understood only by the assembler—they are not programmed into the microcontroller.

org 00h is a directive that tells the assembler where to write the program into the micrcocontroller's program memory. By using a data address of 00h, org tells MPLAB to store the first program instruction into the first memory location (address 0), which is also known as the Reset Vector. The Reset Vector is the memory location that the microcontroller always goes to on power-up or after a hardware reset, so the first program instruction should always be stored there.

Immediately following the org 00h directive is the goto Init_Ports instruction. The goto data Init_Ports refers to the Init_Ports label (two lines further down in the program), but MPLAB doesn't know where this label is yet—computers can't read ahead, like us. MPLAB actually reads the entire program once (called the first pass), and then goes back re-reads the program, filling in the things it didn't know (the second pass). Since the Init_Ports label follows the org 05h directive, this instruction actually becomes goto 05h after the assembler's second pass. The label names are really only there to make the program more readable for us.

Processor initialization


Init_Ports	;Set Ports B and C to support CHRP digital circuitry.

		banksel	TRISB		;Switch to the TRISB register bank
		movlw	01010111b	;Enable Port B pull-ups, internal TMR0
		movwf	OPTION_REG	;clock with prescaler of 256
		clrf	TRISB		;Set all LED (Port B) pins as outputs
		movlw	10110000b	;Set up serial input and output pins,
		movwf	TRISC		;and set motor pins as outputs
		banksel	PORTB		;Return to PORTB register bank
		

The Init_Ports label groups together all of the instructions that prepare the processor to do what we want it to. Init_Ports has no other meaning than just being a name for this part of the program. We could have named the routine by any other name instead, but it makes more sense to give program subroutines names that describe what they actually do—initialize the input/output (I/O) ports, in this case.

banksel TRISB is a directive that tells MPLAB to insert the instruction(s) needed to switch to the file register (RAM) bank containing the TRISB register. The microcontroller block diagram shows us that the TRISB register is in bank 1 of the memory. We need to switch memory banks because the microcontroller starts up in bank 0.

The next two instructions work together to change the contents of a file register address. movlw stands for 'move literal to W'. movlw 01010111b copies the data 01010111 (the literal) from the program memory into the W register inside the core of the processing unit. From there, movwf OPTION_REG moves the data from W to the OPTION_REG register in bank 1. movwf is the assembly code instruction 'move W to file register'. Even though we used the banksel directive to prepare to use TRISB, we can also write to OPTION_REG because they are both in bank 1. The value in OPTION_REG controls a number of the microcontroller's internal features, but we'll look at its function more closely in the following activities.

clrf TRISB is a quick way to fill the TRISB register with zeros. clrf represents the 'clear file register' function. Putting zeros into all of the TRISB bits makes all of the PORTB pins (those connected to the LEDs) into outputs.

movlw 10110000b and movwf TRISC write the data 10110000 into the TRISC register to make some of the PORTC pins outputs, and the rest inputs. Look at the parts connected to PORTC on the CHRP schematic, and it should become clear as to why this combination of inputs and outputs is used.

Finally, banksel PORTB tells the assembler to switch back to addresses in bank 0 of the file registers, and finishes the Init_Ports subroutine.

The main subroutine

Main		movlw	11000011b	;Send light pattern to
		movwf	PORTB		;Port B LEDs

		sleep			;Stop at end of program

	org	1F00h			;Start of bootloader code area
	res	256			;Reserve memory for bootloader

	end
		

The Main label starts the functional code of the output program. The combination of movlw 11000011b and movwf PORTB once again transfers data from the program memory, through W, into the microcontroller's file (RAM) registers. Since the PORTB register connects to the LEDs, the LEDs light up in a pattern matching the data. By referring to the schematic diagram and the circuit board while programming, you can choose which LEDs to light. To light just LED2 (the top LED) for example, change the data to 00000001b.

Finishing up

sleep is probably fairly self-explanatory, which is a good thing since you have been digesting a lot of assembly code already! During sleep, the micrcocontroller shuts its processing core down, but keeps its I/O circuits powered. So, although no more instructions are being executed by the microcontroller, the LEDs remain lit.

The org 1F00h and res 256 directives instruct MPLAB to reserve the last 256 locations of the microcontroller's memory, protecting the contents of these addresses from being overwritten. These last 256 program memory addresses contain the bootloader program that lets the CHRP program itself, and these directives ensure that we don't accidentally over-write it.

The end directive is required to tell the assembler when it has reached the end of the program code. MPLAB ignores anything you write after end, so you can use that space to keep notes about the program, write reminders to yourself about new features, create a shopping list, etc. (Okay, maybe you should find a better way to do a shopping list!)

Program simulation

MPLAB has a built-in program simulator called MPLAB-Sim. You can use the simulator to verify the operation of a program such as Output before programming the code into your microcontroller. The simulator gives you a virtual peek inside the processor, so you can visually watch what your program code is doing—or not doing! Simulators are also able to time the execution of your program, which becomes very important in a lot of microcontroller applications.

Oh, in case you were wondering, running this program in a 4MHz PICmicro takes 13µs (microseconds), or thirteen millionths of a second. Then, with it's work all done, the microcontroller goes to sleep.

Test your knowledge

  1. Assembly code programs contain comments, labels, directives, instructions, and data. What is the difference between a directive and an instruction? What is the difference between a comment and a label?
  2. The Output program contains seven different directives. List each directive and describe its function.
  3. The PIC16F876A microcontroller contains more than one kind of memory. What kind of memory are the file registers made of? What special features do the PORTA, PORTB, and PORTC file registers have?
  4. We refer to registers by name, but the microcontroller refers to registers by their numeric address. What are the addresses of the TRISB and PORTB registers?
  5. What is the W register, and where inside the microcontroller is it located?
  6. What is the function of the TRISA, TRISB, and TRISC registers?
  7. What value would need to be written into the TRISB register to make the bottom six LEDs of the CHRP board into outputs, and the other PORTB pins into inputs?
  8. Each program instruction takes one or more processor clock cycles to execute. Use the MPLAB simulator to determine how many clock cycles each instruction takes to run.

Apply your skills

  1. Modify the Output program to turn on all of PORTB LEDs (useful for testing your circuit board if you haven't already done so).
  2. Modify the Output program to repeatedly display two or more different light patterns on the LEDs and program it into your CHRP (hint: create another output pattern and use a goto instruction to repeat the patterns). Run the program and describe its output. Is it what you expected? Explain why not.
  3. The CHRP motor driver IC can control two DC motors by moving data into the low nybble (4 least significant bits) of PORTC. Use the schematic diagram to help you determine the bit patterns required to make each motor turn forward, reverse, or stop. Connect motors to the CHRP board and verify their operation.