What does it do?
The Math program demonstrates literal (constant) and register-based (variable) math 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:
- a zero result of any addition or subtraction will set the Z bit, a non-zero result leaves it cleared;
- an addition overflow (adding two 8-bit numbers to produce a 9 bit result) will set the C bit, effectively making it the 9th bit of the result;
- an addition overflow from the low nybble (the least significant 4 bits) to the high nybble (the most significant 4 bits) in a byte results in the DC flag being set;
- a subtraction operation will set the C bit before subtracting, and borrow from it (if necessary) during the subtraction—1 means no borrow occurred, 0 indicates a borrow took place.
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.
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 "p16f886.inc" ;Include processor definitions __config _CONFIG1, _DEBUG_OFF & _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSCIO __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 end
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
- 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?
- Add two numbers that produce a sum equal to 256. What is the state of the Z, DC and C bits this time?
- 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.
- Sublw performs the subtraction l-W (literal - W). Does subwf do the subtraction W-f, or f-W? How do you know?
- 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.
- 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.