When a microcontroller is used for a control application, usually, input information is processed (calculated using input information), and output as a controlled variable determined from input information.
Computation (calculation) processing required for a microcontroller to perform a control operation substantially varies depending on the application, from relatively easy to extremely complicated. If complicated calculations are processed only within a given time, the microcontroller is required an extremely high calculation capability. Increasing the calculation capability only to cope with complicated calculation is not practical. As a practical method, therefore, table referencing is used.
[Concept of table referencing]
Table referencing is calculating the result of given input (x) in advance and preparing the results in a table. The calculation itself is cumbersome because it must be executed within a certain range of input values, but can be done relatively easily by using a PC or other computer.
When creating a table, its size is important. If the output pattern is repeated as in the above example, it is not necessary to create a table that covers the entire range of input values; creating a table only in a range that represents the repeated part is enough. The table then should be referenced by using a remainder and quotient resulting from dividing an input value by a period of repetition and other parameters.
[Using table referencing]
In table referencing, an address difference from the top address of the table based on the input data (this is called an offset value) is calculated. If the necessary data has a byte width, the input data can be used as an offset value as is. If the data is a 16-bit width, the input data is doubled to make an offset value. If this offset value is added to the top address of the table, the address of the memory where the value that is needed is stored can be obtained. By reading the memory from that address, the calculation result that is needed can be obtained.
|The 75X series 4-bit microcontroller has instructions dedicated to table referencing (such as MOVT XA, @PCDE and MOVT XA, @PCXA) but the 78K0 does not have instructions called as table referencing instructions. Then isn't the 78K0 capable of table referencing? Actually, it is not necessary for the 78K0 to use dedicated table referencing instructions because both ROM and RAM are located in the same memory space. Based index addressing instructions are useful for table referencing. These instructions, including MOV A, [HL+B] and MOV A, [HL+C], set the top address of the table to the HL register and an offset value to the B or C register, so that the offset value is added to the top address and the value of the memory at that address is read to the A register.|
[Notes on table referencing]
When creating a table, the accuracy of calculation and the number of data to be prepared pose a problem. If the accuracy is improved too much, the table becomes too large, and occupies too much memory space. The table size can be reduced by not processing everything with table referencing and by implementing interpolation processing in the end. For details, refer to the description of interpolation processing below.
Interpolation involves obtaining rough results through table referencing and details through simple proportional calculation. It can substantially decrease table size since it will suffice for data to be prepared at large intervals.
To decrease the data quantity 1/16 of what is needed, for example, only data whose lower 4 bits are 0000 are prepared in the table. Interpolation is done by performing the following processing.
|The table is referenced using an offset value that is input data decreased 1/16 (4 bits shifted to the right). In the above figure, data at point A can be obtained.|
|Next, the difference between this data and the next data on the table (data B in the above figure) is calculated.|
|This difference is divided by 16 and the result is multiplied by the lower 4 bits of the input data. Then an increment from point A can be obtained. (If calculation is carried out in this order as is, a rounding error occurs. Therefore, the order of calculation must be changed and multiplication must be executed first.)|
|The above increment is added to the value of point A obtained from the table.|
The above processing can surely be executed in a relatively short time because, basically, only addition, multiplication, and shift operations are needed. Because the deifference calculated in includes a sign, however, the subsequent calculation is cumbersome. For the actual processing, therefore, it is easier to obtain a weighted mean. These processings are equivalent in that the expression can be transformed as follows, where m is the number of divisions and n is the numeric value indicated by the lower bits of the input data.
As is evident from this last expression, the result is the same if subtraction of the lower bits of the input data from the number of division multiplied by data A obtained from table is added to the lower bits of the input data multiplied by the next data on the table, B, which is divided by the number of divisions.
In the above example, the next data on the table (data B) is added only by the offset indicated by the lower 4 bits, and the data of part A is added to the rest and then divided by 16.
As a program example, a case where the data of a table is compressed to 1/32 is given below. Usually, data does not have to be compressed this much, and may only have to be compressed to 1/2. If data is compressed to 1/2, interpolation processing can be performed with a simple average value of the data before and after given data. As a result, the program can be simplified and the processing speed increases. The total memory capacity used can be much lower than that for mere table referencing. However, the quantity of the data of the table increases, and therefore, an example of 1/2 compression is omitted.
Error of interpolation |
Let's consider the error involved in interpolation processing. In this example, calculation is performed in a range of sin0 to sin/2 at a resolution of 10 bits (division by 1024) and the result is up to 1023 (= sin/2). Detailed calculation results are omitted, but the maximum error is:
0.005 when interpolation of 2 bits is performed with division by 256
0.019 when interpolation of 3 bits is performed with division by 128
0.077 when interpolation of 4 bits is performed with division by 64
0.31 when interpolation of 5 bits is performed with division by 32
In all the cases, the error is sufficiently small (0.5 bits or less) at a 10-bit resolution. When a table of 10 bits is used, a capacity of 2048 bytes is necessary. However, sufficient accuracy can be obtained even if the capacity is decreased to 64 bytes.
An example of a program that calculates sin0 to sin/2 up to an accuracy of 10 bits is given below. As an input value, a range of 0 to /2 is divided by 1024 and indicated by 10 bits (0 to 1023). If the part that calculates the offset value from an input parameter and is ANDed with #00111110b is changed to #01111110b, and if the table is expanded, up to 11 bits (0 to 2047) can be supported and values from sin0 to sin can be obtained. In the following program, a 16-bit variable (CONVDATA) is used to store the input parameter and result, and an 8-bit variable (WORK1) following it is used for work. These variables are allocated to the short direct addressing area.
WORK00 DSEG SADDRP CONVDATA: DS 2 ;Return area of input parameter and result WORK01 DSEG SADDR WORK1: DS 1
The program is a subroutine which consists of four major parts (of which three are the main bodies of the program and one is an internal subroutine)
(1) The first part is to reference a table from an input parameter. In the table, data compressed to 1/32 is stored. To obtain the offset value of the table, therefore, the input data is compressed to 1/32 and doubled since the data length is 10 bits and thus 2 bytes are necessary. In other words, the offset value for table referencing can be obtained if the input parameter is divided by 16. In this example, only the lower 10 bits of the input parameter are meaningful. Therefore, the input parameter is compressed to 1/16 by rotating it 4 bits to the right with the digit rotate instruction (ROR4 [HL]) of the 78K0. The higher 4 bits of the input parameter are ignored. By adding the top address of the table data addresses table to the offset value (a value of 8 bits or less) obtained in this way, the table data addresses can be obtained. If the table is located from a lower address starting from 00, such as 200H, it is not necessary to add the top address to the offset value, and processing can be performed by merely substituting the offset address into the lower address (in this example, the table data address is obtained by adding the first address to the offset value). This part is the same as table referencing except for the 1/16 compression processing.
CONVSUB: PUSH AX PUSH HL MOVW AX,CONVDATA ;Higher byte of input data to A, lower byte to X MOVW HL,#CONVDATA ROR4 [HL] ;Lower 4 bits of A and [HL] are divided by 16 MOV A,[HL] AND A,#00111110b ;Obtains an offset value ADD A,#LOW TABLE ;Calculates the lower address MOV L,A MOV A,#0 ADDC A,#HIGH TABLE ;Calculates the higher address MOV H,A ;HL indicates the target table MOV A,[HL] ;Reads the lower byte MOV CONVDATA,A ;Set as the initial value of the lower byte MOV A,[HL+1] MOV CONVDATA+1,A ;Sets the higher byte
(2) The following part of the program is calculation for interpolation. In this part, the reference value and the next value on the table are totaled, using weights to calculate a weighted mean. If interpolation is not necessary, the processing is complete because the result of referencing the table has already been set as an output parameter. To perform interpolation, the next data is repeatedly added as many times as the number of interpolation data (actually, the next data is multiplied by the interpolation data) and the table data is repeatedly added as many times as 32 minus the number of interpolation data. The actual calculation is processed by a subroutine. In this example, parameters necessary for calculation are prepared and the subroutine is called as many times as needed. Because calculation is 16 bits x 8 bits + 16 bits, the necessary parameters are pushed onto the stack to simplify the processing, and the HL register is used as an index for the total data. The result of totaling falls within 16 bits, but an additional byte is used for work to provide common processing. This 1 byte for work (WORK1) is meaningless as data, but is initialized to 0.
MOV A,X AND A,#00011111b ;Obtains data for interpolation BZ $EXITS ;Finishes if interpolation is unnecessary ; ; Preparation for interpolation ; (weighted mean) (Data for calculation is pushed onto stack) ; MOV WORK1,#0 ;Initializes the higher data MOV X,A ;Sets interpolation data to the X register MOV A,[HL+3] ;Sets the higher byte of the next data on the table PUSH AX ;Saves calculated data MOV A,[HL+2] ;Sets the lower byte of the next data on the table PUSH AX ;Saves calculated data MOV A,#31 SUB A,X ;Calculates the remainder of 32 MOV X,A MOV A,[HL+1] ;Sets the higher byte of reference data on the table PUSH AX ;Saves calculated data MOV A,[HL] ;Sets the lower byte of reference data on the table MOVW HL,#CONVDATA ;Sets pointer ; ; Totaling of the reference data on the table ; CALL !SEKIWA ;Totals the lower data POP AX INCW HL CALL !SEKIWA ;Totals the higher data ; ; Totaling of the next data on the table ; POP AX DECW HL CALL !SEKIWA POP AX INCW HL CALL !SEKIWA
(3) The result of totaling is divided by 32 and the final result is calculated. The result thus far is the same as multiplication of 10 bits and 5 bits, and the result is 16 bits or less. To round the result instead of truncating it, a value equivalent to 0.5 of the result of totaling is added and then 1/32 processing is performed. This processing uses the fact that HL indicates CONVDATA+1 as a result of the processing so far. To compress the data to 1/32, it is rotated 4 bits to the left with the bytes shifted, so that the data is compressed to 1/16 and then 1/2 processing is performed.
MOV A,CONVDATA ;Loads the lower bits of the result ADD A,#00010000b ;Adds 0.5 to round up BNC $NEXT INC CONVDATA+1 ;Carries over to the higher NEXT: AND A,#11100000b ;Masks the unused bits ROR A,1 ;Result to the lower 4 bits ROR A,1 ;A=00XXX000、CY=0 ROR A,1 ;A=000XXX00、CY=0 ROR A,1 ;A=0000XXX0、CY=0 ROL4 [HL] ;Result is divided by 16 RORC A,1 ;Result is further divided by 2 XCH A,[HL] ;Higher 3 bits and lower bits are exchanged RORC A,1 ;Lower bits are also divided by 2 MOV CONVDATA,A ;Result is saved EXITS: POP HL POP AX RET
(4) Shown below is an internal subroutine that actually performs a product-sum operation for totaling. The multiplier and multiplicand are set to the A and X registers, and the subroutine is called with the data pointed to be totaled by HL. The result of multiplying the contents of the A and X registers is totaled to [HL] and [HL+1].
; 8-bit product-sum operation ; (Result should fit in 16 bits) ; SEKIWA: MULU X ;Calculation of weight XCH A,X ;Exchanges the higher and lower results ADD A,[HL] ;Totals the lower MOV [HL],A ;Saves the result MOV A,X ;Brings the higher of the result. ADDC A,[HL+1] ;Calculation to carry over to the higher MOV [HL+1],A ;Saves the higher byte RET
(5) This is a table corresponding to 0(0) to 1024 (=/2). This table does not have 1024 data items but data compressed to 1/32 (data of every 32 data items taken out).
To expand the target range to 0(0) to 2048(=).
TAREA CSEG AT 200H ; ; Table of values when sin0 to sin/2 are divided by 32 then multiplied by 1023 TABLE: DW 0, 50, 100, 150 DW 200, 249, 297, 345 DW 392, 437, 482, 526 DW 568, 609, 649, 687 DW 723, 758, 791, 822 DW 851, 877, 902, 925 DW 945, 963, 949, 992 DW 1003, 1012, 1018, 1022 DW 1023
Supporting 2048 (=) or more
or more cannot be supported using a table or masking an offset value. This is because it is necessary to review the range of the result value (how to express negative values).
This program can handle 0 to 1023 as a range of the result values. Therefore, sin/2 to sin 3 /2 must be expressed as 0 to 1023. Specifically, 1(=sin/2) is expressed as 1023, 0(=sin), as 512, and -1(=sin3/2), as 1.
Because this program cannot support expressing a negative value as a 2's complement, external processing that signs data (by subtracting it from 0) must be added.