[an error occurred while processing this directive]
Господа, как известно, в Париже - не смущай, в Сети все на "ты" по умолчанию - до особой просьбы, разумеется :))
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено =AVR= 07 июня 2006 г. 13:35
В ответ на: Господин =AVR=, еще вопросик по матетике в подолжение вчерашнего отправлено vanessa 07 июня 2006 г. 11:43

Ты верно начал рассуждать, но пришел к неверным выводам. Смысл состоит в том, чтобы совсем избавиться от арифметического деления, заменив его делением на степень двойки - 2^N, т.е. сдвигом вправо на N бит. Для этого нужно пересчитать коэффициент из "системы счисления" по основанию 10000 в "систему счисления" по основанию 65536:

0.9876 = 9876/10000, тогда числитель будет 0.9876*65536 ~~ 64723

Дальше - пересчет 12..985 в 0..799. Это уже не Y=kX, а Y=kX+b. Сначала убери сдвиг - вычти 12, тем самым приведя к 0..973, а затем вычисли k:

k=799/985=0.81117, 0.81117*65536~~53161, значит, k=53161/65536.
Проверяем: 985*53161=52363585=0x031F0141. Берем MSW и получаем 0x031f=799, что и требовалось.

С отрицательными входными значениями подход точно такой же, то есть kX+b, но с приведением к 0 самого отрицательного значения и добавлением смещения к результату масштабирования. Вот пример:

Есть данные АЦП в диапазоне от -2000 до +1500, на выходе требуется показать от 4.010 до 9.180. Выбрасываем точку (запомнив, куда ее потом поставить), получаем выход 4010..9180. Приводим к 0 вход, получаем 0..3500, приводим к 0 выход (запомнив 4010 в роли нуля как "a"), получаем 0..5170. Дальше - почти так же, как и прежде:

k=5170/3500=1.47714, так как k > 1 - нагло делим его на 2, чтобы влезть в размер int (учтем это позже), получаем K=0.73857. Вычисляем числитель - 0.73857*65536=48403. Теперь проверяем, не забыв предварительно умножить вход на 2 (учитываем проведенное выше деление k на 2):

(3500*2)*48403=338821000=0x1431FF88. Берем MSW = 0x1431=5169, прибавляем запомненное "a"=4010, получаем 9179. Ставим на место точку, получаем искомое pH = 9.179.

Здесь наглядно видна ошибка порядка 0.01%, возникшая из-за ограниченной разрядности вычислений и применения отбрасывания LSW вместо округления. Если это не устраивает, тогда придется все делать в long, но при разрядности АЦП меньше 16 это просто бессмысленно.

Я намеренно не стал расписывать процесс в общем виде, а привел численные примеры. Разумеется, применить плавучку будет гораздо комфортнее, но когда поджимают ресурсы МК, это может и не пролезть. На практике работа с плавучкой в десятки раз медленнее, чем с целыми, а код в те же десятки раз толще. Для работы с целыми у меня написаны богатые ассемблерные библиотеки, и работа с ними для меня ничем не менее комфортна, чем для других работа с плавучкой на С, а результат - высвобождение максимума ресурсов МК под остальные задачки. Но это, как говорится, дело вкуса. И квалификации :))

Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание

E-mail: info@telesys.ru