Вывод текста на дисплей ST7789

Кто любит RISC в жизни, заходим, не стесняемся.
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Вывод текста на дисплей ST7789

Сообщение DmitryR »

[uquote="Martian",url="/forum/viewtopic.php?p=4596545#p4596545"]

Код: Выделить всё

 for (j = 0; j < Font->FontWidth; j++) {

         if ((b << j) & 0x8000) {
[/uquote]

Вы правильно указали на место, при таком исполнении массив выводится правильно:

Код: Выделить всё

			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
Там очень похожие функции
Реклама
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Вывод текста на дисплей ST7789

Сообщение Martian »

DmitryR писал(а): почему именно 8000 и 8008000.
наверное, я опечатался. правильно 8000 и 80000000 - это просто маска для проверки старшего бита. 0х8000 для uint_16 и 0х80000000 для uint_32
если число, например, 0х9828, и маску 0х8000 представить в двоичном виде, и сделать логическую операцию AND (в Си - &), то
1001100000101000 // 0х9828
&
1000000000000000 // 0х8000
=
1000000000000000

так как: http://informatika7.adu.by/?page_id=165

Добавлено after 11 minutes 42 seconds:
насчёт смысла перехода на другой пример... ну, в теории, конечно, есть, если там используется DMA, заполнение областей памяти и т.д. Но я бы советовал сначала изучить основы. Раз есть сложности с размерностью данных и логическими операциями, то это надо устранить. В общем, надо прочесть книжку(и) по языку, алгоритмам, микроконтроллерам и т. д.
Реклама
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Вывод текста на дисплей ST7789

Сообщение DmitryR »

[uquote="Martian",url="/forum/viewtopic.php?p=4596553#p4596553"]
DmitryR писал(а): почему именно 8000 и 8008000.
наверное, я опечатался. правильно 8000 и 80000000 - это просто маска для проверки старшего бита. 0х8000 для uint_16 и 0х80000000 для uint_32[/uquote]
не совсем, получается, что правильно будет 16 бит, и ((b << j) & 0x8008000)

Ну я его запускал, в целом там все так же. DMA не проблема
jcxz
Мудрый кот
Сообщения: 1717
Зарегистрирован: Вт авг 15, 2017 10:51:13

Re: Вывод текста на дисплей ST7789

Сообщение jcxz »

[uquote="DmitryR",url="/forum/viewtopic.php?p=4595962#p4595962"]Для простоты оставил первый символ сгенерированного шрифта, а именно пробел - " ". Но заполнил его чередующимися 0 и 1. По сути на дисплей должен вывестись прямоугольник из полосок размером 32 на 48 пикселей (соотношение сторон 2 : 3).

Но на дисплее я получаю прямоугольник ровно в 2 раза уже, чем тот, что должен быть, соотношение сторон 1 : 3. Не могу найти причину данного поведения. Может у кого есть догадки?[/uquote]Шрифт какой - пропорциональный или моноширинный?
Если шрифт - пропорциональный, то где-то в нём для каждого символа должна задаваться ширина (а также: базовая линия и может ещё какая инфа). И чтобы изменить вид какого-то символа, недостаточно изменить его битмап. Нужно изменить ширину и базовую линию.
Символ пробела в пропорциональных шрифтах обычно бывает очень узким. Возможно у вас выводит новый битмап, но со старой шириной.
Реклама
Эиком - электронные компоненты и радиодетали
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Вывод текста на дисплей ST7789

Сообщение Martian »

DmitryR писал(а):правильно будет 16 бит, и ((b << j) & 0x8008000)
... DMA не проблема
Полагаю, тому, кто легко справляется с DMA, мои детские подсказки не нужны и смешны.
Но рискну заметить очевидное: в 0x8008000 три с половиной байта и два установленных бита.

Добавлено after 1 minute 39 seconds:
jcxz, ТС выводит uint_16t, сдвигая его 32 раза. До пропорциональный или моноширинный там далеко...
Реклама
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Вывод текста на дисплей ST7789

Сообщение DmitryR »

[uquote="jcxz",url="/forum/viewtopic.php?p=4596579#p4596579"]Шрифт какой - пропорциональный или моноширинный?[/uquote]
Моноширинный
jcxz писал(а):Полагаю, тому, кто легко справляется с DMA, мои детские подсказки не нужны и смешны.
Ну DMA попроще... Нет? Ну, возможно, это просто для меня так.
jcxz писал(а):ТС выводит uint_16t, сдвигая его 32 раза. До пропорциональный или моноширинный там далеко...
Ну смотрите, если взять 32 битный массив, то он все равно тогда отображает 1 значение массива в 2 строки. Если взять if ((b << j) & 0x8000000) то будет отображаться половина массива. Почему тогда так?
Я на тексте пока не пробовал, может там ошибки полезут. Но пока на массиве из полосок результат такой
Реклама
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Вывод текста на дисплей ST7789

Сообщение Martian »

что такое "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-битные числа, а сдвиг задаёте равным ширине символа
DmitryR
Встал на лапы
Сообщения: 100
Зарегистрирован: Ср авг 31, 2022 12:10:34

Re: Вывод текста на дисплей ST7789

Сообщение DmitryR »

Кому надо будет вывести большой шрифт на данном дисплее, можно воспользоваться данным примером
https://github.com/Floyd-Fish/ST7789-ST ... 9/st7789.c
Только я добавил шрифты и совсем немного изменил функцию их вывода

Код: Выделить всё

#define BG_COLOR   				0x1234				
#define TEXT_COLOR   			0x5678				
#define NUM_COLOR   			0x5678	

#define BLK_Pin GPIO_PIN_11
#define BLK_GPIO_Port GPIOA
//#define DC_Pin GPIO_PIN_3
//#define DC_GPIO_Port GPIOA
//#define RES_Pin GPIO_PIN_2
//#define RES_GPIO_Port GPIOA	

Код: Выделить всё

// START DELAY
HAL_Delay(250);

// LCD BACKLIGHT RESET
HAL_GPIO_WritePin(BLK_GPIO_Port, BLK_Pin, GPIO_PIN_RESET);

// LCD START
ST7789_Init();
ST7789_Fill_Color(BG_COLOR);

ST7789_WriteChar_64_96(15, 15, '0', Font_64x96, NUM_COLOR, BG_COLOR);
ST7789_WriteChar_64_96(75, 15, '0', Font_64x96, NUM_COLOR, BG_COLOR);

ST7789_WriteChar_32_48(150, 20, '0', Font_32x48, NUM_COLOR, BG_COLOR);
ST7789_WriteChar_32_48(185, 20, '0', Font_32x48, NUM_COLOR, BG_COLOR);

ST7789_WriteChar_24_32(175, 70, '0', Font_24x32, TEXT_COLOR, BG_COLOR);
ST7789_WriteChar_24_32(150, 70, '0', Font_24x32, TEXT_COLOR, BG_COLOR);
ST7789_WriteChar_24_32(195, 70, '0', Font_24x32, TEXT_COLOR, BG_COLOR);

// LCD BACKLIGHT SET
HAL_GPIO_WritePin(BLK_GPIO_Port, BLK_Pin, GPIO_PIN_SET);
Для генерации шрифтов использовал matrixFont-x64-Portable, для правильного вывода шрифта надо подобрать настройки генерации.

Была некая проблема, дисплей не всегда запускался, уменьшение скорости SPI и увеличение задержек при запуске результатов не дало. Помогло дублирование функции инициализации ST7789_Init(); через задержку. Как это можно исправить не знаю.

С SPI тоже есть неоднозначность, настройки из большинства примеров не подошли, их тоже надо подбирать под дисплей. По-моему какая-то одна, вроде на какой фронт клока считывать байты
Вложения
St7789.rar
(12.44 КБ) 123 скачивания
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: Вывод текста на дисплей ST7789

Сообщение AlanDrakes »

[uquote="DmitryR",url="/forum/viewtopic.php?p=4614827#p4614827"]Была некая проблема, дисплей не всегда запускался, уменьшение скорости SPI и увеличение задержек при запуске результатов не дало. Помогло дублирование функции инициализации ST7789_Init(); через задержку. Как это можно исправить не знаю.[/uquote]

Рабочая инициализация для вот этого дисплея:
Спойлер

Код: Выделить всё

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() в памяти дисплея мусор и его нужно переписать своим изображением. Лично я заливаю нулями для получения чёрного фона.

SPI инициализируется минимально:

Код: Выделить всё

<...>
	RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_ADC1EN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_SYSCFGEN;
	SPI1->CR1 = SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE | SPI_CR1_MSTR;
	SPI1->CR2 = SPI_CR2_NSSP | SPI_CR2_SSOE | (7 << 8);	// 8 bit, NO DMA, SSE pin enable, output.
	SPI1->CR1 |= SPI_CR1_SPE;		// + Channel enabled.
<...>
Ответить

Вернуться в «ARM»