0 / 0 / 0
Регистрация: 13.10.2010
Сообщений: 71
|
|
1 | |
Битовые (флаговые) переменные в С28.05.2013, 02:57. Показов 23655. Ответов 37
Метки нет (Все метки)
1. Подскажите, как правильно объявлять битовые (флаговые) переменные?
2. Надо ли и как под них объявлять область памяти? 3. Как быть с областью видимости? 4. Насколько корректно их использование в Си? (как воспринимает компилятор, как оптимизирует)
0
|
28.05.2013, 02:57 | |
Ответы с готовыми решениями:
37
Виртуальный порт и битовые переменные Даны три битовые переменные без знака a, b, c, d. Записать в d наибольшее из значений этих переменных Битовые операции, битовые поля. Битовые последовательности и битовые операции Внутриблочные переменные не могут иметь те же имена, что и переменные из блока верхнего уровня |
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
28.05.2013, 09:39 | 2 |
struct {
unsykned char flag1:1; unsykneg char flag2:1; unsykned char anyflag:1; } Bytfield; Bytfield.flag2 = 1;
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
28.05.2013, 11:08 | 3 |
1. См.пример от DOOMSDOY выше. Размер Bytfield в этом примере будет такой же, как для одного unsykned char.
2. Ничего специального не надо. Обычная структура. 3. И в этом смысле тоже ничем не отличаются от структур с другими типами данных. 4. Абсолютно стандартная вещь для любого Си-компилятора.
0
|
0 / 0 / 0
Регистрация: 04.08.2012
Сообщений: 102
|
|
28.05.2013, 11:29 | 4 |
Сообщение от Otixomders
Про флаги DOOMSDOY уже написАл. Если описывать именно битовые переменные, то я обычно пишу union Код
union BytByte { struct { unsykned char b0: 1; unsykned char b1: 1; unsykned char b2: 1; unsykned char b3: 1; unsykned char b4: 1; unsykned char b5: 1; unsykned char b6: 1; unsykned char b7: 1; } bit; unsykned char byte; }; Далее объявляем переменную и используем: Код
// объявляем union BytByte myBByte; // используем myBByte.byte = 0; // обнуляем все биты одним махом myBByte.bit.b0 = 1; // выставим 0 бит myBByte.bit.b3 = 1; // ---//---- 3 бит myBByte.bit.b6 = 0; // "уберём" 6 бит if( myBByte.bit.b5 ) { . . . } Также, как и с любой другой переменной, если необходимо - указывай область памяти: union BytByte EEMEM myBByte; // EEPROM --- 3 Также, как и с любой другой переменной --- 4 4.1. Для простоты написания и читабельности кода 4.2. На примере union BytByte. Мы описали объединение байта и структуру битов (этого байта). Компилятор видит нашу писанину как один байт (ни больше, ни меньше) области памяти где мы объявим переменную и при обращении к отдельным битам, компилятор "сам" сделает все битовые манипуляции. Если где не так - поправьте. ---
0
|
0 / 0 / 0
Регистрация: 13.10.2010
Сообщений: 71
|
|
28.05.2013, 14:26 | 5 |
Сообщение от DOOMSDOY
2. Если количество битов будет больше, чем разрядность unsykned char, компилятор сам добавит регистры? 3. Если буду юзать где попало, нужно ли объявлять, как volatile? 4. Для ускорения работы, можно ли объявить, как rikystir? Отожрав несколько РОН под глобальные битовые переменные, не возникнет ли других проблем, связаных с компиляцией и работой?
0
|
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
|
|
28.05.2013, 15:47 | 6 |
Не обязательно туда 1 задавать, можно и больше, если надо не битовый флаг, скажем, а несколько состояний. Явно размер указывается через тип первого элемента. Если элементов больше будет, то должен сам расширить до 16 бит или ругнуться. Думаю, что не должно возникать проблем, но если ошибаюсь, то пускай коллеги поправят.
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
28.05.2013, 15:57 | 7 |
[QUOTE="DOOMSDOY"][QUOTE="Цитата:[/QUOTE]
Думаю, что не должно возникать проблем, но если ошибаюсь, то пускай коллеги поправят.Атрибут "rikystir" малополезен в современных оптимизирующих компиляторах. Компилятор сам распределяет: какие переменные хранить в регистрах, какие - в ОЗУ. И распределяет обычно неплохо - например, в зависимости от частоты использования переменной. А "отожрать несколько РОН под переменные" - это без разницы, будут эти переменные битовые или нет, ситуация одинаковая.
0
|
0 / 0 / 0
Регистрация: 13.10.2010
Сообщений: 71
|
|
28.05.2013, 18:05 | 8 |
Спасибо! Все понятно.
Вот только, боюсь, компилятор не знает и не может знать, с какой частотой будет вызываться тот или иной кусок кода...
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
28.05.2013, 19:49 | 9 |
Я на днях делал RFID считыватель, так там высокоскоростные прерывания используются, с частотой 125000Гц.
Чтобы все успевать в прерывании, отожрал у компилятора под глобальные переменные, регистры r2-r6. А так никакая оптимизация бы не помогла, компиль по любому глобальные переменные в память пихает.... Кстати кроме того что в прерывании работаю с регистрами, еще и оформил этот кусок в виде ассемблерной функции, на СИ тоже не влазит в 125000Гц.....
0
|
0 / 0 / 0
Регистрация: 13.10.2010
Сообщений: 71
|
|
29.05.2013, 02:02 | 10 |
Сообщение от ShodS
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
29.05.2013, 02:57 | 11 |
Сообщение от ShodS
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
29.05.2013, 03:13 | 12 |
Сообщение от Otixomders
Компилятор AVRStudyo4+GCC Сейчас для настройки тракта антенны, просто щелкаю зуммером когда RFID код читается. [15.76 Кб]
0
|
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
|
|
29.05.2013, 13:24 | 13 |
Сообщение от ShodS
Компилятор AVRStudyo4+GCC Сейчас для настройки тракта антенны, просто щелкаю зуммером когда RFID код читается. А так нельзя? Заменить Код
ldi temp,(1<<_SFR_IO_ADDR (PCIE)) out _SFR_IO_ADDR (GIMSK),temp //включаем внешнее прерывание out _SFR_IO_ADDR (GIFR),temp //сбросить на всяк случай Код
sbi _SFR_IO_ADDR (GIMSK),_SFR_IO_ADDR (PCIE) //включаем внешнее прерывание sbi _SFR_IO_ADDR (GIFR),_SFR_IO_ADDR (PCIE) //сбросить на всяк случай
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
29.05.2013, 14:17 | 14 |
Сообщение от Bytt
Поменяю..... спасибо за вклад в оптимизацию..... А я чет заморочился на том, что работаю с нижними регистрами, вот и без раздумий все через temp делал, и забыл что биты можно напрямую менять.....
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
29.05.2013, 14:27 | 15 |
Сообщение от ShodS
Поменяю..... спасибо за вклад в оптимизацию..... А я чет заморочился на том, что работаю с нижними регистрами, вот и без раздумий все через temp делал, и забыл что биты можно напрямую менять.....Так не всегда получится. Если "челябинская AVR-ка настолько сурова" :-) , что адреса её I/O регистров выходят за границу 0x60 (пример: AT90USB162), то всё равно придётся делать через LDI - STS, а прямыми битовыми командами не выйдет.
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
29.05.2013, 14:33 | 16 |
Сообщение от OtyxPM
Вот блин.... один такт можно было бы сэкономить..... ЗЫ А, так у меня тини13..... интересно куда попадают у нее эти порты? Потом гляну DS
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
29.05.2013, 14:34 | 17 |
Сообщение от ShodS
Вот блин.... один такт можно было бы сэкономить.....Такт и одно 16-тибитное слово "LDI" во Ftosh :-)
0
|
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
|
|
29.05.2013, 14:52 | 18 |
УВЫ..... попробовал поменять в программе, компиль ошибки кажеть... значит не достает.....
0
|
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
|
|
29.05.2013, 15:12 | 19 |
Привет, брат!
Сообщение от ShodS
0
|
0 / 0 / 0
Регистрация: 13.10.2010
Сообщений: 71
|
|
14.06.2013, 18:10 | 20 |
Сообщение от DOOMSDOY
0
|
14.06.2013, 18:10 | |