Mathematics with PICs

 The purpose of the exercise is to learn something about the mathematical possibilities of PIC microcontrollers.

In fact, it often happens that we have to carry out calculations on data that must be processed not only logically, but also mathematically, both for decisions to be made and for presentation on displays or sending to peripherals or host computers.

Microchip has produced various application notes in this regard:

  • A N526 "PIC16C5x/PIC16Cxxx Math Utility Routines"
  • A N617 "Fixed Point routines"

which can be downloaded from the Microchip website. Referring to these documents for further information, let's try to have some ideas on what is possible to do.

Arithmetic: 8-bit opcodes

Baselines, as we have seen, are the most basic family of PICs and this is also reflected in the instruction set which includes only two arithmetic operations:

  • The sum between the W register and a file: addwf
  • The subtraction between the W register and a file: subwf

Since these are processors with an 8-bit data bus, these operations also take place on this width, where the maximum value is 255 (FFh). There are no multiplication or division operators; to perform calculations on larger numbers or other mathematical operations, appropriate algorithms must be implemented. It involves using the instructions in the set and a sufficient number of registers in RAM.

For this purpose, the STATUS register intervenes, which with its flags allows the 8 bit limitation to be overcome. In the case of the sum, the Carry flag and the Zero flag of the STATUS are modified like this:

  • if the result of the sum does not exceed 255, the Carry remains at 0
  • if the result exceeds 255, the Carry goes to 1, thus containing the carry
    And
  • if the result of the sum is different from 0, the Zero flag is at 0
  • if the result of the sum is zero, the flag goes to 1

Pratically

  • The Carry indicates that the sum has a carryover
  • Zero indicates that the result in the byte is 0

Let's see in detail how an 8-bit sum works:

;Sum (AARG + BARG) -> 8-bit BARG.
; The Carry carries any carryover
movf AARG,w ; A to W
addwf BARG,f ; sum A+B in B (B=B+A)
; if there is a carry, the Carry goes to 1

Thus, adding 33h and 22h, the result is 55h, which is less than FFh and therefore entirely containable in the byte.
If, however, we add 33h and CEh, the result is 101h, which cannot be represented in 8 bits, but requires 9.
Consequently, the 8 least significant bits (01h) will be contained in the result register, while the Carry, going to 1, will indicate that the sum has exceeded FFh. So, the result will be presented like this:

 Carry Register
1  01

The Carry, indicating the carry over of the sum, becomes a key element for carrying out operations that employ more than 8 bits.
For those who still have doubts about the result, let's say that the Carry bit is absolutely adequate to contain the carry, given that the sum of two 8-bit numbers at most gives a 9-bit number as a result. Indeed:

 FFh +FFh = 1FEh

then, adding:

; 8-bit sum (AARG + BARG).
; The result is saved in BARG
; The Carry carries any carryover
movlw .255 ; W = FFh
movf AARG ; A = W = FFh
movf BARG,w ; B = W = FFh
movf AARG,w ; W = A = FFh
addwf BARG,f ; sum to B in B -> (B=B+A = FFh+FFh = 1FEh)
; the Carry goes to 1 for the carry 

  Carry  Register
 1  FE

 

The same can be said of subtraction

Be careful, however, that the subwf opcode performs the operation (W-file) and not (W-file) as you might think: 

; 8-bit subtraction (BARG - AARG).
; The result is saved in BARG
; The Carry carries any carryover
movf AARG,w ; A to W
subwf BARG,f ; subtracts from B to B -> B=B-A
; if there is a remainder, the Carry/Borrow goes to 1

 In this case, the Carry becomes the Borrow that brings back the remainder of the subtraction. Consequently, if the subtraction has a remainder or the result is negative, the STATUS flags C and Z will indicate the situation:

 Result  Carry  Zero 
 Positive 1 0
Zero  1  1
Negative 0 0

 

 The use of flags allows the operation to be extended to more bits, and as well as managing signed numbers.

The Baselines do not have the addition and subtraction opcodes with "literal" values, addlw and sublw , which are present in the other instruction sets. This requires that you have to resort to sets of instructions, for example with a macro:

; Sottrae W dal valore lit (sublw)
; Si utilizza una locazione temporanea
mSUBLW MACRO lit, value
movlw lit ; W= lit
movwf temp ; temp = W = lit
movlw value ; W = value
subwf temp,w ; W = lit - W
ENDM

For the sake of completeness, it should be added that the addition and subtraction operations also act on  the DC (Digit Carry) bit of the STATUS, but this flag is used almost exclusively in 4-bit arithmetic, with numbers encoded in BCD or in binary-BCD conversions, which we will see later.

A further important note concerns the operations of addition and subtraction of the Baselines: for these PICs these are actions that do not take into account the Carry, in the sense that this flag is modified by the result of the operation, but does not become part of the operation itself. So, technically, these are Carry-free trades.

It is necessary to specify this because other families of PICs perform addition and subtraction taking into account the present Carry.

So, for Baselines:

addwf -> (file+W) with the Carry as the ninth bit of the

result For Midrange and above, the same opcode renders:

addwf -> (file+W+C) with the Carry as the ninth bit of the result

And so it is with subtraction, where the Carry becomes Borrow.

This feature, in Baselines, allows you to avoid having to adjust the Carry, zeroing it, when it is an 8-bit sum, but, on the other hand, it requires that it be adjusted correctly when we perform operations on multiple bytes.

 16-bit arithmetic

To achieve adequate accuracy, many operations must process at least 16-bit numbers (maximum content 65535 decimal or FFFFh). Since the capacity of the data bus is 8 bits, it is not possible to perform these operations in a single action, but it is necessary to take advantage of the available instructions, creating appropriate algorithms. And, since, in any case, the registers are 8-bit, it will take more than one to preserve operands and result.

For example, if we want to deal on 16-bit numbers, we will need to use registers in pairs:

UDATA ;  variables for 16-bit calculations

AL res 1 ;16-bit A register

AH res 1

BL res 1 ;16-bit B register

BH res 1

where xL is the least significant byte and xH is the largest byte (little endian arrangement).

In defining these elements, a problem arises, which English speakers call endianness, namely that of the sequence of values in bytes. In practice, we have two options:

variable

variable+1

way

High Byte

Low Byte

Big Endian

Low Byte

High Byte

Little Endian

 

So, if we have to store the number 1234h :

variable

variable+1

way

12

34

Big Endian

34

12

Little Endian

 

The big endian mode has the advantage that it can be read more easily in listings and during debugging, while the little endian mode allows better dynamics for numbers of varying sizes. To explain, if we use the big endian mode and the variable requires more bytes, it also requires the bytes to change position.

For example:

variable

variable+1

variable+2 hundreds

Dozens

unit

--

12

34

--

hundreds

Dozens

unit

12

34

56

 

On the other hand, an increase in the little endian  mode allows the bytes to always maintain the same relationship with their position in memory, making it easier to operate:

variable

variable+1

variable+2

unit

Dozens

--

34

12

--

unit

Dozens

hundreds

56

34

12

While both modes are valid, little endian, for the most dynamic possibilities, is often the preferred one, and Microchip also uses this approach.

Sum at 16 bits and above

To get more definition, it is often necessary to resort to numbers larger than those that can be contained in 8 bits. Numbers on 16 bits are then used, a form referred to as "double precision".

Based on what we have said, the algorithm for realizing a 16-bit sum is a simple consequence:

; Add 16-bit A and B.
; The result is saved in B
; The Carry carries the possible movf carry AL,w ; LSB of a in W
addwf BL,f ; sum to the LSB of b in b
; if there is a carry, the Carry goes to 1
skpnc ; skip next opcode if C=0 incf BH,f ; if C=1 increases MSB by b
movf AH,w ; MSB of a in W
addwf BH,f ; sum to the MSB of b in b
; the Carry contains any carryover

The need to adjust the MSB according to the Carry depends on what we said above, i.e. for Baselines the Carry does not become part of the sum, but only of the result.

Suppose we add a = 0033h and b = 00FFh; We:

  • a = 33h a+1 = 00h
  • b = FFh b+1 = 00h

in Little Endian format. The algorithm runs like this:

movf

AL,w

; W = 33h

addwf

BL,f

; BL = FFh + 33h = 32h with carryover 1 to Carry

skpnc ; does not skip next opcode, since C=1
incf BH,f ; BH = 00h + 1 = 01h

movf AH,w ; W = 00

addwf BH,f ; BH = 01h + 00 = 01h

However, when creating a mathematical algorithm, it is necessary to exhaustively verify its correctness. Let's add FFFFh and FFFFh: 

movf

addwf

skpnc

AL,w BL,f

; W = FFh

; BL = FFh + FFh = FEh with carryover 1 to Carry

; it doesn't skip next opcode, since C=1

incf

BH,f

; BH = FFh + 1 = 00h with the carryover in C=1

; but the Carry does not become part of the following

sum... movf   AH,w ; W = FFh

addwf BH,f       ; BH = 00h + FFh = FFh without carryover

; therefore:

; FFFFh + FFFh = 1FFFEh

; result in BL = FEh and BH =FFh (little endian)

; but without the carryover 1 in the Carry

ewf

favicon bacd

+(39) 347 051 5328

Italy - Kazakhstan

09.00am to 18.00pm

About

We offer the best and economical solutions, backed by 27+ years of experience and international standards knowledge, echnological changes, and industrial systems.

Marketing Materials

Spring Renovation
Industry
US Gas Company
Construct
Plus Project
Vam Drilling Service
X Project
X Project
Cabrrus Training

Marketing Materials1

Spring Renovation
Industry
US Gas Company
Construct
Plus Project
Vam Drilling Service
ultrasonic sensor
ultrasonic sensor
Cabrrus Training