реклама на сайте
подробности

 
 
> Вычисления на ATmega88
koluna
сообщение Dec 2 2008, 14:00
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Здравствуйте!

Использую WinAVR, ATmega88, сигнал синхронизации - внтутренняя RC-цепь (частота 8 МГц).
Необходимо как можно быстрее вычислить значение следующего выражения:

C = Y * C' / 255.
Причём:
C, Y, C' - unsigned char, т. е., действительные числа мне не нужны...

В данный момент вычисления производятся приблизительно за 92 мкс (в программе три выражения подряд).

Можно, конечно, кварц поставить на большую частоту, но хотелось бы пока без него smile.gif

Фрагмент программы:

Код
...
OCR0A = n_red * dmx[0] / 255;
OCR0B = n_green * dmx[0]  / 255;
OCR2B = n_blue * dmx[0] / 255;
...



Спасибо заранее!


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Арк К
сообщение Dec 2 2008, 14:16
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 45
Регистрация: 8-05-08
Пользователь №: 37 363



А надо делить именно на 255? не на 256?
тогда было бы нужно просто выкинуть младший байт
Критичные ко времени места лучше делать на ассемблере.
Go to the top of the page
 
+Quote Post
koluna
сообщение Dec 3 2008, 08:26
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Цитата(Арк К @ Dec 2 2008, 18:16) *
А надо делить именно на 255? не на 256?
тогда было бы нужно просто выкинуть младший байт
Критичные ко времени места лучше делать на ассемблере.


Понятно, что на ассемблере быстрее будет работать...
Но я не знаю как сопрячь WinAVR C и ассемблер sad.gif

Цитата(_Pasha @ Dec 2 2008, 18:24) *
Используйте предварительно посчитанные значения K=M*dmx[0]/255
где М выбирается таким, чтобы получалось то, что делается быстрее, т.е. умножение на К и взятие старшего байта произведения.
асмовый текст, раз уж заговорили про скорость
Код
  lds r24,K
  lds r25,n_red
  mul r24,r25
  out OCR0A,r1
  lds r25,n_green
  mul r24,r25
  out OCR0A,r1
  lds r25,n_blue
  sts OCR2A,r1

Надеюсь, принцип понятен.


К сожалению принцип не понятен пока.
Сколько нужно памяти для предварительно посчитанных значений?

Цитата(_Pasha @ Dec 2 2008, 19:20) *
Я обратил внимание на то, что эта часть dmx[0] / 255; должна быть вычислена один раз и больше не участвовать в окончательных выражениях. Таблицей, конечно, не получится
ЗЫ - наверное, автору все-таки нужно сразу делить на 256, потому что разница в 3 промилле, наверняка, не важна.


f = dmx[0] / 255 делается действительно 1 раз.
Я вынес эту операцию в другое место.
Теперь делаю только С = C' * f.
Время выполнения сократилось приблизительно на 10 мкс (кстати, я ещё кварц на 20 МГц поставил).
Но хотелось бы ещё побыстрее...


Цитата(VDG @ Dec 3 2008, 02:02) *
Человек скорее всего управляет RGB-светодиодом, а деление на 255 - это соответственно "нормализация в восьмибитное число" после умножения на коэффициент яркости. В таком случае, деление на 255 - ошибка. На 256 надо делить, или как выше сказали - взять HIBYTE.


Ими и управляю. Поясню.

Регулирую яркость 8-битным ШИМом микроконтроллера.
Имеем 4 внешних контролла, от которых зависит результирующий цвет луча и его интенсивность.

1 - Общая световая интенсивность dmx[0].
2 - Интенсивность красного n_red.
3 - Интенсивность зелёного n_green.
4 - Интенсивность синего n_blue.

Т. е., моя задача - вычислить значение 8-битного регистра сравнения OCR микроконтроллера, которое зависит от dmx[0] и n_red/n_green/n_blue.

Придумал управлять так:
Код
OCR0A = n_red * dmx[0] / 255;
OCR0B = n_green * dmx[0]  / 255;
OCR2B = n_blue * dmx[0] / 255;


Но подвело меня деление...

Почему надо делить на 256?
Ясное дело, это сдвиг вправо на 8 - выполняется молниеносно, но почему 256?
Т. е., просто согласиться с появляющейся ошибкой?

Сообщение отредактировал n_bogoyavlensky - Dec 3 2008, 08:26


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 3 2008, 08:55
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(n_bogoyavlensky @ Dec 3 2008, 12:26) *
Т. е., просто согласиться с появляющейся ошибкой?

Я ж говорю 256/255 = 1.0039 Точнее - 4 промилле.
Цитата
Но я не знаю как сопрячь WinAVR C и ассемблер

Сишка:
Код
uint8_t n_red,n_green,n_blue;
uint8_t precomputed;
extern void fast_out(void);

Добавляете в проект файл fast_out.S
Код
#include <avr/io.h>
.extern n_red,n_blue,n_green
.extern precomputed

fast_out:
  lds r24,precomputed
  lds r25,n_red
  mul r24,r25
  out OCR0A,r1
  lds r25,n_green
  mul r24,r25
  out OCR0B,r1
  lds r25,n_blue
  sts OCR2A,r1
  ret
// put the global declaration to export function name

.global fast_out


Уже в таком виде должно собраться.
В данном примере precomputed - это Ваше С'
Но, скорее всего, Вам придется эту часть, с предварительными вычислениями тоже в асм внести.
Успехов!

В догонку.
Деление на 255 в данном случае можно заменить делением на 256 и учетом одного исключения:
Код
if (c !=255) a = (b*c)/256; else a=b;

Просьба не воспринимать это как сишный текст smile.gif
Go to the top of the page
 
+Quote Post
koluna
сообщение Dec 3 2008, 09:46
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Цитата
В догонку.
Деление на 255 в данном случае можно заменить делением на 256 и учетом одного исключения:
Код
if (c !=255) a = (b*c)/256; else a=b;

Просьба не воспринимать это как сишный текст smile.gif


И как паскалевский, и как ассемблерный... ясен перец smile.gif

За быстрое деление на 255 - всем спасибо.
Работает. Быстро работает smile.gif

Сообщение отредактировал n_bogoyavlensky - Dec 3 2008, 09:47


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- n_bogoyavlensky   Вычисления на ATmega88   Dec 2 2008, 14:00
- - Непомнящий Евгений   а если поделить на 256? Компилер должен превратить...   Dec 2 2008, 14:12
|- - Непомнящий Евгений   Цитата(Арк К @ Dec 2 2008, 17:16) Критичн...   Dec 2 2008, 14:24
- - _Pasha   Цитата(n_bogoyavlensky @ Dec 2 2008, 18:0...   Dec 2 2008, 14:24
|- - Непомнящий Евгений   Цитата(_Pasha @ Dec 2 2008, 17:24) Исполь...   Dec 2 2008, 15:14
|- - _Pasha   Цитата(Непомнящий Евгений @ Dec 2 2008, 19...   Dec 2 2008, 15:20
|- - =GM=   Цитата(Непомнящий Евгений @ Dec 2 2008, 15...   Dec 2 2008, 16:53
|- - Непомнящий Евгений   Цитата(=GM= @ Dec 2 2008, 19:53) Вот здес...   Dec 3 2008, 05:26
|- - =GM=   Цитата(Непомнящий Евгений @ Dec 3 2008, 05...   Dec 3 2008, 11:00
- - =GM=   Цитата(n_bogoyavlensky @ Dec 2 2008, 14:0...   Dec 2 2008, 14:52
|- - Непомнящий Евгений   Цитата(=GM= @ Dec 2 2008, 17:52) C=(Y*C1*...   Dec 2 2008, 15:00
|- - =GM=   Цитата(Непомнящий Евгений @ Dec 2 2008, 15...   Dec 2 2008, 15:05
- - LordVader   Вот что нагуглилось: http://www.sharpthinking.net/...   Dec 2 2008, 16:48
- - VDG   Человек скорее всего управляет RGB-светодиодом, а ...   Dec 2 2008, 22:02
- - n_bogoyavlensky   Вот ещё одна задача. Как аналогичным образом целоч...   Dec 12 2008, 20:39
|- - Александр Куличок   Цитата(n_bogoyavlensky @ Dec 12 2008, 22...   Dec 12 2008, 23:29
|- - n_bogoyavlensky   ЦитатаДля диапазона A=[0..255): (unsigned char)(...   Dec 13 2008, 11:33
|- - singlskv   Цитата(n_bogoyavlensky @ Dec 13 2008, 14...   Dec 13 2008, 12:06
|- - n_bogoyavlensky   Цитата(singlskv @ Dec 13 2008, 16:06) Име...   Dec 13 2008, 12:16
|- - xemul   Цитата(n_bogoyavlensky @ Dec 13 2008, 15...   Dec 13 2008, 12:56
||- - n_bogoyavlensky   Цитата(xemul @ Dec 13 2008, 16:56) x/10 ~...   Dec 13 2008, 18:34
||- - xemul   Цитата(n_bogoyavlensky @ Dec 13 2008, 21...   Dec 13 2008, 20:41
||- - singlskv   Цитата(xemul @ Dec 13 2008, 23:41) Спасиб...   Dec 13 2008, 21:33
||- - xemul   Цитата(singlskv @ Dec 14 2008, 00:33) на ...   Dec 13 2008, 22:41
||- - Александр Куличок   Цитата(singlskv @ Dec 13 2008, 23:33) -ит...   Dec 13 2008, 23:35
|- - SSerge   Цитата(n_bogoyavlensky @ Dec 13 2008, 18...   Dec 13 2008, 13:00
- - singlskv   Дык все точно так же, умножте на 26(~256/10) или н...   Dec 12 2008, 21:13
- - ae_   x/10 = x*(1/10) = x*(205/2048) = (x*205)>>11...   Dec 13 2008, 12:56
- - ae_   Так, что бы во всём диапазоне 0...255 / 10 выполня...   Dec 14 2008, 11:51
- - n_bogoyavlensky   Кстати, а что за метод в 11 посте? Там логика друг...   Dec 15 2008, 09:59
- - SSerge   Цитата(n_bogoyavlensky @ Dec 15 2008, 15...   Dec 15 2008, 11:33


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th June 2025 - 06:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01414 секунд с 7
ELECTRONIX ©2004-2016