Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Похожие статьи:


Реклама ⓘ

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

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

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Паяльник с регулировкой температуры Мультиметр Mastech MS8268
вверх