EEPROM Работа с битами

IUS
Offline
Зарегистрирован: 15.01.2015

Добрый день подскажите молодому

Необходимо записывать,  хранить и считывать 6 битовых состояний , теоретьчески можно задействовать 6 адресов, но это не наш метод. Думаю в 1 адрес записывать и читать переменную , а в коде программы разлажиать в масив Boolean. И также собирать для записи.

Подскажите плиз как это сделать правильно, а главное эстетично. По возможности пример, или подробно для чайника, зарание благодарен.

X-Dron
Offline
Зарегистрирован: 24.01.2015

Не получится. Тип boolean занимает целый байт в памяти false = 0, true = 1...255.
http://www.arduino.cc/en/Reference/BooleanVariables

http://www.arduino.cc/en/Reference/Constants

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

IUS, я лично не понял что имел ввиду x-dron, может я сам не правильно понял? У вас есть например 6 портов, и вы хотите записывать их состояние в еепром, уместив всё в один байт? Это можно, и нужно именно так делать. Специально для начинающих есть команды BitRead и им подобные.

X-Dron
Offline
Зарегистрирован: 24.01.2015

Я думал про самое простое решение -
 

union MyUnion {
    byte ByteVal;
    boolean booleanVal[8];
};

Вот оно работать не будет.Массив из 8-ми boolean занимает не один, а 8 байт.
А вот запихивать и считывать биты bitSet() (или просто кодированием по степени двойки) и bitRead() действительно можно.

Datak
Offline
Зарегистрирован: 09.10.2014

Или, ещё, можете почитать про  Битовые поля в C++

Если понравится - пользуйтесь.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Работа с битами, хоть в EEPROM, хоть в ОЗУ флеше или в портах отличается только операцией чтения и записи. Основа же одинакова. Все верно тип BOOL занимает в случае с ардуино один байт, поскольку это восьмиразрядный процессор. Был бы 16 разрядный тип занимал бы одно слово - 16 бит. Но это вовсе не значит, что мы не можем оперировать битами, в том числе и для хранения логических состояний. К тому же си язфк в котором всегда одну задачу можно решить уймой способов. Например bitRead  и bitSet, или используя длгические битовые операции. Но есть способ для тех кому лень заморвчиваться со светрыванием и развертыванием данных, давайте доверим это компилятору и объявим вот такую структуру:

struct bits_byte {
  unsigned char bit0: 1;
  unsigned char bit1: 1;
  unsigned char bit2: 1;
  unsigned char bit3: 1;
  unsigned char bit4: 1;
  unsigned char bit5: 1;
  unsigned char bit6: 1;
  unsigned char bit7: 1;
}; 

Теперь используя этот тип объявим переменную

bits_byte myByte;

// установка бита
myByte.bit0=true;

Ну а дальше сами разберетесь :) 

Хыыыы... опередили :)

IUS
Offline
Зарегистрирован: 15.01.2015

Да, это то, что нужно. Всем огромное спасибо, щас разберусь

dachnik
Offline
Зарегистрирован: 26.07.2013

Тоже сейчас наткнулся на это и встал вопрос:

С чтением битов из eeprom проблем нет, пример:

bitRead(EEPROM.read(s_name.PAR.EEPROM_ADR), 0)

А вот как записать в eeprom бит через bitWrite?

строчка такого типа не работает:

EEPROM.write(s_name.PAR.EEPROM_ADR, bitWrite(s_name.PAR.EEPROM_ADR,1, x));

я в ступоре

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

И чтение и запись в EEPROM осуществляется только байтами. Там, где Вам кажется, что Вы считали бит, на самом деле Вы считали байт и выделили из него нужный бит.

Аналогично нужно поступать и при записи: читаете байт, устанавливаете в нем нужный бит в нужное состояние и записываете байт обратно.

dachnik
Offline
Зарегистрирован: 26.07.2013

т.е. пишу байт из eeprom в локальную переменную, меняю её и записываю обратно в eeprom?

dachnik
Offline
Зарегистрирован: 26.07.2013

Спасибо, выручили =) Может кому пригодтся :

void write_value(add s_name)  //передаём структуру
{
  int memEncoder_position = i; //запоминаем значение энкодера
  byte eeprom_byte = EEPROM.read(s_name.PAR.EEPROM_ADR); // читем байт из памяти  
  bool eeprom_bit = bitRead(eeprom_byte, 1); //вытащили первый бит из байта
  i = eeprom_bit; //присваиваем значение энкодера к прочитанному биту
  bool x;//вводим новую переменную
  
while(!Btn) //входим в цикл, крутимся пока нажата кнопка
  {

  if (i>1){i=0;} //чтобы было либо 0 либо 1
  if (i<0){i=1;} 
    x = i;
  int a=enc.read();                         //  Читаем состояние энкодера в переменную a
  if(a){                                    //  Если энкодер зафиксировал поворот, то ...
    i=i+a;   /* i+=a*/                    //  Меняем значение переменной i на 1, т.к. в переменной a находится -1 (при повороте влево), или +1 (при повороте вправо).

     } 
    display.clearDisplay();
//delay (1000);
    display.setCursor(0,0);
    display.print(s_name.s_name);
    display.print(".CS.MODE=");
    display.println(x);
    bitWrite(eeprom_byte, 1, x);
    EEPROM.update(s_name.PAR.EEPROM_ADR, eeprom_byte);
   // bitWrite(x, n, b) 

   
   display.display();
  }
  i=memEncoder_position; //возвращаем значение энкодера 
  structures();
}