sherr 0 26 февраля, 2016 Опубликовано 26 февраля, 2016 (изменено) · Жалоба Все по той же матрично-светодидной теме -> Есть 32-битная переменная ,Надо ее преобразовать так (ниже номера бит) Было: 00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,12,21,22,23,24,25,26 ,27,28,29,30,31 Стало: хх,хх, 00,06,11,16,22,27,01,07,12,17,23,28,02,08,13,18,24,29,03,09,14,19,25,30,04,10,15 ,20,26,31 Тактов на все про все не больше 60-70 ... В лоб занимает > 200, табличный вариант оставил на крайний случай. Может есть какой-то хитрый метод ? В принципе задача сводится к пяти преобразованиям типа : ABCDxxxxxxx,,, в A00000B00000C00000D00000... где A-D это биты, с последующим суммированием . ps увы, в системе команд STM32F0 с битовыми операциями не густо и битбандинга нет Изменено 26 февраля, 2016 пользователем sherr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Тактов на все про все не больше 60-70 ... В лоб занимает > 200, табличный вариант оставил на крайний случай. Может есть какой-то хитрый метод ? А почему такое неприятие табличного метода??? Просто быстро и универсально. Я плохо знаю систему команд M0, но думаю займёт тактов 20 примерно. И по памяти можно уложиться в 4 кБ флеша (хотя, если есть МНОГО памяти, можно за счёт неё ещё неск. тактов выиграть наверное). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Вот тут трюки с битами:Swapping individual bits with XOR . Может быть, поможет. Если время будет, попробую применить такой метод к вашей задаче. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Автору: Вот тут чел страдает похожим: http://electronix.ru/forum/index.php?showt...p;#entry1407219 Может поможет? PS: Только что в голову пришёл самый быстрый метод - в зависимости от функционирования GPIO в Вашем МК, этот метод вообще может занимать всего пару тактов :rolleyes: Выделяете 2-а 32-битных порта GPIO. Соединяете вых. линии первого порта с вх. линиями второго в соответствии с таблицей перестановки бит, выводите слово в первый порт, считываете со второго. На ядре M3 этот алгоритм может занимать всего два такта, если GPIO сидит на быстрой шине. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sherr 0 26 февраля, 2016 Опубликовано 26 февраля, 2016 (изменено) · Жалоба PS: Только что в голову пришёл самый быстрый метод - в зависимости от функционирования GPIO в Вашем МК, этот метод вообще может занимать всего пару тактов :rolleyes: Выделяете 2-а 32-битных порта GPIO. Соединяете вых. линии первого порта с вх. линиями второго в соответствии с таблицей перестановки бит, выводите слово в первый порт, считываете со второго. На ядре M3 этот алгоритм может занимать всего два такта, если GPIO сидит на быстрой шине. Гениально ! Да только ног свободных столько нету... А почему такое неприятие табличного метода??? Просто быстро и универсально. Я плохо знаю систему команд M0, но думаю займёт тактов 20 примерно. И по памяти можно уложиться в 4 кБ флеша (хотя, если есть МНОГО памяти, можно за счёт неё ещё неск. тактов выиграть наверное). Там вообще-то минимум 32*6 32-битных слов в таблице - это и в ОЗУ влезет если надо,,,, Изменено 26 февраля, 2016 пользователем sherr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Там вообще-то минимум 32*6 32-битных слов в таблице - это и в ОЗУ влезет если надо,,,, Это как считали? У меня получается 16 32-битных слов. Пример 16-битный легко переделать в 32 бита. Исходное число: A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, C4, D4. Результат: A1, A2, A3, A4, B1, B2, B3, B4, C1, C2, C3, C4, D1, D2, D3, D4. 0. Обнуляем результат. 1. Сдвигаем исходное число вправо на (16 - 4 * (1 + 0)) разрядов и делаем AND с 15. 2. Получаем A1 B1 C1 D1. 3. Используем как индекс в таблице и получаем из таблицы A1, 0, 0, 0, B1, 0, 0, 0, C1, 0, 0, 0, D1, 0, 0, 0. 4. Сдвигаем на 0 вправо и делаем OR с результатом. 5. Сдвигаем исходное число вправо на (16 - 4 * (1 + 1)) разрядов и делаем AND с 15. 6. Получаем A2 B2 C2 D2. 7. Используем как индекс в таблице и получаем из таблицы A2, 0, 0, 0, B2, 0, 0, 0, C2, 0, 0, 0, D2, 0, 0, 0. 8. Сдвигаем на 1 вправо и делаем OR с результатом. 9. Повторяем сдвиг на (16 - 4 * (1 + n)) исходного числа с последующим AND 15 и извлечением из таблицы. Данные из таблицы сдвигаем на n и делаем OR с результатом. Для n=2 и n=3. 10. В результате получаем то, что требовалось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 3 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба На ядре M3 этот алгоритм может занимать всего два такта, если GPIO сидит на быстрой шине. Можно ссылочку на камень, который умеет записывать в периферию (я так понимаю, это непосредственная адресация?) в 1 такт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 26 февраля, 2016 Опубликовано 26 февраля, 2016 · Жалоба Сделал. На картинке: 1 строка - входные биты 2 строка - номера для bit_table_item 3 строка - выходные биты 4 строка - номера для table .macro bit_table_item shift_in shift_out lsrs r4, r0, # \shift_in ands r4, r3 ldr r4, [r2, r4] .if \shift_out lsrs r4, # \shift_out .endif orrs r1, r4 .endm .global bit_table bit_table: push {r1-r4, lr} eors r1, r1 ldr r2, table ldr r3, =#31 bit_table_item 27 0 bit_table_item 21 1 bit_table_item 16 2 bit_table_item 11 3 bit_table_item 5 4 bit_table_item 0 5 mov r0, r1 pop {r1-r4, pc} .macro table_item b4 b3 b2 b1 b0 .word (\b4 << 29) | (\b3 << 23) | (\b2 << 17) | (\b1 << 11) | (\b0 << 5) .endm .align 4 table: table_item 0 0 0 0 0 table_item 0 0 0 0 1 table_item 0 0 0 1 0 table_item 0 0 0 1 1 table_item 0 0 1 0 0 table_item 0 0 1 0 1 table_item 0 0 1 1 0 table_item 0 0 1 1 1 table_item 0 1 0 0 0 table_item 0 1 0 0 1 table_item 0 1 0 1 0 table_item 0 1 0 1 1 table_item 0 1 1 0 0 table_item 0 1 1 0 1 table_item 0 1 1 1 0 table_item 0 1 1 1 1 table_item 1 0 0 0 0 table_item 1 0 0 0 1 table_item 1 0 0 1 0 table_item 1 0 0 1 1 table_item 1 0 1 0 0 table_item 1 0 1 0 1 table_item 1 0 1 1 0 table_item 1 0 1 1 1 table_item 1 1 0 0 0 table_item 1 1 0 0 1 table_item 1 1 0 1 0 table_item 1 1 0 1 1 table_item 1 1 1 0 0 table_item 1 1 1 0 1 table_item 1 1 1 1 0 table_item 1 1 1 1 1 Листинг .global bit_table bit_table: push {r1-r4, lr} 8003978: b51e push {r1, r2, r3, r4, lr} eors r1, r1 800397a: 4049 eors r1, r1 ldr r2, table 800397c: 4a10 ldr r2, [pc, #64] ; (80039c0 <table>) ldr r3, =#31 800397e: 4b32 ldr r3, [pc, #200] ; (8003a48 <table+0x88> = 0x1F) bit_table_item 27 0 8003980: 0ec4 lsrs r4, r0, #27 8003982: 401c ands r4, r3 8003984: 5914 ldr r4, [r2, r4] 8003986: 4321 orrs r1, r4 bit_table_item 21 1 8003988: 0d44 lsrs r4, r0, #21 800398a: 401c ands r4, r3 800398c: 5914 ldr r4, [r2, r4] 800398e: 0864 lsrs r4, r4, #1 8003990: 4321 orrs r1, r4 bit_table_item 16 2 8003992: 0c04 lsrs r4, r0, #16 8003994: 401c ands r4, r3 8003996: 5914 ldr r4, [r2, r4] 8003998: 08a4 lsrs r4, r4, #2 800399a: 4321 orrs r1, r4 bit_table_item 11 3 800399c: 0ac4 lsrs r4, r0, #11 800399e: 401c ands r4, r3 80039a0: 5914 ldr r4, [r2, r4] 80039a2: 08e4 lsrs r4, r4, #3 80039a4: 4321 orrs r1, r4 bit_table_item 5 4 80039a6: 0944 lsrs r4, r0, #5 80039a8: 401c ands r4, r3 80039aa: 5914 ldr r4, [r2, r4] 80039ac: 0924 lsrs r4, r4, #4 80039ae: 4321 orrs r1, r4 bit_table_item 0 5 80039b0: 0004 movs r4, r0 80039b2: 401c ands r4, r3 80039b4: 5914 ldr r4, [r2, r4] 80039b6: 0964 lsrs r4, r4, #5 80039b8: 4321 orrs r1, r4 mov r0, r1 80039ba: 4608 mov r0, r1 pop {r1-r4, pc} 80039bc: bd1e pop {r1, r2, r3, r4, pc} 80039be: 46c0 nop 080039c0 <table>: 80039c0: 00000000 .word 0x00000000 80039c4: 00000020 .word 0x00000020 80039c8: 00000800 .word 0x00000800 80039cc: 00000820 .word 0x00000820 80039d0: 00020000 .word 0x00020000 80039d4: 00020020 .word 0x00020020 80039d8: 00020800 .word 0x00020800 80039dc: 00020820 .word 0x00020820 80039e0: 00800000 .word 0x00800000 80039e4: 00800020 .word 0x00800020 80039e8: 00800800 .word 0x00800800 80039ec: 00800820 .word 0x00800820 80039f0: 00820000 .word 0x00820000 80039f4: 00820020 .word 0x00820020 80039f8: 00820800 .word 0x00820800 80039fc: 00820820 .word 0x00820820 8003a00: 20000000 .word 0x20000000 8003a04: 20000020 .word 0x20000020 8003a08: 20000800 .word 0x20000800 8003a0c: 20000820 .word 0x20000820 8003a10: 20020000 .word 0x20020000 8003a14: 20020020 .word 0x20020020 8003a18: 20020800 .word 0x20020800 8003a1c: 20020820 .word 0x20020820 8003a20: 20800000 .word 0x20800000 8003a24: 20800020 .word 0x20800020 8003a28: 20800800 .word 0x20800800 8003a2c: 20800820 .word 0x20800820 8003a30: 20820000 .word 0x20820000 8003a34: 20820020 .word 0x20820020 8003a38: 20820800 .word 0x20820800 8003a3c: 20820820 .word 0x20820820 8003a40: e000ed0c .word 0xe000ed0c ; левое 8003a44: 05fa0004 .word 0x05fa0004 ; левое 8003a48: 0000001f .word 0x0000001f UDP: подрихтовал Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sherr 0 26 февраля, 2016 Опубликовано 26 февраля, 2016 (изменено) · Жалоба Сделал. Спасибо ,Пока не могу оценить - в ассемблере слаб (и вот повод подразобраться), Тоже сделал на С, ну как умею uint32_t const bitveer [32]= {// 10987654321098765432109876543210 0b00000000000000000000000000000000, 0b00000000000000000000000000000100, 0b00000000000000000000000100000000, 0b00000000000000000000000100000100, 0b00000000000000000100000000000000, 0b00000000000000000100000000000100, 0b00000000000000000100000100000000, 0b00000000000000000100000100000100, 0b00000000000100000000000000000000, 0b00000000000100000000000000000100, 0b00000000000100000000000100000000, 0b00000000000100000000000100000100, 0b00000000000100000100000000000000, 0b00000000000100000100000000000100, 0b00000000000100000100000100000000, 0b00000000000100000100000100000100,//15 0b00000100000000000000000000000000, 0b00000100000000000000000000000100, 0b00000100000000000000000100000000, 0b00000100000000000000000100000100, 0b00000100000000000100000000000000, 0b00000100000000000100000000000100, 0b00000100000000000100000100000000, 0b00000100000000000100000100000100, 0b00000100000100000000000000000000, 0b00000100000100000000000000000100, 0b00000100000100000000000100000000, 0b00000100000100000000000100000100, 0b00000100000100000100000000000000, 0b00000100000100000100000000000100, 0b00000100000100000100000100000000, 0b00000100000100000100000100000100//31 }; /*****************************************************************/ uint32_t cms[1024];//matrix of leds 16*64 --> low 16 bit is pixel of line 0.1.2... ,high - line 16, 17. 18 ... in BGR16 format uint32_t lin[64]; // line buffer B4H.G4H.R4H.B4L........R0L.0.0 /*****************************************************************/ void fill_string (uint16_t num) //num is LED line number(0-15) { uint32_t tm = 0, z = 0;// temp variables uint16_t adr=0,adr_st=0;//temp vars of adresses ->string 0-15;16-31, adr = num*64; for(int i=0;i<64;i++) { tm = 0; z = cms[adr]; // cells (2*rgb) to temp var tm = bitveer[(z & 0x1F)]; //table conversion z>>=6 ; //Green0 is unneeded bit tm |= (bitveer[(z & 0x1F)]<<1); z>>=5 ; tm |= (bitveer[(z & 0x1F)]<<2); z>>=5 ; tm |= (bitveer[(z & 0x1F)]<<3); z>>=6 ; tm |= (bitveer[(z & 0x1F)]<<4); z>>=5 ; tm |= (bitveer[(z & 0x1F)]<<5); lin[adr_st] = tm ; adr++; adr_st++; } } , стало быстрее почти в 4 раза, Изменено 26 февраля, 2016 пользователем sherr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 27 февраля, 2016 Опубликовано 27 февраля, 2016 · Жалоба В принципе задача сводится к пяти преобразованиям типа : ABCDxxxxxxx,,, в A00000B00000C00000D00000... где A-D это биты Это преобразование можно сделать так: y = ((x & 0xF) * 0x8421) & 0x41041; Если умножение за один такт, то может получиться очень интересно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sherr 0 4 марта, 2016 Опубликовано 4 марта, 2016 · Жалоба А подскажите, как обратное преобразование сделать, в частности у меня A0000B00000C0000D0000E00000F0000 -> .....000000ABCDEF00 ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 4 марта, 2016 Опубликовано 4 марта, 2016 · Жалоба А подскажите, как обратное преобразование сделать, в частности у меня A0000B00000C0000D0000E00000F0000 -> .....000000ABCDEF00 ? Побитово собирать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 4 марта, 2016 Опубликовано 4 марта, 2016 (изменено) · Жалоба Побитово собирать. чтобы собирать быстрее, надо использовать группирование: 1) A0000B0000C0000D0000E0000F0000 -> AB000BC000CD000DE000EF000F0000 2) AB000 BC000 CD000 DE000 EF000 F0000 -> AB000 00000 CD000 DE000 00000 F0000 2) AB000 00000 CD000 DE000 00000 F0000 -> ABDE0 00000 CDF00 DE000 00000 F0000 3) ABDE0 00000 CDF00 DE00 00000 F0000 -> Изменено 4 марта, 2016 пользователем AlexRayne Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться