|
Вычисления на ATmega88 |
|
|
|
Dec 2 2008, 14:00
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Здравствуйте! Использую WinAVR, ATmega88, сигнал синхронизации - внтутренняя RC-цепь (частота 8 МГц). Необходимо как можно быстрее вычислить значение следующего выражения: C = Y * C' / 255. Причём: C, Y, C' - unsigned char, т. е., действительные числа мне не нужны... В данный момент вычисления производятся приблизительно за 92 мкс (в программе три выражения подряд). Можно, конечно, кварц поставить на большую частоту, но хотелось бы пока без него  Фрагмент программы: Код ... OCR0A = n_red * dmx[0] / 255; OCR0B = n_green * dmx[0] / 255; OCR2B = n_blue * dmx[0] / 255; ... Спасибо заранее!
--------------------
Благодарю заранее!
|
|
|
|
|
 |
Ответов
|
Dec 2 2008, 14:24
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(n_bogoyavlensky @ Dec 2 2008, 18:00)  Код ... OCR0A = n_red * dmx[0] / 255; OCR0B = n_green * dmx[0] / 255; OCR2B = n_blue * dmx[0] / 255; ... Спасибо заранее! Используйте предварительно посчитанные значения 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 Надеюсь, принцип понятен.
|
|
|
|
|
Dec 2 2008, 15:14
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(_Pasha @ Dec 2 2008, 17:24)  Используйте предварительно посчитанные значения K=M*dmx[0]/255 где М выбирается таким, чтобы получалось то, что делается быстрее, т.е. умножение на К и взятие Не могли бы вы пояснить эту мысль? К зависит от двух 1-байтных чисел, объем таблицы получится 65536 байт... Или я вас не так понял? Цитата(=GM= @ Dec 2 2008, 17:52)  C=(Y*C1*257) >> 16;
Или совсем уж убыстрить
С2=Y*C1; C=((C2 << 8)+С2) >> 16; А кстати, нифига  (С2*257) >> 16 =( (С2 <<8) + C2)>>16 = ((C2<<8)>>16) + (C2>>16) = C2>>8 = C2 / 256 ... сдвиг на 16 - это ж деление на 65536, а не на 65535
|
|
|
|
|
Dec 2 2008, 16:53
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Непомнящий Евгений @ Dec 2 2008, 15:14)  (С2*257) >> 16 =( (С2 <<8) + C2)>>16 = ((C2<<8)>>16) + (C2>>16) = C2>>8 = C2 / 256 ... сдвиг на 16 - это ж деление на 65536, а не на 65535  Так и задумывалось, делить на 65536, чтобы был сдвиг на 16 бит, а не деление на 65535. Вот здесь ошибочка у вас ((C2<<8)>>16) + (C2>>16) = C2>>8 +(C2>>16). Округление можно так сделать C=((C2 << 8)+С2+32768) >> 16;
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Dec 3 2008, 05:26
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(=GM= @ Dec 2 2008, 19:53)  Вот здесь ошибочка у вас ((C2<<8)>>16) + (C2>>16) = C2>>8+(C2>>16). С2 = У * С1 У и С1 - unsigned char, т.е. их произведение <=65535. Сдвиг на 16 влево такого числа даст 0. Поэтому (C2>>16) == 0 Цитата Так и задумывалось, делить на 65536, чтобы был сдвиг на 16 бит, а не деление на 65535. Ну просто это получается эквивалентно C2/256. Просто малость замаскировано
|
|
|
|
Сообщений в этой теме
n_bogoyavlensky Вычисления на ATmega88 Dec 2 2008, 14:00 Непомнящий Евгений а если поделить на 256? Компилер должен превратить... Dec 2 2008, 14:12 Арк К А надо делить именно на 255? не на 256?
тогда было... Dec 2 2008, 14:16 Непомнящий Евгений Цитата(Арк К @ Dec 2 2008, 17:16) Критичн... Dec 2 2008, 14:24 n_bogoyavlensky Цитата(Арк К @ Dec 2 2008, 18:16) А надо ... Dec 3 2008, 08:26  _Pasha Цитата(n_bogoyavlensky @ Dec 3 2008, 12:2... Dec 3 2008, 08:55   n_bogoyavlensky ЦитатаВ догонку.
Деление на 255 в данном случае мо... Dec 3 2008, 09:46  _Pasha Цитата(Непомнящий Евгений @ Dec 2 2008, 19... Dec 2 2008, 15:20    =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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|