База знаний
Запись переменных битами
Одна переменная может хранить не только обычное число, но и набор отдельных признаков. В промышленной автоматизации так часто передают состояния, аварии, разрешения, режимы работы и packed-флаги в Modbus-регистрах.
Бит как отдельный флаг
Каждый бит имеет номер и вес. Если бит равен 1, его вес добавляется к итоговому числу. Если бит равен 0, он ничего не добавляет. Для целочисленных типов это простая сумма степеней двойки.
BYTE, WORD и DWORD
BYTE содержит 8 бит, WORD - 16 бит, DWORD - 32 бита. В картах Modbus один 16-битный holding register часто описывают как WORD: внутри него может быть одно значение 0...65535 или 16 независимых флагов.
| Тип | Размер | Обычное применение |
|---|---|---|
BYTE | 8 бит | Небольшой набор флагов или значение 0...255. |
WORD | 16 бит | Один Modbus-регистр, status word, alarm word, control word. |
DWORD | 32 бита | Два Modbus-регистра, большая маска флагов или 32-битное число. |
Signed-типы
В SHORT8, INT16 и DINT32 старший бит используется как часть знакового представления. Обычно применяется дополнительный код: если старший бит установлен, число считается отрицательным. Например, INT16 с битовым шаблоном 1111 1111 1111 1111 означает -1, а не 65535.
REAL: знак, экспонента и мантисса
REAL - это не просто сумма битов. В большинстве PLC и SCADA он хранится как 32-битное число IEEE-754 Float32: один бит знака, 8 бит экспоненты и 23 бита мантиссы. Поэтому одинаковые 32 бита можно прочитать как UDINT32 и как REAL, но смысл будет разный.
| номер бита | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| часть | MANTISSA | |||||||||||||||
| содержание | 1/21 | 1/22 | 1/23 | 1/24 | 1/25 | 1/26 | 1/27 | 1/28 | 1/29 | 1/210 | 1/211 | 1/212 | 1/213 | 1/214 | 1/215 | 1/216 |
| значение бита | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| номер бита | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| часть | MANTISSA | EXPONENT | S | |||||||||||||
| содержание | 1/217 | 1/218 | 1/219 | 1/220 | 1/221 | 1/222 | 1/223 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | +/- |
| значение бита | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
(-1)S x 1.M x 2E-1271.M.0 - положительное число, 1 - отрицательное число.Что важно в Modbus
Modbus передаёт регистры по 16 бит. Если переменная занимает 32 бита, она лежит в двух регистрах. Для DWORD, DINT32 и REAL важно знать порядок слов: старшее слово первым или младшее слово первым. Если порядок выбран неверно, биты будут те же, но число получится неправильным.
Частые вопросы по битовым переменным
Как понять, какой бит включён в WORD
Разложите значение на степени двойки. Например, если в WORD включён бит 3, его вес равен 2^3 = 8. Несколько включённых битов складываются, поэтому значение 9 означает биты 3 и 0.
Чем signed отличается от unsigned
В unsigned-типе все биты участвуют в положительном числе. В signed-типе старший бит становится битом знака, поэтому тот же набор битов может означать отрицательное значение. Для диагностики важно знать тип из карты устройства.
Почему REAL сложнее WORD и DWORD
REAL хранит число по IEEE-754 Float32: знак, экспоненту и мантиссу. Здесь нельзя просто сложить веса битов как для флагов. Нужно учитывать формулу, порядок слов в Modbus и способ отображения числа в программе.