|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 8:13 am
|
Страница 1 от 1
|
[ 14 мнения ] |
|
| Автор |
Съобщение |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 673
|
 Битови манипулаций в С++
Има ли по лесен начин в C++(защото го пиша е такава среда и знам че се пише като на С) да се
отдели бит от байт и да се използва в случая като променлива char
|
| Чет Яну 15, 2009 9:05 pm |
|
 |
|
bobyk
Ранг: Ориентиран
Регистриран на: Пон Яну 09, 2006 11:32 am Мнения: 276 Местоположение: Kozloduy
|
Ами мисля че второто ще генерира по-къс код. Иначе мога да ти каже че ако е за пик на асм може да стане с 3 инструкции, а авр може да го направи дори с 2 инструкции (има инструкции bit load, bit store)
|
| Чет Яну 15, 2009 9:27 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 673
|
Така е правилно .... сбъркал съм по горе. Използвах това по друг случай Компилаторите за микроконтролери позволяват проненливи дефинирани като ...
Интересува ме как се прави в Borland C++.
|
| Чет Яну 15, 2009 10:01 pm |
|
 |
|
¶
Ранг: Форумен бог
Регистриран на: Пет Фев 25, 2005 1:58 pm Мнения: 4585 Местоположение: US
|
Какво искаш да правиш, след като си отделил бита и си го заредил в променлива тип char ? Искаш бита да е на същата позиция на която си е бил, или просто искаш да го заредиш като 1 или 0 в променливата тип char ?
Втория код ( ако е само да знаеш 1 или 0 ) може да стане още по-компактен ( като размер, не като скорост ), ако го напишеш така:
_________________ Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....
|
| Чет Яну 15, 2009 11:55 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 673
|
Да 0 или 1 в променлива тип чар.
Искам да следя състояние на портове. Да се виждат в прозореца на програмата.Имам на платката 4 джъмпера, и тях искам да виждам на прозореца.
Искам да изписвам прочетените от ADC-стойности на няколко пина, и ми трябва най компактно прехвърляне по серийния порт ( промерно с 2 BCD za 4 цифри). И се чудя как да намаля размера на пакетите, за да се обновява най-бързо на екрана на PC-то.
Или по точно , имам една машина на която трябва да заменя скъпоструващото оригинално процесорно, с много, много по ефтино.
Но има процеси който трябва да се настройват много финно в реално време, за да е налице същия резултат.
Трябва да следя състоянието на мощните елементи и да се сигнализира при повреда, вентилатори да ли се въртят...
|
| Пет Яну 16, 2009 10:18 am |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30686 Местоположение: София
|
То много зависи за какъв процесор го пишеш според мен ама .....
|
| Съб Яну 17, 2009 1:45 pm |
|
 |
|
Цецо
Ранг: Форумен бог
Регистриран на: Пон Сеп 27, 2004 9:22 am Мнения: 15501 Местоположение: София
|
За съжаление при подобни ситуации ти се налага да поназнайваш асемблер. Инак няма как да знаеш какво е натворил конкретния компилатор, за конкретния процесор. Всеки е със собствено мнение.
_________________ "Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.
|
| Съб Яну 17, 2009 1:55 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 673
|
Ще стане много трудно на асемблер, затова тъпо ама ще заложа на производителност, и повече Mhz.
Мисля си за Mega32. Важно ми е, и не искам да ползвам някоя SAM7 , все още не съм ги изучил добре.
|
| Съб Яну 17, 2009 5:07 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Ако искаш да намалиш размера на пакетите и да стане по-бързо, предавай направо целия байт (port_b_byte). И остави ПС-то да се занимава с манипулирането на битовете. Освен това като напишеш веднъж фърмуеъра после е въпрос на развой върху ПС за да получиш информацията на монитора във вид в който ти е най-удобно.
Иначе ако въпроса ти е принципен, както Цецо ти каза гледай резултата в асемблера. При arm-elf-gcc например с включена оптимизация, както и да го напишеш на С в крайна сметка и двата варианта, които си дал ще се сведат до едно и също. 
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Съб Яну 17, 2009 9:45 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
arm-elf-gcc вероятно ще се справи по-добре в първия случай, защото няма if() и при thumb ще се избегнат преходи (които тормозят конвейра) а при arm-mode може да се избегне условното изпълнение, т.е. вместо с 2 да стане с 1 инструкция. Друг е въпросът, arm-elf-gcc има алергия към char & short типове и много вероятно да вкара излишно шифтване напред-назад...
Това което буди недоумение е защо трябва да се пръскат битовете в отделни променливи. Обикновено много по-ефективно е в една променлива да се запиши стойността на целия порт.
Иначе и маската ако е константа е безсмислена...
|
| Съб Яну 17, 2009 11:13 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Абе да ти кажа не вложих толкова усилия в разсъждението относно arm-elf-gcc. Основната ми мисъл беше че маскирането обикновенно го свежда винаги до шифтване наляво и после надясно.
Ето един набързо скалъпен тест:
Резултата е:  |  |  |  | Код: 400007a0 <_Z8test_bitv>: 400007a0: e59f201c ldr r2, [pc, #28] ; 400007c4 <_Z8test_bitv+0x24> 400007a4: e5d23000 ldrb r3, [r2] 400007a8: e2132004 ands r2, r3, #4 ; 0x4 400007ac: 159f3014 ldrne r3, [pc, #20] ; 400007c8 <_Z8test_bitv+0x28> 400007b0: 059f3010 ldreq r3, [pc, #16] ; 400007c8 <_Z8test_bitv+0x28> 400007b4: 13a02001 movne r2, #1 ; 0x1 400007b8: 15c32000 strbne r2, [r3] 400007bc: 05c32000 strbeq r2, [r3] 400007c0: e12fff1e bx lr 400007c4: 40004000 .word 0x40004000 400007c8: 40004001 .word 0x40004001
400007cc <_Z9test_bit2v>: 400007cc: e59f3014 ldr r3, [pc, #20] ; 400007e8 <_Z9test_bit2v+0x1c> 400007d0: e5d32000 ldrb r2, [r3] 400007d4: e59f3010 ldr r3, [pc, #16] ; 400007ec <_Z9test_bit2v+0x20> 400007d8: e1a02122 lsr r2, r2, #2 400007dc: e2022001 and r2, r2, #1 ; 0x1 400007e0: e5c32000 strb r2, [r3] 400007e4: e12fff1e bx lr 400007e8: 40004000 .word 0x40004000 400007ec: 40004001 .word 0x40004001
400007f0 <_Z9test_bit3h>: 400007f0: e1a00120 lsr r0, r0, #2 400007f4: e2000001 and r0, r0, #1 ; 0x1 400007f8: e12fff1e bx lr
400007fc <_Z9test_bit4h>: 400007fc: e1a00120 lsr r0, r0, #2 40000800: e2000001 and r0, r0, #1 ; 0x1 40000804: e12fff1e bx lr |  |  |  |  |
Това е в arm режим.
Тука се вижда един дефект на компилатора, който имам инсталиран на домашния компютър. В първата функция има ненужно дублиране на унструкции. Нещо беше скапана тази версия(4.2.2) която инсталирах тогава с YAGARTO. В предишната както и в последната тези магарии ги няма.
Но се вижда че последните две функции са еднакви.  Макар че не точно това имах впредвид.
А за пръскането на битовете в отделни байтове и аз това имах впредвид - не е нужно.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Нед Яну 18, 2009 12:35 am |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
Избягвай char... в случая
unsigned char test_bit4(unsigned char port_b)
е по-добре да е:
unsigned int test_bit4(unsigned int port_b)
Самата функция декрарина и по двата начина ще ти даде един и същ код, но при извикването може да те изненада ако я викнеш така:
test_bit4(port_b_byte +1);
просто ще вкара два ненужни шифта за да направи параметър char, демек да махне евентуален пренос в старшия байт...
|
| Нед Яну 18, 2009 1:11 am |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Това е ясно.
Написах го с char само за примера. Явно стратегията на компилатора е да маскира старшите байтове извън функцията, при извикването и, и затова наистина в примерите не се вижда това което искаше да кажеш в предния пост. Дано не сме забъркали по-голяма каша в главата на RM с "академичното" отклонение към arm-elf-gcc.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Нед Яну 18, 2009 1:39 am |
|
 |
|
Yanek
Ранг: Новодошъл
Регистриран на: Пет Юни 29, 2007 10:59 pm Мнения: 113
|
Компилаторите, които използвам за С и С++ за микроконтролери обикновено позволяват побитови структури. Ето пример на IAR:
Този пример е с абсолютно задаване на адреса на променливата. по друг начин: В клас:
Редакция: Редно е компилатора да изписка от подобно неявно преобразуване на char в unsigned char, но IAR-а явно счита, че не може да се получи загуба на информация (наистина е така) и си мълчи. Затова и съм го оставил така.
|
| Нед Яну 18, 2009 2:53 pm |
|
|
|
Страница 1 от 1
|
[ 14 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 4 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|