Главная » Микроконтроллеры
Призовой фонд
на август 2019 г.
1. 1000 руб
Паяльник
2. Тестер компонентов MG328
Паяльник
3. 200 руб.
От пользователей

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

Использование табличной конвертации часто является самым рациональным способом вычисления Функций. При этом удается избежать сложных расчетов и многократно увеличить скорость выполнения кода. Платой за простоту является относительно большой расход памяти программ, но у 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

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

Теги:

Котов Игорь Юрьевич Опубликована: 2012 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (1) | Я собрал (0) | Подписаться

0
Григорий #
А где в исходнике производиться деление на d?
В последнем исходнике, в строке 16 имелось ввиду ";если R19:R18 > R24:R23"?
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

AVR-программатор USB ASP
AVR-программатор USB ASP
Паяльник с регулировкой температуры Мини гравер 125 Ватт
вверх