Вы правильно указали на место, при таком исполнении массив выводится правильно:
Код:
if ((b << j) & 0x8008000) {
for (yy = 0; yy < multiplier; yy++){ for (xx = 0; xx < multiplier; xx++){ ST7789_DrawPixel(X+xx, Y+yy, TextColor); } }
}
Если честно, я не до конца понял почему именно 8000 и 8008000. Почему, например не 0xFFFF. Если знаете, буду благодарен за объяснение. В любом случае Вам спасибо, что помогли. Я еще прогоню это на шрифте, чтобы убедиться, что все корректно работает. Так как это пока просто тест на 0x0000 и 0xFFFF. Как на шрифте он себя покажет надо пробовать. Ну ввиду того, что ранее писали про попиксельный вывод. Я понимаю, что это не совсем хорошо. Ввиду этого есть ли смысл перейти на этот пример? https://github.com/Floyd-Fish/ST7789-ST ... 9/st7789.c Там очень похожие функции
наверное, я опечатался. правильно 8000 и 80000000 - это просто маска для проверки старшего бита. 0х8000 для uint_16 и 0х80000000 для uint_32 если число, например, 0х9828, и маску 0х8000 представить в двоичном виде, и сделать логическую операцию AND (в Си - &), то 1001100000101000 // 0х9828 & 1000000000000000 // 0х8000 = 1000000000000000
Добавлено after 11 minutes 42 seconds: насчёт смысла перехода на другой пример... ну, в теории, конечно, есть, если там используется DMA, заполнение областей памяти и т.д. Но я бы советовал сначала изучить основы. Раз есть сложности с размерностью данных и логическими операциями, то это надо устранить. В общем, надо прочесть книжку(и) по языку, алгоритмам, микроконтроллерам и т. д.
Для простоты оставил первый символ сгенерированного шрифта, а именно пробел - " ". Но заполнил его чередующимися 0 и 1. По сути на дисплей должен вывестись прямоугольник из полосок размером 32 на 48 пикселей (соотношение сторон 2 : 3).
Но на дисплее я получаю прямоугольник ровно в 2 раза уже, чем тот, что должен быть, соотношение сторон 1 : 3. Не могу найти причину данного поведения. Может у кого есть догадки?
Шрифт какой - пропорциональный или моноширинный? Если шрифт - пропорциональный, то где-то в нём для каждого символа должна задаваться ширина (а также: базовая линия и может ещё какая инфа). И чтобы изменить вид какого-то символа, недостаточно изменить его битмап. Нужно изменить ширину и базовую линию. Символ пробела в пропорциональных шрифтах обычно бывает очень узким. Возможно у вас выводит новый битмап, но со старой шириной.
Приглашаем 3 декабря 2024 на вебинар, посвященный силовым модулям ведущего китайского производителя SUNCO - одного из мировых лидеров по производству дискретных полупроводниковых компонентов. На вебинаре вы узнаете о новинках, включая модули 17 класса в корпусе E3, и контроле качества на всех этапах производства. Вы также узнаете о новейших продуктах – IGBT-, SiC-, диодных и тиристорных модулях, погрузитесь в современные топологии, сравните характеристики IGBT-чипов разных поколений.
правильно будет 16 бит, и ((b << j) & 0x8008000) ... DMA не проблема
Полагаю, тому, кто легко справляется с DMA, мои детские подсказки не нужны и смешны. Но рискну заметить очевидное: в 0x8008000 три с половиной байта и два установленных бита.
Добавлено after 1 minute 39 seconds: jcxz, ТС выводит uint_16t, сдвигая его 32 раза. До пропорциональный или моноширинный там далеко...
Всплески перенапряжения являются серьезной угрозой надежности работы радиоэлектронных устройств. Причины их появления различны, это могут быть коммутационные переходные процессы в системе электропитания устройств, разряды молний, электростатические разряды. Для создания эффективной и современной системы защиты от ЭСР компания SUNCO разработала надежные и качественные супрессоры, представляющие собой TVS- и ESD-диоды, а также сборки на их основе. Компоненты SUNCO не только не уступают, но часто превосходят по характеристикам аналогичную продукцию других брендов.
Полагаю, тому, кто легко справляется с DMA, мои детские подсказки не нужны и смешны.
Ну DMA попроще... Нет? Ну, возможно, это просто для меня так.
jcxz писал(а):
ТС выводит uint_16t, сдвигая его 32 раза. До пропорциональный или моноширинный там далеко...
Ну смотрите, если взять 32 битный массив, то он все равно тогда отображает 1 значение массива в 2 строки. Если взять if ((b << j) & 0x8000000) то будет отображаться половина массива. Почему тогда так? Я на тексте пока не пробовал, может там ошибки полезут. Но пока на массиве из полосок результат такой
что такое "32 битный массив"? Массив, где каждый элемент типа uint32_t? У Вас не такой. У Вас каждый элемент uint16_t поясню ещё раз но чтобы меньше писать, поделю на два. Предположим, есть массив uint8_t a [] = {0x2b, 0x42); Каждый элемент Вы сдвигаете 16 раз: первый элемент (далее количество сдвига, точка, двоичное представление): 0. 00101011 1. 01010110 2. 10101100 3. 01011000 4. 10110000 5. 01100000 6. 11000000 7. 10000000 8. 00000000 9. 00000000 a. 00000000 b. 00000000 c. 00000000 d. 00000000 e. 00000000 f. 00000000
Понятно? Последние 8 операций у Вас нет информации, только ноль, и Вы в нуле проверяете восемь раз, нет ли там единицы? конечно нет. В Вашем коде тоже самое, только 16 бит в числах и 32 сдвига, потому что в массиве 16-битные числа, а сдвиг задаёте равным ширине символа
Кому надо будет вывести большой шрифт на данном дисплее, можно воспользоваться данным примером https://github.com/Floyd-Fish/ST7789-ST ... 9/st7789.c Только я добавил шрифты и совсем немного изменил функцию их вывода
// LCD BACKLIGHT SET HAL_GPIO_WritePin(BLK_GPIO_Port, BLK_Pin, GPIO_PIN_SET);
Для генерации шрифтов использовал matrixFont-x64-Portable, для правильного вывода шрифта надо подобрать настройки генерации.
Была некая проблема, дисплей не всегда запускался, уменьшение скорости SPI и увеличение задержек при запуске результатов не дало. Помогло дублирование функции инициализации ST7789_Init(); через задержку. Как это можно исправить не знаю.
С SPI тоже есть неоднозначность, настройки из большинства примеров не подошли, их тоже надо подбирать под дисплей. По-моему какая-то одна, вроде на какой фронт клока считывать байты
Была некая проблема, дисплей не всегда запускался, уменьшение скорости SPI и увеличение задержек при запуске результатов не дало. Помогло дублирование функции инициализации ST7789_Init(); через задержку. Как это можно исправить не знаю.
Рабочая инициализация для вот этого дисплея: Спойлер
Код:
const uint16_t LCD_regValues[] = { 0x0111, // Sleep out 0xF80C, // Delay ~12ms 0x013A, 0x0055, // Set interface mode: 65k RGB color / 16 bit/px 0x0136, 0x0000, // Memory write control // 0x012B, 0x0000, 0x0014, 0x0001, 0x002B, // Row address set: 0..279 (20..299) - Full screen 0x012B, 0x0000, 0x0000, 0x0000, 0x00EF, // Row address set: 0..239 - Full screen 0x0130, 0x0000, 0x0000, 0x0000, 0x00EF, // Display area is 0..239 0x0121, // Inversion: ON // 0x0113, // Normal display on 0x0112, // Partial display on 0x0129 // Display on };
void SPI_Send_8(uint8_t Value) { *(volatile uint8_t *)&(SPI1->DR) = Value; while (!(SPI1->SR & SPI_SR_TXE)) {}; while (SPI1->SR & SPI_SR_BSY) {}; }
void LCD_Init(void) { unsigned int i; uint16_t v;
GPIOF->BSRR = GPIO_BSRR_BR_1; // LCD /RST pin Down delay_ms(2); GPIOF->BSRR = GPIO_BSRR_BS_1; // LCD /RST pin UP delay_ms(20);
for (i=0;i<sizeof(LCD_regValues)/2;i++) { v = LCD_regValues[i]; if (v >= 0xF800) { delay_ms(v & 0x7FF); } else { if (v & 0x0100) { LCD_DC_SET(); } else { LCD_DC_UNSET(); } SPI_Send_8(v & 0xFF); } } }
Дисплей в даташите ТРЕБУЕТ задержки после Soft-Reset'а Ну и аппаратный сброс выполняется тоже по таймингам. Инициализируется каждый раз. Закомментированные строки - от другого дисплея на этом же чипе.
После функции LCD_Init() в памяти дисплея мусор и его нужно переписать своим изображением. Лично я заливаю нулями для получения чёрного фона.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения