Отключаемые счетчики электроэнергии на пульте. Все с документами пломбами, гарантией и без посредников!

Вычисление функций по таблицам

Вычисление функций по таблицам

Использование табличной конвертации часто является самым рациональным способом вычисления Функций. При этом удается избежать сложных расчетов и многократно увеличить скорость выполнения кода. Платой за простоту является относительно большой расход памяти программ, но у AVR, как правило, на это можно не обращать внимание.

Рис.1 Табличные значения функции

Для реализации данного метода необходимо предварительно определить значение функции в ряде точек на заданном интервале изменения аргумента (построить функцию по точкам). Данные сводятся в таблицу и сохраняются в неизменном виде во FLASH-памяти программ или в энергонезависимой памяти иного типа. Теперь отыскание значений функции Y = F(X) будет сводиться к простому выбору из таблицы, заранее посчитанных, Yi для соответствующих Xi. Сам интервал разбивается на n участков. Расстояние между двумя соседними точками d = Xi+1 – Xi будет шагом таблицы. Число n всегда надо выбирать кратным целой степени двойки, а d, если это возможно, одинаковым в пределах всей таблицы (таблица с фиксированным шагом). На рис.1 показана функция Y = F(X), а т.A(Xi,Yi) и т.B(Xi+1,Yi+1) это два её соседних табличных значения. Для того чтобы определить функцию в произвольной точке, например в т.С(X,Y), прибегают к линейной интерполяции, замещая участок функции прямой. В нашем случае это прямая AB. Искомая т.С отобразится на ней как т.С’. В расчеты будет внесена некоторая абсолютная погрешность Δ = |F(C) – F(C’)|, которая не превзойдет максимально возможного значения Δmax = |F(B) – F(A)| если функция не поменяет свой знака на этом участке.

Уравнение прямой проведенной через две точки имеет вид:

(X – Xi)/(Xi+1 – Xi) =  (Y – Yi)/(Yi+1 – Yi).  (1)

Если учесть, что в (1) d = Xi+1 – Xi, то для текущих координат получим окончательную формулу:              

Y = Yi + (X – Xi)* (Yi+1 – Yi)/d.  (2)

Таким образом, будем иметь следующий порядок расчета. Сначала, делением заданного X на шаг таблицы d, определяем в каком месте таблицы находится искомое значение функции Y = F(X). Частное от этого деления даст индекс i аргумента Xi в таблице, по которому и определяется Yi. Если остаток от деления нулевой, то Y совпадает с Yi и расчет заканчивается. В противном случае из таблицы нужно взять следующее значение Yi+1, а искомое Y определить в соответствии с (2). Ниже приведена подпрограмма, основанная на этом алгоритме. Она предназначена для совместного использования с таблицами функций sinX и arcsinX (приведены ниже). Скорость вычисления в самом худшем случае составляет всего 46(!) машинных циклов.

; Подпрограмма вычисления функций c использованием ; табличной конвертации ; R17:R16 – входное значение аргумента в формате (8.8), ; лежащее в диапазоне 0…128.0 ; на n = 128 участков 2-байтовых значений функции ; R21:R20 – значение функции на выходе из подпрограммы ; R0,R1,R18,R19,R30,R31 – вспомогательные регистры tbl_func: dec R17 ;уменьшаем на 1 аргумент поскольку нулевое clr R18 ;значение функции в таблице не хранится ldi ZL,low(2*tabl) ;заносим в указатель ZH:ZL адрес ldi ZH,high(2*tabl) ;начала таблицы lsl R17 ;удваиваем значение аргумента, чтобы учесть rol R18 ;2-байтовый формат данных в таблице add ZL,R17 ;добавляем к указателю смещение adc ZH,R18 lpm R17,Z+ ;извлекаем из таблицы значение R18:R17 = Yi lpm R18,Z+ tst R16 ;если остаток R16=0, то в R17:R16 уже brne PC+2 ;находится нужное значение ret ;и поэтому выходим из подпрограммы lpm R19,Z+ ;в ином случае извлекаем из таблицы lpm R20,Z ;очередное значение R20:R19 = Yi+1 sub R19,R17 ;находим разность R20:R19 = Yi+1 – Yi sbc R20,R18 mul R20,R16 ;находим смещение относительно точки Yi movw R20,R0 ;R21:R20:R19 = (Yi+1 – Yi)*(X – Xi)/d в mul R19,R16 mov R19,R0 clr R16 add R20,R1 adc R21,R16 sec ;если R19 ≥ 1/2, то устанавливаем флаг sbrs R19,7 ;переноса для коррекции результата clc adc R17,R20 ;находим окончательно значение функции adc R18,R21 ;R21:R20 = Y = Yi + (X – Xi)*(Yi+1 – Yi)/d ret ; Таблица значений функции sinX ; диапазон изменения аргумента 0…900, шаг d = (90/128)0 ; значения функции хранятся в виде 32768*sinX sin_tabl: .dw 0x0192,0x0324,0x04B6,0x0648,0x07D9,0x096B,0x0AFB,0x0C8C .dw 0x0E1C,0x0FAB,0x113A,0x12C8,0x1455,0x15E2,0x176E,0x18F9 .dw 0x1A83,0x1C0C,0x1D93,0x1F1A,0x209F,0x2224,0x23A7,0x2528 .dw 0x26A8,0x2827,0x29A4,0x2B1F,0x2C99,0x2E11,0x2F87,0x30FC .dw 0x326E,0x33DF,0x354E,0x36BA,0x3825,0x398D,0x3AF3,0x3C57 .dw 0x3DB8,0x3F17,0x4074,0x41CE,0x4326,0x447B,0x45CD,0x471D .dw 0x486A,0x49B4,0x4AFB,0x4C40,0x4D81,0x4EC0,0x4FFB,0x5134 .dw 0x5269,0x539B,0x54CA,0x55F6,0x571E,0x5843,0x5964,0x5A82 .dw 0x5B9D,0x5CB4,0x5DC8,0x5ED7,0x5FE4,0x60EC,0x61F1,0x62F2 .dw 0x63EF,0x64E9,0x65DE,0x66D0,0x67BD,0x68A7,0x698C,0x6A6E .dw 0x6B4B,0x6C24,0x6CF9,0x6DCA,0x6E97,0x6F5F,0x7023,0x70E3 .dw 0x719E,0x7255,0x7308,0x73B6,0x7460,0x7505,0x75A6,0x7642 .dw 0x76D9,0x776C,0x77FB,0x7885,0x790A,0x798A,0x7A06,0x7A7D .dw 0x7AEF,0x7B5D,0x7BC6,0x7C2A,0x7C89,0x7CE4,0x7D3A,0x7D8A .dw 0x7DD6,0x7E1E,0x7E60,0x7E9D,0x7ED6,0x7F0A,0x7F38,0x7F62 .dw 0x7F87,0x7FA7,0x7FC2,0x7FD9,0x7FEA,0x7FF6,0x7FFE,0x8000 ; Таблица значений функции arcsinX ; диапазон изменения аргумента 0…1, шаг d = 1/128 ; значения функции хранятся в виде 32768*arcsinX рад arcsin_tabl: .dw 0x0100,0x0200,0x0300,0x0400,0x0500,0x0601,0x0701,0x0801 .dw 0x0902,0x0A03,0x0B03,0x0C05,0x0D06,0x0E07,0x0F09,0x100B .dw 0x110D,0x120F,0x1312,0x1415,0x1518,0x161C,0x1720,0x1825 .dw 0x1929,0x1A2F,0x1B34,0x1C3A,0x1D41,0x1E48,0x1F50,0x2058 .dw 0x2161,0x226A,0x2374,0x247E,0x2589,0x2695,0x27A1,0x28AE .dw 0x29BC,0x2ACB,0x2BDA,0x2CEB,0x2DFC,0x2F0D,0x3020,0x3134 .dw 0x3249,0x335E,0x3475,0x358C,0x36A5,0x37BF,0x38DA,0x39F6 .dw 0x3B13,0x3C32,0x3D52,0x3E73,0x3F95,0x40B9,0x41DE,0x4305 .dw 0x442E,0x4558,0x4683,0x47B1,0x48E0,0x4A10,0x4B43,0x4C78 .dw 0x4DAE,0x4EE7,0x5022,0x515F,0x529E,0x53E0,0x5524,0x566B .dw 0x57B4,0x5900,0x5A4F,0x5BA1,0x5CF5,0x5E4D,0x5FA9,0x6107 .dw 0x626A,0x63D0,0x653A,0x66A8,0x681A,0x6991,0x6B0D,0x6C8D .dw 0x6E13,0x6F9E,0x712F,0x72C6,0x7463,0x7608,0x77B3,0x7966 .dw 0x7B21,0x7CE6,0x7EB3,0x808B,0x826D,0x845C,0x8657,0x8860 .dw 0x8A79,0x8CA3,0x8EE0,0x9132,0x939C,0x9621,0x98C7,0x9B91 .dw 0x9E89,0xA1B7,0xA52B,0xA8FA,0xAD4B,0xB268,0xB90D,0xC910

Перейти к следующей части:


Категория: Микроконтроллеры
Метки:

Написать коментарий

*
= 5 + 0

Добавить изображение

Последние статьи