Преобразование 8-разрядного двоичного файла в шестнадцатеричную пару как unsigned char
У меня есть функция:
void Epd::SendData(unsigned char data) {
digitalWrite(dc_pin, HIGH);
SpiTransfer(data);
}
В данный момент я жестко кодирую данные, отправляемые в него, путем вычисления на бумаге, а затем записываю результат в виде кода, но я хочу это улучшить. Например, я звоню:
SendData(0x03);
SendData(0x1f);
Чтобы получить эти два значения (0x03
и 0x1f
) Я преобразую десятичное значение 799
в двоичное: 1100011111
, а затем добавляю 0
в начале, чтобы убедиться, что мой двоичный результат имеет длину 16 цифр: 0000 0011 0001 1111
. После этого я преобразую каждые 4 бита в шестнадцатеричное значение и отправляю их в виде пар, используя функцию sendData
.
Я чувствую, что я почти на месте, но я не знаю, как преобразовать мой результат в правильный тип, чтобы отправить его в функцию sendData
:
void Epd::SendDecAsData(int dec) {
int binary[16];
for (int i = 0; i < 16; i++) {
binary[i] = dec % 2;
dec = dec / 2;
}
int dec1 = binary[15] * 8 + binary[14] * 4 + binary[13] * 2 + binary[12];
int dec2 = binary[11] * 8 + binary[10] * 4 + binary[9] * 2 + binary[8];
int dec3 = binary[7] * 8 + binary[6] * 4 + binary[5] * 2 + binary[4];
int dec4 = binary[3] * 8 + binary[2] * 4 + binary[1] * 2 + binary[0];
String val1 = "0x" + String(dec1, HEX) + String(dec2, HEX);
String val2 = "0x" + String(dec3, HEX) + String(dec4, HEX);
SendData(val1); // ошибка, потому что я отправляю `String` вместо `unsigned char`
SendData(val2);
}
Мне нужна помощь в преобразовании этих строк (val1
, val2
) в правильный тип данных или, что еще лучше, в оптимизации этого процесса, чтобы получить конечный результат в нужном типе с меньшим количеством кода / вычислений (вероятно, избегая преобразования в строку
).
@pingDino, 👍0
Обсуждение1 ответ
Как предложилStarCat, я могу просто отправлять десятичные значения, используя ту же функцию sendData
, которая мне была предоставлена. Поскольку плата e-ink может обмениваться данными только с помощью 8-битных команд, мне все равно пришлось разделить десятичное значение перед его отправкой.
Это функция, которую я использовал для отправки десятичных данных в 8-битных парах:
void Epd::SendDecAsData(int dec) {
if (dec == 0) {
SendData(0);
SendData(0);
} else {
SendData((dec-1) / 256);
SendData((dec-1) % 256);
}
}
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- форматирование строк в Arduino для вывода
- Очень простая операция Arduino Uno Serial.readString()
- DateTime в строку
- Как преобразовать строку в массив байтов
- Как отправить строку на мастер с помощью i2c
- Создание форматированной строки (включая числа с плавающей запятой) в Arduino-совместимом C++
Если я вас правильно понял, вы хотите разделить 16-битный
int
на дванеподписанных символа
и отправить их. Зачем такое запутанное преобразование в шестнадцатеричное? Почему бы не использовать что-то вродеsendData (dec >> 8); sendData (dec & 0xff);
. Это просто двоичные данные, их не нужно преобразовывать., @StarCat@StarCat Я только что получил существующий код (e-ink board), и я вижу, что они отправляют шестнадцатеричное значение, поэтому я предположил, что должен сделать то же самое. Существует тонна жестко закодированных "sendData", которые вручную преобразуются из dec в hex (по какой-то причине в виде двух вызовов "sendData" из 2-значного шестнадцатеричного числа). Таким образом, даже когда мне просто нужно отправить 0
dec
, он отправляется какsendData (0x00)
, вызываемый дважды. Я надеюсь, что это объяснение поможет, @pingDinoТо, что вы отправляете с помощью sendData(0x00), * не является шестнадцатеричным значением *. Он просто представлен в тексте вашего кода шестнадцатеричным значением, но во время компиляции преобразуется в двоичное значение (unsigned char). Вы можете заменить все вхождения 0xNN их десятичным значением (если они не являются частью строки), и ваша программа будет работать точно так же. Просто попробуй., @StarCat
799
,0x031f
иB0000001100010111
хранятся как одно и то же 16-битное двоичное число... различия заключаются только в исходном коде для чтения человеком .... скомпилированный код всегда имеет дело с0000001100010111
... вся ваша программа конверсии - пустая трата ресурсов ... сделайте то, что предложил @StarCat в первом комментарии, @jsotolaСпасибо вам, ребята. Я попробую завтра, как только доберусь до офиса, @pingDino
`Я жестко кодирую данные , отправляемые в него , путем вычислений на бумаге , а затем записываю результат в виде кода" ... что именно ты здесь делаешь? ... пожалуйста, приведите пример данных, задействованных в расчете, @jsotola
@jsotola например,
031f
- это799
, который представляет ширину изображения, которое я добавляю на плату e-ink. Код, который я использую, говорит, что его нужно разбить на два отдельных вызоваsendData
, но я попробую воспользоваться приведенными выше предложениями. Если это сработает, я могу удалить оооочень много кода: D, @pingDinoхорошо, ширина изображения жестко запрограммирована... если одно и то же значение используется часто, то определите что-то вроде
width_h
иwidth_l
... в противном случае используйте код, предложенный @StarCat ... причина, по которой вам приходится разбивать 16-битные значения, заключается в том, что данные передаются в байтах .... проверьте библиотеку, может быть 16-битная функция передачи, которая делает это за вас, @jsotola@jsotola есть много изображений, и каждое из них имеет значения (x, y, width, height), и их нелегко понять, потому что они разделены как эти две команды sendData, поэтому я хотел упростить добавление новых изображений и упростить чтение существующих + удалить много кода, @pingDino
Я действительно могу отправлять десятичные значения вместо шестнадцатеричных (умопомрачительных). Плата, с которой я работаю, может принимать только 8 бит данных одновременно, поэтому для отправки десятичной дроби "799" я сначала отправляю "3", а затем
31
(3*256 + 31). Зная это, я сумею радикально очистить код. Я просто напишу новый метод, который разбивает десятичное значение, которое я отправляю, на пару меньших десятичных значений. Спасибо StarCat и jsotola, @pingDino