int на Uno более 16 бит?
Итак, я играю с TFT-экраном и пытаюсь понять кодировку цветового пространства . Я написал быстрый цикл for
, чтобы показывать цвета от 0 до FFFF и печатать значение отображаемого цвета:
for (int q=0; q<0xFFFF; q+=0x80) {
tft.fillScreen(q);
tft.setCursor(0, 0); tft.println(q, HEX);
delay(2);
}
Я был удивлен, обнаружив отображаемые значения, превышающие FFFF, что предполагает, что int
имеет длину более 16 бит. Он работает на Uno.
Что случилось?
(PS теперь я понимаю кодировку RGB565, так что это не по теме)
@Socco, 👍0
Обсуждение1 ответ
Думаю, вы видите большие цифры, начинающиеся с FFFF...?
Вы видите не большие цифры, а искаженные цифры.
У вас есть int
. Это не «16-битное число», это 15-битное число плюс знаковый бит.
При печати переменная повышается до long
, а знаковый бит расширяется.
Этот long
затем преобразуется (приводится) в unsigned long
для печати его в шестнадцатеричном виде (в шестнадцатеричном представлении Arduino нет отрицательного значения), и это бит расширенного знака рассматривается как строка F.
Например, значение 0xABCD, хранящееся в int
, имеет вид:
1 010 1011 1100 1101
Я отломил первый бит, потому что это бит знака в знаковом целом. Фактическое десятичное значение составляет -21555.
Теперь, когда оно преобразуется в длинное значение, расширение знака копирует ведущий бит знака во все остальные 16 бит слева от него, в результате чего:
1 111 1111 1111 1111 1010 1011 1100 1101
Из-за особенностей работы дополнения до двух эта строка битов по-прежнему представляет -21555 в десятичном формате.
Однако приведите его к unsigned long
для печати в формате HEX, и вы увидите, что в итоге вы получите большие числа. Это даст вам:
FFFFABCD
Итак, вы можете видеть, что 16-битное знаковое значение может быть напечатано как 8 шестнадцатеричных цифр, и все из-за того, как работает функция print()
в API Arduino.
При работе с беззнаковыми значениями вам действительно следует работать с беззнаковой переменной, особенно если эти беззнаковые значения (0–65535) выходят за пределы диапазона типа знаковой переменной (-32768–32767). Переключитесь на использование uint16_t
, и вы сможете правильно хранить и представлять значения.
Возможно, вам будет полезно поэкспериментировать с этим сайтом, чтобы узнать, как различные типы переменных представляют и хранят в себе данные в двоичном виде.
Спасибо за подробное объяснение @Majko - для меня весьма информативно. (1) Однако на дисплее не отображаются ведущие FFFFF - например, теперь отображается 26C E000
. (2) Я предполагаю, что цикл for
никогда не завершится, потому что 0xFFFF всегда будет больше, чем оценка максимального знакового int = 0x7FFF - (3) Но это все равно не объясняет, почему на дисплее отображаются числа, разрядность которых превышает 16 бит, это предполагает, что команде печати присвоено число больше 16 бит. (4) Uno - это китайский клон, полученный с другим железом - так может это актуально?, @Socco
Это не потому, что это китайский клон — это все равно то же программное обеспечение, работающее на том же процессоре, даже если оно из мусорной корзины. Ваш цикл определенно никогда не закончится. Вам следует перейти на беззнаковое значение, которое больше максимального значения цикла. Вместо этого используйте uint32_t для своего цикла, а затем приведите его к uint16_t для значения цвета., @Majenko
- Какую скорость передачи данных com порта можно использовать без ошибок?
- Насколько холодным или горячим может быть Arduino Uno?
- Как почувствовать, когда кто-то спит с моим Arduino?
- Различия между Arduino Uno SMD и Uno DIP
- Использование кнопки для поворота шагового двигателя на 90 градусов.
- Разбор HTML-запроса GET с параметрами с помощью WiFiEsp
- RGB светодиодная лента 100м.
- Разница в загрузчике между Atmel328p (сквозное отверстие) и Atmel328p au (smd)
Сокко, закроем этот вопрос? В следующий раз начните с того, что сообщите нам, какой у вас TFT-экран и что вы используете библиотеку adafruit gfx, и, если возможно, покажите рабочий эскиз. tft.fillScreen имеет беззнаковый 16-битный параметр. Значение выше 0xFFFF переносится и снова начинается с 0x0000., @Jot