Program description

What does it do?

The Math program demonstrates literal (constant) and register-based (variable) math instructions.

New instructions

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

addlw 'add literal to W' - adds the contents of a constant specified in the program to the W register.
sublw 'subtract W from literal' - subtracts the contents the W register from a constant supplied by the program.
addwf 'add W to file register' - adds the contents of the W register to the contents of a file register. The result of this addition can be left in the W register or in the file (RAM) register by appending W, or F to the instruction, respectively.
subwf 'subtract W from file register' - subtracts the contents of the W register from the contents of a file register. As in addwf, above, the result can be stored in W or the file register by appending W or F to the instruction.

Math programming activity

The Math program demonstrates the three primary ways of performing addition and subtraction operations in mid-range PIC microcontrollers as well as introducing the functions of the status register bits Z, DC and C. This program also demonstrates the use of the equate directive to reference a RAM register.

What you should know before starting

Microcontroller related information

The only two types of mathematical operations directly supported in mid-range PIC microcontrollers are addition and subtraction. Each math operation can be performed using constant or variable data, resulting in a total of four available math instructions: addlw, addwf, sublw and subwf.

The internal W register (see the simplified PIC16f886 diagram) is used during all math operations in the mid-range PICmicro microcontrollers. One of the numbers being added or subtracted needs to be loaded into W before the math operation can proceed. This first number can be a constant supplied by the program, or a variable quantity stored in the RAM file registers, and is simply moved into W before the math operation. Then, the math instructions perform their operations on the number already in W and a second number that can be supplied as a literal (constant) or the contents of a file register. Finally, math register operations can either store their result back in the register (thus over-writing it), or in W.

Status register bits

The Count program used the Z bit in the Status register to check for a zero result in the TMR0 timer register. The Z (Zero) bit, as well as the DC (Digit Carry) and C (Carry) bits of the Status register are all affected by all math operations. During simulation, the state of the Z, DC, and C bits is shown in the bottom status bar of the MPLAB IDE. Their state is represented by the letter state—an upper-case letter means the bit is set, and a lower case letter means the bit is clear. For example, seeing Z dc C indicates that a Carry has taken place, the result of the operation is zero, and no digit carry occurred.

Each Status register bit corresponds to specific states:

Using registers as variables

The programs we have created up to this point have used some of the pre-defined registers in the PIC16F886 microcontroller. Looking at the simplified PIC16f886 diagram, we can see that there are a total of 368 RAM addresses available for use in the PIC16F886, with the first free memory register residing at address 20h in bank 0. Memory registers can be labelled with variable names, and have their names assigned to the memory address using equate directives. As with earlier equate examples, the equate statement has no inherent knowledge of what is being equated: bits, bytes, or addresses. Equates simply allow a numeric value to be substituted for the label name later in the program.

Program requirements

To use this program you will need:

An assembled CHRP 3 board, an optional power supply, a programmer and/or programming cable, and a computer with the MPLAB IDE or MPLAB X software as described in the Output activity.

Create the program

The entire MATH.ASM program is shown below. Create a Math project in MPLAB, copy this code into it, and build the program.

;Math			v3.1	January 14, 2013
;Description:	Demonstrates math between constants, constants and registers,
;				and registers.

;Configure MPLAB and the microcontroller.

	include	""		;Include processor definitions

	__config _CONFIG2, _WRT_OFF & _BOR40V

;Set RAM register equates.

num1			equ	20h				;RAM storage register for the first number
num2			equ	21h				;RAM storage register for the second number

;Start the program at the reset vector.

				org	00h				;Reset vector - start of program memory

				clrf	PORTA		;Clear all port outputs before configuring
				clrf	PORTB		;port TRIS registers. Clearing RA4 turns on
				clrf	PORTC		;the Run LED when TRISA is initialized.

				goto	initPorts	;Jump to initialize routine

				org	05h				;Continue program after the interrupt vector

initPorts       ;Configures PORTA and PORTB for digital I/O.

				banksel	ANSEL		;Switch register banks
				clrf	ANSEL		;Set all PORTA pins to digital
				clrf	ANSELH		;Set all PORTB pins to digital
				movlw	01010111b	;Enable Port B pull-ups, TMR0 internal
				movwf	OPTION_REG	;clock, and 256 prescaler
				banksel	TRISA		;Switch register banks
				movlw	00101111b	;Set piezo and LED pins as outputs and
				movwf	TRISA		;all other PORTA pins as inputs
				clrf	TRISB		;Set all PORTB pins as outputs for LEDs
				banksel	PORTA		;Return to register bank 0

main			;Preload the number registers for later use

				movlw	6			;Save these constants in the RAM registers
				movwf	num1
				movlw	4
				movwf	num2

conCon			;Demonstrate math operations using two constants.

				movlw	7			;Load W with the first constant and
				addlw	5			;add the second constant to W

				movlw	4			;Load W with the first constant and
				sublw	13			;subtract it from the second constant

regCon			;Demonstrate math operations between a constant and the contents
				;of a file register.

				movf	num1,W		;Copy the contents of num1 into W and
				addlw	8			;add a constant to W

				movlw	2			;Load W with a constant and
				addwf	num1,W		;add the contents of num1, keeping the
									;result in W
				addwf	num1,f		;Now, add contents of num1 to W again,
									;overwriting the contents of num1

regReg			;Demonstrate math operations between the contents of two
				;file registers.

				movf	num1,W		;Copy the contents of num1 into W and
				addwf	num2,W		;add contents of num2 to W

				movf	num1,W		;Copy the contents of num1 to W again
				addwf	num2,f		;and add to num2, overwriting num2

				sleep				;Stop at end of program


You won't need to download this program to your CHRP board—just run it in the MPLAB Sim debugger. Set up a watch window to watch the contents of the W register and file registers 20h and 21h. Step through the program and observe the contents of the registers after each step. Also observe the contents of the Status register bits: Z, DC and C.

How the program works

Really? Hopefully you got to this section by simulating and reading along, and didn't jump here to find out how the program really works. After having built and simulated the program, you should have been able to follow the code to figure out its exact sequence of operations. There really are not any complex operations taking place.

The only really important thing to keep in mind when doing register math is determining where you would like the answer to be. Beware that specifying a file register destination (as in addwf num1,f) over-writes the original number in the register. Using ,W as the destination leaves the contents of the file register untouched.

Test your knowledge

  1. Add two numbers that produce a sum equal to or less than 255. What is the state of the Z, DC and C bits in the Status register?
  2. Add two numbers that produce a sum equal to 256. What is the state of the Z, DC and C bits this time?
  3. Add two numbers that produce a sum greater than 256. What is the state of the Z, DC and C bits after this addition?

Apply your skills

The Math program demonstrates the used of the sublw operation, but not subwf. Modify the regCon and regReg subroutines to perform subtraction instead of addition.

  1. Sublw performs the subtraction l-W (literal - W). Does subwf do the subtraction W-f, or f-W? How do you know?
  2. Set up your program so that one subtraction produces a zero result, and a second subtraction produces a negative result. What is the state of the Status register's Z, DC and C bits after each subtraction.
  3. Bonus: Sometimes there is a need to add 16-bit numbers, in which two 8-bit register store the high byte and low byte of the 16-bit word. Adding two low bytes may produce a carry, as might adding two high bytes. Create a program that adds two 16-bit numbers and stores its answer in a 24-bit result register.