Есть массив типа boolean, нужно отправить его на eeprom 24с32 по i2c, использую стандартную библиотеку wire. Таким образом осуществлять передачу нужно побайтово, могу взять и собрать из булеанов байт, однако мне интересно есть ли способ сразу взять 8 булеанов и отправить непосредственно, они ведь в памяти друг за другом следуют?
возьми 1 байт, в котором каждый из 8 бит (B00000000) будет отвечать за свой boolean. Т.е. пересылаешь 1 байт, а на приемнике он уже разворачивается в 8 переменных boolean (либо так и оперируй побитово).
Используйте битовые операции логики и сдвига, тогда упихать 8 бит в байт проблем не будет. Если самостоятельно не получится, напишу как.
буду использовать примерно следующий алгоритм: byte a = 0; //переменая в которую буду помещать значение boolean byte b = 0; //переменая в кторорой соберу число из 8 boolean for(byte i =0,i<8,i++) { a = mass; //из массива boolean передаю в а значение b= b||a; b = b <<1; } //после чего отправлю b Правильно?
разобрался, вот так должно быть byte a = 0; //переменая в которую буду помещать значение boolean byte b = 0; //переменая в кторорой соберу число из 8 boolean for(byte i =0,i<8,i++) { b = b <<1; a = mass; //из массива boolean передаю в а значение b= b|a; } //после чего отправлю b
ну это не проблема С, это вообще не проблема, это фича мк atmega328 и других atmeg- у них нет битовых полей. В некоторых других мк можно в память писать /считывать побитно.
Не до конца понимаю что такое битовое поле(кажется это та часть ячейки памяти, которая нужнна, но которую нужно сперва вычленить?).Однако ведь программно можно хранить 8 битовых значений как в одном, так и в 8 байтах. В codevisionAVR есть возможность оптимизации кода по размеру и по скорости выполнения, догадываюсь явление связанно с данным вопросом?
Нет, оптимизация не связана с хранением булевых переменных как битов, побайтная адресация - сво-ва atmega, и тут ничего с'оптимизировать не получится. Оптимизация по размеру обычно делается выделением общих каких-то функций или действий в отдельные функции, например если вы анализируете пины и по результатам что-то делаете похожее, то компилятор может объединить эти действия в одну функцию, когда оптимизация по скорости - наоборот, за счет уменьшения переходов оптимизирируется скорость, но размер кода как правило растет.
Битовые поля -- это фишка компилятора, а не контроллера. Компилятор avr-gcc (для atmega и прочих avr) поддерживает битовые поля и ни каких проблем с использованием битовых полей в AVR'ках нет. Здесь у меня пробел в знаниях, можете подсказать МК, в котором можно адресовать отдельные биты? Что касается того, что тип bool в памяти представляется как байт, то связано это с тем, что переменная каждого типа должена быть адресуемой. А в большинстве МК/процессоров (AVR'ки, PIC'и, ARM'ы, Intel'ы, AMD'хи, PowerPC'хи и т.п.) минимальной адресуемой ячейкой памяти является байт. Поэтому компиляторы языка C/C++ (семейство GCC, Intel и т.п.), для таких МК/процессоров под bool выделяют байт памяти.
неловко выразился, но смысл тот же- минимальная единица в atmega - байт, а не бит. Но термин битовые поля - относится именно к железу, а не к компилятору. Cквозную адресацию по битам встречал в stm32, вроде 051.
Вообще-то битовые поля присутствуют в Си совершенно стандартным образом и ни с каким компилятором это не связано. Код (C): struct { unsigned int b0:1; unsigned int b1:1; unsigned int b2:1; unsigned int b3:1; unsigned int b4:1; unsigned int b5:1; unsigned int b6:1; unsigned int b7:1; } bitfields8; bitfields8 a; a.b0 = 1; a.b1 = 0; bool x = (0==rand()); a.b2 = x;
При использовании любого побайтового хранилища, хоть FLASH, хоть, EEPROM, хоть обычной памяти SRAM, все равно читать и писать ее придется байтами, поскольку побитовый доступ они не поддерживают. А в таком случае упаковку и распаковку битов в байты все равно придется делать вручную. Ну, написать функцию-обертку. При этом можно использовать как в буквальном смысле синтаксически оформленные битовые поля, так и побитовые операции над байтами целиком, точно так же, как мы поступаем с регистрами. Впрочем, именно в эти операции с регистрами в итоге все и превратится. Для фиксированных полей конфигурации удобнее структуры, для массивов - побитовые операции над байтами. Код (C++): bool getBit(uint16_t addr) { return (eeprom.read(addr>>3) >> (addr&7)) & 1; } void setBit(uint16_t addr, bool data) { uint8_t ha = addr>>3, la = addr&7; uint8_t x = eeprom.read(ha); x = (x&~_BV(la)) | (data<<la); eeprom.write(ha,x); }
Код (C++): return ((eeprom.read(addr>>3) >> (addr&7)) & 1; тут вроде закрывающей скобки не хватает, и у меня есть как минимум две позиции для ее вставки