|
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:
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:
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:
Pratically
Let's see in detail how an 8-bit sum works: ;Sum (AARG + BARG) -> 8-bit BARG. Thus, adding 33h and 22h, the result is 55h, which is less than FFh and therefore entirely containable in the byte.
The Carry, indicating the carry over of the sum, becomes a key element for carrying out operations that employ more than 8 bits. FFh +FFh = 1FEh then, adding: ; 8-bit sum (AARG + BARG).
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). 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:
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) 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:
So, if we have to store the number 1234h :
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:
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:
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 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:
in Little Endian format. The algorithm runs like this:
skpnc ; does not skip next opcode, since C=1 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:
ewf |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
We offer the best and economical solutions, backed by 27+ years of experience and international standards knowledge, echnological changes, and industrial systems.