Медленный вывод на STM32 8 битной шины (дисплей)

Кто любит RISC в жизни, заходим, не стесняемся.
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

Здравствуйте!

Я переписал код, который был написан AVR по управлению в "ручную" 8 битной шиной для управления дисплеем IVI9488 при помощи платы nucleo с ST32F103RB. У меня дисплей 420*380, в уроке был 320*240. Да я понимаю, что у меня значительно большее идет данных по шине, но на AVR из цвета в цвет переходил ну практически моментально, а у меня закрашивается наверное около секунды. В чем может быть проблема?

Из-за того что я использую Nucleo64 с дисплейным шилдом, то все выводы раскиданы аж по 3 портам, поэтому написано всечерез функции с применением библиотеки HAL. Может ли это значительно уменьшать скорость ?

Изменение скорости тактирования порта с LOW на HIGH существенно ничего не меняет.
Прикладываю только файл *.cpp , думаю *.h с заголовками тут не поможет. в main.c тоже только TFT9488_ini(); да TFT9488_FillScreen(); с другими необходимыми для запуска nucleo командами

Знаю что у меня есть DMA и это может дать прирост в скорости, но я не пока не умею им пользоваться и как мне кажется, STM32 должна опережать по скорости Atmega8 , даже без использования DMA...

Так же проверял этот код на гораздо более скоростной плате f469i-disco скорость отображения 1в1 такая же как и на f103RB

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

/*
 * ili9488.c
 *
 *  Created on: Mar 14, 2022
 *      Author: AVerzin
 */
#include "ili9488.h"

unsigned int X_SIZE = 320;

unsigned int Y_SIZE = 480;

unsigned long dtt = 0;
// что нужно доделать

// чтобы было незаметно глазу обновление экрана он это должен делать быстрее чем за
// 1с / 25 кадров в секунду = 0,04 секунды = 40 миллисекунд = 40 000 микросекунд

// сделать функцию перевода портов линии данных из состояния чтения в состояние вывода
// убрать упоминание портов во всех функицях, сделать все на метках DATA,CS и тп (+)
// отладить функцию чтения портов линии данных (+)
// сделать функцию чтения из регистров LCD (+)
// прочитать ID LCD (!!!!) (+)

// Функция установки нужных уровней на линии выбора дисплея PORTC4
void TFT9488_CS_Active(void) {
	HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, RESET);
}
void TFT9488_CS_Idle(void) {
	HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, SET);
}

// Функции установки состояния ножки RESET PORTC5
void TFT9488_RESET_Active(void) {
	HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, RESET);
}
void TFT9488_RESET_Idle(void) {
	HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, SET);
}

// Функции установки состояния ножки отвечающей за строб, о том что данные готовы к считыванию
// PORTC2
void TFT9488_WR_Active(void) {
	HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, RESET);
}
void TFT9488_WR_Idle(void) {
	HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, SET);
}

// Функции установки состояния ножки если уровень низкий то мы читаем данные из LCD
// PORTB2
void TFT9488_RD_Active(void) {
	HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, RESET);
}
void TFT9488_RD_Idle(void) {
	HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, SET);
}

// Функции установки состояния ножки отвечающий за то что будет передаваться данные или команда
// PORTС3
void TFT9488_RS_Command(void) {
	HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, RESET);
}
void TFT9488_RS_Data(void) {
	HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, SET);
}

// Функция чтения данных из портов на линии данных
char TFT9488_Port_Read(void) {
	char dt;									// переменнная для чтения данных
	TFT9488_Set_Port_Read();		// Установка портов линии даннных на чтение

	// чтение данных с портов линии данных начиная со старшего бита
	dt = HAL_GPIO_ReadPin(DATA7_GPIO_Port, DATA7_Pin);	// прочитали бит с пина
	dt <<= 1;									// сдвинули влево на 1 разряд
	dt |= HAL_GPIO_ReadPin(DATA6_GPIO_Port, DATA6_Pin);	// прочитали следующий пин и присоединили его к dt
	dt <<= 1;
	dt |= HAL_GPIO_ReadPin(DATA5_GPIO_Port, DATA5_Pin);
	dt <<= 1;
	dt |= HAL_GPIO_ReadPin(DATA4_GPIO_Port, DATA4_Pin);
	dt <<= 1;
	dt |= HAL_GPIO_ReadPin(DATA3_GPIO_Port, DATA3_Pin);
	dt <<= 1;
	dt |= HAL_GPIO_ReadPin(DATA2_GPIO_Port, DATA2_Pin);
	dt <<= 1;
	dt |= HAL_GPIO_ReadPin(DATA1_GPIO_Port, DATA1_Pin);
	dt <<= 1;
	dt |= HAL_GPIO_ReadPin(DATA0_GPIO_Port, DATA0_Pin);

	TFT9488_Set_Port_Write();// Возврат портов линии данных на запись, так как этот режим применяется чаще соответственно он должен быть по умолчанию

	return (dt);
}

// Функция записи данных в порты на линию данных
void TFT9488_Port_Write(char dt) {
	// смысл этого (dt & 0b10000000)?1:0 в следующем. это тернарная операция if
	// мы смотрим, есть ли в старшем бите dt единица и если она есть, то выдаем 1
	// если в старшем бите 0, соотвественно выводим 0.
	HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, (dt & 0b10000000) ? 1 : 0);
	HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, (dt & 0b01000000) ? 1 : 0);
	HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, (dt & 0b00100000) ? 1 : 0);
	HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, (dt & 0b00010000) ? 1 : 0);
	HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, (dt & 0b00001000) ? 1 : 0);
	HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, (dt & 0b00000100) ? 1 : 0);
	HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, (dt & 0b00000010) ? 1 : 0);
	HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, (dt & 0b00000001) ? 1 : 0);
}

// Функция которая дает строб, который говорит что данные готовы
void TFT9488_WR_Strobe(void) {
	TFT9488_WR_Active();
	TFT9488_WR_Idle();
}

//—————————————————————

void TFT9488_SendCommand(unsigned char cmd) {
	TFT9488_RS_Command(); 		//лапка в состоянии посылки команды
	TFT9488_RD_Idle();			//отключим чтение
	TFT9488_CS_Active();			//подали команду LCD чтобы он начал слушать
	TFT9488_Port_Write(cmd);		//выставили на нужных ножках данные
	TFT9488_WR_Strobe();			//подаем строб, чтобы LCD забрал данные
	TFT9488_CS_Idle();			//подаем команду на прекращение слушания LCD
}

//—————————————————————

void TFT9488_SendData(unsigned char dt) {
	TFT9488_RS_Data();			//лапка в состоянии посылки данных
	TFT9488_RD_Idle();			//отключим чтение
	TFT9488_CS_Active(); 			//выбор дисплея
	TFT9488_Port_Write(dt);
	TFT9488_WR_Strobe();
	TFT9488_CS_Idle();
}

//—————————————————————

void TFT9488_reset(void) {

	TFT9488_CS_Idle();
	TFT9488_WR_Idle();
	TFT9488_RD_Idle();
	TFT9488_RESET_Active();
	HAL_Delay(2);
	TFT9488_RESET_Idle();
	TFT9488_CS_Active();
	TFT9488_SendCommand(0x01); //Software Reset
	for (uint8_t i = 0; i < 3; i++)
		TFT9488_WR_Strobe();
	TFT9488_CS_Idle();
}
//—————————————————————

void TFT9488_Write8(unsigned char dt) {
	TFT9488_Port_Write(dt);
	TFT9488_WR_Strobe();
}

//—————————————————————

unsigned long TFT9488_ReadReg(unsigned char r) {
	unsigned long id;
	unsigned char x;
	TFT9488_CS_Active(); //выбор дисплея
	TFT9488_RS_Command(); //лапка в состоянии посылки команды
	TFT9488_Write8(r);
	TFT9488_Set_Port_Read();
	TFT9488_RS_Data();
//	_delay_us(50);

	HAL_Delay(1);
	TFT9488_RD_Active();
//	_delay_us(5);
	HAL_Delay(1);
	x = TFT9488_Port_Read();

	TFT9488_RD_Idle();
	id = x;
	id <<= 8;
	TFT9488_RD_Active();

//	_delay_us(5);
	HAL_Delay(1);
	x = TFT9488_Port_Read();
	TFT9488_RD_Idle();
	id |= x;
	id <<= 8;
	TFT9488_RD_Active();

//	_delay_us(5);
	HAL_Delay(1);
	x = TFT9488_Port_Read();
	TFT9488_RD_Idle();
	id |= x;
	id <<= 8;
	TFT9488_RD_Active();

//	_delay_us(5);
	HAL_Delay(1);
	x = TFT9488_Port_Read();
	TFT9488_RD_Idle();
	id |= x;
	if (r == 0xEF) {
		id <<= 8;
		TFT9488_RD_Active();
//		_delay_us(5);
		HAL_Delay(1);
		x = TFT9488_Port_Read();
		TFT9488_RD_Idle();
		id |= x;
	}
	TFT9488_CS_Idle();
	TFT9488_Set_Port_Write();
//	_delay_us(150);//stabilization time
	HAL_Delay(2);

	return (id);
}

//—————————————————————
// Функции настройки портов к котормы подключены линии данных на чтение или запись
// линии данных подключены к портам G и A
void TFT9488_Set_Port_Read(void) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };
	// Каждый пин расписан индивидуально, без обьединенений для того чтобы при перенеосе этой библиотеки
	// нужно было менять пины и порты только в файле .h

	/*Configure GPIO pins : DATA7_Pin*/
	GPIO_InitStruct.Pin = DATA7_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA7_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA6_Pin*/
	GPIO_InitStruct.Pin = DATA6_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA6_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA5_Pin*/
	GPIO_InitStruct.Pin = DATA5_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA5_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA4_Pin*/
	GPIO_InitStruct.Pin = DATA4_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA4_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA3_Pin*/
	GPIO_InitStruct.Pin = DATA3_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA3_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA2_Pin*/
	GPIO_InitStruct.Pin = DATA2_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA2_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA1_Pin*/
	GPIO_InitStruct.Pin = DATA1_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA1_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA0_Pin*/
	GPIO_InitStruct.Pin = DATA0_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(DATA0_GPIO_Port, &GPIO_InitStruct);
}

void TFT9488_Set_Port_Write(void) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, GPIO_PIN_SET);

	/*Configure GPIO pins : DATA7_Pin*/
	GPIO_InitStruct.Pin = DATA7_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA7_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA6_Pin*/
	GPIO_InitStruct.Pin = DATA6_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA6_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA5_Pin*/
	GPIO_InitStruct.Pin = DATA5_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA5_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA4_Pin*/
	GPIO_InitStruct.Pin = DATA4_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA4_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA3_Pin*/
	GPIO_InitStruct.Pin = DATA3_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA3_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA2_Pin*/
	GPIO_InitStruct.Pin = DATA2_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA2_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA1_Pin*/
	GPIO_InitStruct.Pin = DATA1_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA1_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : DATA0_Pin*/
	GPIO_InitStruct.Pin = DATA0_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(DATA0_GPIO_Port, &GPIO_InitStruct);

}

// конфигурирование портов данных и управления
void TFT9488_Port_ini(void) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();

	// Конфигурирование начальных уровней, в высокое положение
	HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(WR_GPIO_Port, WR_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(RD_GPIO_Port, RD_Pin, GPIO_PIN_SET);

	/*Configure GPIO pins : RS_Pin*/
	GPIO_InitStruct.Pin = RS_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(RS_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : WR_Pin*/
	GPIO_InitStruct.Pin = WR_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(WR_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : CS_Pin */
	GPIO_InitStruct.Pin = CS_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(CS_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : RST_Pin */
	GPIO_InitStruct.Pin = RST_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(RST_GPIO_Port, &GPIO_InitStruct);

	/*Configure GPIO pins : RD_pin */
	GPIO_InitStruct.Pin = RD_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(RD_GPIO_Port, &GPIO_InitStruct);

	TFT9488_Set_Port_Write();
}

// Функция установки ориентации дисплея
/*
 * 0 — вертикальная обычная ориентация
 1 — горизонтальная обычная ориентация
 2 — вертикальная перевёрнутная ориентация
 3 — горизонтальная перевёрнутная ориентация.
 *
 */
void TFT9488_SetRotation(unsigned char r) {
	TFT9488_SendCommand(0x36);
	switch (r) {
	case 0:
		TFT9488_SendData(0x48);
		X_SIZE = 320;
		Y_SIZE = 480;
		break;
	case 1:
		TFT9488_SendData(0x28);
		X_SIZE = 480;
		Y_SIZE = 320;
		break;
	case 2:
		TFT9488_SendData(0x88);
		X_SIZE = 320;
		Y_SIZE = 480;
		break;
	case 3:
		TFT9488_SendData(0xE8);
		X_SIZE = 480;
		Y_SIZE = 320;
		break;
	}
}

// Функция заливки области
void TFT9488_Flood(unsigned short color, unsigned long len)
{
	unsigned short blocks;
	unsigned char i, hi = color>>8, lo=color;
	TFT9488_CS_Active();
	TFT9488_RS_Command();
	TFT9488_Write8(0x2C);
	TFT9488_RS_Data();
	TFT9488_Write8(hi);
	TFT9488_Write8(lo);
	len--;
	blocks=(unsigned short)(len/64);//64 pixels/block
	if (hi==lo)
	{
		while(blocks--)
		{
			i=16;
			do
			{
				TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();//2bytes/pixel
				TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();TFT9488_WR_Strobe();//x4 pixel
			} while (--i);
		}
		//Fill any remaining pixels(1 to 64)
		for (i=(unsigned char)len&63;i--;)
		{
			TFT9488_WR_Strobe();
			TFT9488_WR_Strobe();
		}
	}
	else
	{
		while(blocks--)
		{
			i=16;
			do
			{
				TFT9488_Write8(hi);TFT9488_Write8(lo);TFT9488_Write8(hi);TFT9488_Write8(lo);
				TFT9488_Write8(hi);TFT9488_Write8(lo);TFT9488_Write8(hi);TFT9488_Write8(lo);
			} while (--i);
		}
		//Fill any remaining pixels(1 to 64)
		for (i=(unsigned char)len&63;i--;)
		{
			TFT9488_Write8(hi);
			TFT9488_Write8(lo);
		}
	}
	TFT9488_CS_Idle();
}

// Функция записи в регистр 32 числа
void TFT9488_WriteRegister32(unsigned char r, unsigned long d)
{
	TFT9488_CS_Active();
	TFT9488_RS_Command();
	TFT9488_Write8(r);
	TFT9488_SendData;
	HAL_Delay(1);
	TFT9488_Write8(d>>24);
	HAL_Delay(1);
	TFT9488_Write8(d>>16);
	HAL_Delay(1);
	TFT9488_Write8(d>>8);
	HAL_Delay(1);
	TFT9488_Write8(d);
	TFT9488_CS_Idle();
}
/*
 * прежде чем отправлять в память байты, нам нужно объявить область памяти, в которую будет вся наша цепочка одинаковых пикселей отправляться. Для этого мы напишем специальную функцию
 */
void TFT9488_SetAddrWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
	unsigned long t;
	TFT9488_CS_Active();
	TFT9488_SendCommand(0x2A);

	TFT9488_SendData(x1 >> 8);
	TFT9488_SendData(x1 & 0xFF);     // XSTART
	TFT9488_SendData(x2 >> 8);
	TFT9488_SendData(x2 & 0xFF);     // XEND

	TFT9488_SendCommand(0x2C);
	TFT9488_SendData(y1>>8);
	TFT9488_SendData(y1 &0xff);     // YSTART
	TFT9488_SendData(y2>>8);
	TFT9488_SendData(y2 &0xff);     // YEND

	TFT9488_SendCommand(0x2C); // write to RAM

	//t = x1;
	//t<<=16;
	//t |= x2;
	//TFT9488_WriteRegister32(0x2A,t);//Column Addres Set
	//t = y1;
	//t<<=16;
	//t |= y2;
	//TFT9488_WriteRegister32(0x2B,t);//Page Addres Set

	TFT9488_CS_Idle();
}

void TFT9488_FillScreen(unsigned int color)
{
	TFT9488_SetAddrWindow(0,0,X_SIZE-1,Y_SIZE-1);
	TFT9488_Flood(color,(long)X_SIZE*(long)Y_SIZE);
}

// Заливка прямоугольника
void TFT9488_FillRectangle(unsigned int color,unsigned int x1, unsigned int y1,
							 unsigned int x2, unsigned int y2)
{
	TFT9488_SetAddrWindow(x1, y1, x2, y2);
	TFT9488_Flood(color, (long)(x2-x1+1) * (long)(y2-y1+1));
}

void TFT9488_ini(void) {
	TFT9488_Port_ini();
	TFT9488_reset();
	HAL_Delay(1000);
	dtt = TFT9488_ReadReg(0xD3);
	TFT9488_CS_Active();


	//Software Reset
	TFT9488_SendCommand(0x01);


	// Display OFF
	TFT9488_SendCommand(0x28);

	// Positive Gamma Correction
	 TFT9488_SendCommand(0xE0);
	TFT9488_SendData(0x00);
	TFT9488_SendData(0x03);
	TFT9488_SendData(0x09);
	TFT9488_SendData(0x08);
	TFT9488_SendData(0x16);
	TFT9488_SendData(0x0A);
	TFT9488_SendData(0x3F);
	TFT9488_SendData(0x78);
	TFT9488_SendData(0x4C);
	TFT9488_SendData(0x09);
	TFT9488_SendData(0x0A);
	TFT9488_SendData(0x08);
	TFT9488_SendData(0x16);
	TFT9488_SendData(0x1A);
	TFT9488_SendData(0x0F);

	//Negative Gamma  Correction
	TFT9488_SendCommand(0XE1);
	TFT9488_SendData(0x00);
	TFT9488_SendData(0x16);
	TFT9488_SendData(0x19);
	TFT9488_SendData(0x03);
	TFT9488_SendData(0x0F);
	TFT9488_SendData(0x05);
	TFT9488_SendData(0x32);
	TFT9488_SendData(0x45);
	TFT9488_SendData(0x46);
	TFT9488_SendData(0x04);
	TFT9488_SendData(0x0E);
	TFT9488_SendData(0x0D);
	TFT9488_SendData(0x35);
	TFT9488_SendData(0x37);
	TFT9488_SendData(0x0F);


	//Power Control 1
	TFT9488_SendCommand(0XC0);
	TFT9488_SendData(0x17);    //Vreg1out
	TFT9488_SendData(0x15);    //Verg2out

	//Power Control 2
	TFT9488_SendCommand(0xC1);
	TFT9488_SendData(0x41);    //VGH,VGL

	//Power Control 3
	TFT9488_SendCommand(0xC5);
	TFT9488_SendData(0x00);
	TFT9488_SendData(0x12);    //Vcom
	TFT9488_SendData(0x80);

	//Memory Access или это определение ориентации
	TFT9488_SendCommand(0x36);
	TFT9488_SendData(0x48); //01001000

	TFT9488_SendCommand(0x3A);      // Interface Pixel Format
	TFT9488_SendData(0x55);   //16 bit

	TFT9488_SendCommand(0XB0);      // Interface Mode Control
	TFT9488_SendData(0x00);      //SDO NOT USE

	TFT9488_SendCommand(0xB1);      //Frame rate
	TFT9488_SendData(0xA0);    //60Hz

	TFT9488_SendCommand(0xB4);      //Display Inversion Control
	TFT9488_SendData(0x02);    //2-dot

	TFT9488_SendCommand(0XB6);      //Display Function Control  RGB/MCU Interface Control
	TFT9488_SendData(0x02);    //MCU
	TFT9488_SendData(0x02);    //Source,Gate scan dieection
	TFT9488_SendData(0x3B);    //480 линий

	TFT9488_SendCommand(0XE9);      // Set Image Functio
	TFT9488_SendData(0x00);    // Disable 24 bit data

	TFT9488_SendCommand(0xF7);      // Adjust Control
	TFT9488_SendData(0xA9);
	TFT9488_SendData(0x51);
	TFT9488_SendData(0x2C);
	TFT9488_SendData(0x82);    // D7 stream, loose

	//Выйдем из спящего режим
	TFT9488_SendCommand(0x11);
	HAL_Delay(2);

	//Включение дисплея
	TFT9488_SendCommand(0x29);

	TFT9488_SendData(0x2C);
	HAL_Delay(2);
}
/*
 * ili9488.c
 *
 *  Created on: Mar 16, 2022
 *      Author: AVerzin
 */

Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение Reflector »

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

// Функция записи данных в порты на линию данных
void TFT9488_Port_Write(char dt) {
   // смысл этого (dt & 0b10000000)?1:0 в следующем. это тернарная операция if
   // мы смотрим, есть ли в старшем бите dt единица и если она есть, то выдаем 1
   // если в старшем бите 0, соотвественно выводим 0.
   HAL_GPIO_WritePin(DATA7_GPIO_Port, DATA7_Pin, (dt & 0b10000000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA6_GPIO_Port, DATA6_Pin, (dt & 0b01000000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA5_GPIO_Port, DATA5_Pin, (dt & 0b00100000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA4_GPIO_Port, DATA4_Pin, (dt & 0b00010000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA3_GPIO_Port, DATA3_Pin, (dt & 0b00001000) ? 1 : 0);
   HAL_GPIO_WritePin(DATA2_GPIO_Port, DATA2_Pin, (dt & 0b00000100) ? 1 : 0);
   HAL_GPIO_WritePin(DATA1_GPIO_Port, DATA1_Pin, (dt & 0b00000010) ? 1 : 0);
   HAL_GPIO_WritePin(DATA0_GPIO_Port, DATA0_Pin, (dt & 0b00000001) ? 1 : 0);
}
Вывод 8 бит в порт, вместе с RS и RW, если порт тот же - это одна запись в BSRR, а не вот это... Неужели на AVR было так же и заливка происходила практически моментально?
Реклама
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение AlanDrakes »

Хоспаде, вы бы ещё на Ява-скрипте написали.
HAL он на то и "Уровень абстракции от железа". Он позволяет писать код одинаково для всех контроллеров производителя, но взамен выполняет МНОГО дополнительных операций внутри своих слоёв. Ну и плюс... Почему нельзя было просто вывести байт в порт? Зачем эта дикая конструкция по проверке битов?
a797945
Мучитель микросхем
Сообщения: 446
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Откуда: 69.Ржев

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение a797945 »

это, наверно, с ардуины притащили.
замут чтобы линии на экран назначать любой порт, любой пин.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение VladislavS »

[uquote="The Rock",url="/forum/viewtopic.php?p=4199768#p4199768"]Из-за того что я использую Nucleo64 с дисплейным шилдом, то все выводы раскиданы аж по 3 портам,[/uquote]А код написан так, словно у вас каждый пин на своём порту.

[uquote="The Rock",url="/forum/viewtopic.php?p=4199768#p4199768"]поэтому написано всечерез функции с применением библиотеки HAL.[/uquote]Не лучшая идея, когда нужна скороcть.

[uquote="The Rock",url="/forum/viewtopic.php?p=4199768#p4199768"]Изменение скорости тактирования порта с LOW на HIGH существенно ничего не меняет.[/uquote]Оно вообще ничего не меняет, так как влияет только на крутизну фронтов. Скорость вывода остаётся прежней.

[uquote="The Rock",url="/forum/viewtopic.php?p=4199768#p4199768"]Знаю что у меня есть DMA и это может дать прирост в скорости, но я не пока не умею им пользоваться[/uquote]Нет, DMA в данном случае вам совсем не помощник. Думается, только хуже сделаете.

[uquote="The Rock",url="/forum/viewtopic.php?p=4199768#p4199768"]и как мне кажется, STM32 должна опережать по скорости Atmega8 , даже без использования DMA...[/uquote]Когда вот так в лоб сравнивают скорость AVR с ARM сразу приходит в голову мультик "Ишь ты, Масленица" - "Пока твой конь четырьмя ногами - раз два три четыре... Мальчишка на двух - раз, два, раз, два".

[uquote="The Rock",url="/forum/viewtopic.php?p=4199768#p4199768"]Может ли это значительно уменьшать скорость ?[/uquote]Скажу так, ваш код, навскидку, можно в десятки (а может даже сотню, смотря как ноги по портам распихать) раз ускорить.

Добавлено after 16 minutes 28 seconds:
План действий такой:
1. Отказаться от HAL_GPIO_WritePin.
2. Сгруппировать записи по портам. У вас их три, вот и должно быть три записи.
3. Объединить запись линий data с сигналами RS и RW.
4. Посмотреть на код и перегруппировать ноги так, чтобы было как можно меньше логических операций при группировке данных для записи в порты.

На каждом шаге можно получить значительный прирост в скорости. Atmega8 так уж точно обойдём :)
Реклама
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

[uquote="Reflector",url="/forum/viewtopic.php?p=4199786#p4199786"]Вывод 8 бит в порт, вместе с RS и RW, если порт тот же - это одна запись в BSRR, а не вот это... Неужели на AVR было так же и заливка происходила практически моментально?[/uquote]
Нет, в уроке было более оптимально просто перенос переменной в регистры. так как там все было подключено к 1 порту, я просто думал что STM32 настолько быстро дрыгает своими ножками, что и так сойдет...
AlanDrakes писал(а):замут чтобы линии на экран назначать любой порт, любой пин.
Да, именно в этом и была цель. Так как у меня разные платы и, казалось, что 8 битная шина ну никак не может быть медленной. Но видимо ошибся
VladislavS писал(а):План действий такой:
1. Отказаться от HAL_GPIO_WritePin.
2. Сгруппировать записи по портам. У вас их три, вот и должно быть три записи.
3. Объединить запись линий data с сигналами RS и RW.
4. Посмотреть на код и перегруппировать ноги так, чтобы было как можно меньше логических операций при группировке данных для записи в порты.
На каждом шаге можно получить значительный прирост в скорости. Atmega8 так уж точно обойдём
Огромное спасибо! На днях отпишусь по результатам, может даже попробую все переписать на работу с 1 портом :)
Портов на линии данных на самом деле 2, часть управления на 3ем =)

Добавлено after 2 hours 5 minutes 32 seconds:
Чтото у меня ещё более монструозное получается.... Чую я не в том направление иду, уже вижу ошибки как минимум в GPIOx->ODR = mask. Затирает весь порт и оставляет только биты данных

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

uint16_t mask = 0x0000;
	if (dt & 0b00000010) {
		mask = 0x0080;
	}
	GPIOC->ODR = mask;

	mask = 0x0000;
	//7 бит данных на 8 порт
	if(dt & 0b10000000) {
		mask = 0x0100;
	}
	// 0бит данных на 9 порт
	if(dt & 0b00000001){
		mask |= 0x0200;
	}
	//2бит данных на 10 порт
	if(dt & 0b00000100){
		mask |= 0x0400;
	}
	GPIOA->ODR = mask;

	mask = 0x0000;
	//3бит данных на 3 порт
	if(dt & 0b00001000){
		mask |= 0x0008;
	}
	//4 бит данных на 5 порт
	if(dt & 0b00010000){
		mask |=0x0020 ;
	}
	//6 бит данных на 10 порту
	if(dt & 0b01000000){
		mask |= 0x0400;
	}
	GPIOB->ODR = mask;
Реклама
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение VladislavS »

Не, не, не. Ни каких ODR. Читаем про регистр BSRR.
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

2 VladislavS
Подскажите пожалуйста, переписал на BSRR, но увы не работает. Перепроверял соответствие бита и пинов все верно, однако не работает (

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

	if (dt & 0b10000000) maskA |= GPIO_PIN_8; // 7 бит данных на 8 пин порт А
	if (dt & 0b01000000) maskB |= GPIO_PIN_10; // 6 бит данных на 10 пин порта В
	if (dt & 0b00100000) maskB |= GPIO_PIN_4;// 5 бит данных на 4 пин порта В
	if (dt & 0b00010000) maskB |= GPIO_PIN_5; // 4 бит данных на 5 пин порта В
	if (dt & 0b00001000) maskB |= GPIO_PIN_3; // 3 бит данных на 3 пин порт В
	if (dt & 0b00000100) maskA |= GPIO_PIN_10; // 2 бит данных на 10 пин порт А
	if (dt & 0b00000010) maskC |= GPIO_PIN_7; // 1 бит данных на 7 пин порта С
	if (dt & 0b00000001) maskA |= GPIO_PIN_9; // 0  бит данных на 9 пин порт А

	GPIOA->BSRR = maskA;
	GPIOB->BSRR = maskB;
	GPIOC->BSRR = maskC;
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение Reflector »

BSRR состоит из двух половинок, в одной сбрасываешь все биты пинов, в другой устанавливаешь нужные(установка имеет приоритет).
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

Reflector писал(а):BSRR состоит из двух половинок, в одной сбрасываешь все биты пинов, в другой устанавливаешь нужные(установка имеет приоритет).
Честно говоря не понял (

То что я вычитал, это есть BSRR и BRR и вот BSRR ставит, BRR снимает.

написал в main вот такое и блинк работает

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

 uint16_t masa = 0;
 masa |= GPIO_PIN_5;

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

	//  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);


	  // зажигаем 5 пин
	  GPIOA -> BSRR = masa;
	  HAL_Delay(150);
	  GPIOA -> BRR = masa;
	  HAL_Delay(150);
}
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение Reflector »

Нет, BSRR ставит и снимает одновременно. Ты только ставишь, через время на портах будет 10 единичек. Конечно можно снимать при помощи BRR, но тогда будет две записи в порт...
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

Пока пытался понять логику работы понял, что вы имеете ввиду. Получается что через BRR я в итоге забью весь порт и будет у меня там всегда 1 после этой функции и они не будут сбрасываться для следующей передачи данных. Интересная мысль спасибо!

т.е. получается мне необходимо модифицировать какуюто функцию, чтобы данные отправились, произошел строб для считывания и потом все линии стали в нули....
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение Reflector »

Похоже ты ничего не понял. Допустим нужно в PA2/PA1/PA0 записать 5 не трогая другие пины, тогда сначала очищаем все три пина записывая единички в старшую половину BSRR, а потом устанавливаем нужные два:

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

GPIOA->BSRR = (0x07 << 16) | 5;
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

Reflector,
Спасибо, действительно пока сложно понять, как работать с этим регистром в моем случае. Пример был очень наглядный и понятный, пойду возьму паузу на осмысление и понятия того как это использовать мне.
А так было просто с WritePin)

Добавлено after 8 minutes 39 seconds:
Родилось вот такое

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

	if (dt & 0b10000000) maskA |= GPIO_PIN_8; 	// 7 бит данных на 8 пин порт А
	if (dt & 0b01000000) maskB |= GPIO_PIN_10; 	// 6 бит данных на 10 пин порта В
	if (dt & 0b00100000) maskB |= GPIO_PIN_4;	// 5 бит данных на 4 пин порта В
	if (dt & 0b00010000) maskB |= GPIO_PIN_5; 	// 4 бит данных на 5 пин порта В
	if (dt & 0b00001000) maskB |= GPIO_PIN_3; 	// 3 бит данных на 3 пин порт В
	if (dt & 0b00000100) maskA |= GPIO_PIN_10; 	// 2 бит данных на 10 пин порт А
	if (dt & 0b00000010) maskC |= GPIO_PIN_7; 	// 1 бит данных на 7 пин порта С
	if (dt & 0b00000001) maskA |= GPIO_PIN_9; 	// 0 бит данных на 9 пин порт А

	GPIOA->BSRR = (GPIO_PIN_8|GPIO_PIN_10|GPIO_PIN_9) << 16 | maskA;
	GPIOB->BSRR = (GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16 | maskB;
	GPIOC->BSRR = GPIO_PIN_7 << 16 | maskC;
Скорость немного подросла
было 2.7 секунд
стало 1.4 секунды....

Надо ещё както ускорить в 10 раз....

Добавлено after 14 minutes 44 seconds:
Ещё вижу способ для ускорения это убрать HAL_Delay(1). В примере от AVR были микросекундные задержки, а у меня в 1000 раз больше.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение VladislavS »

На какой скорости работает процессор и какой уровень оптимизации?

Для начала вот так

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

GPIOA->BSRR = ((GPIO_PIN_8|GPIO_PIN_10|GPIO_PIN_9) << 16)
            | ((dt & 0b10000000) << 1)   // 7 бит данных на 8 пин порт А
            | ((dt & 0b00000100) << 8)   // 2 бит данных на 10 пин порт А
            | ((dt & 0b00000001) << 9);  // 0 бит данных на 9 пин порт А

GPIOB->BSRR = ((GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16)
            | ((dt & 0b01000000) << 4)    // 6 бит данных на 10 пин порта В
            | ((dt & 0b00100000) >> 1)    // 5 бит данных на 4 пин порта В
            | ((dt & 0b00010000) << 1)    // 4 бит данных на 5 пин порта В
            | (dt & 0b00001000);          // 3 бит данных на 3 пин порт В

GPIOC->BSRR = (GPIO_PIN_7 << 16 )
            | ((dt & 0b00000010) << 6);   // 1 бит данных на 7 пин порта С
Затем, сюда же вводите сигналы RS и RW, их можно/нужно устанавливать вместе с данными.

На маску B напрашивается таблица перекодировки на 16 элементов, из которой выбирается значение по индексу ((dt & 0b01111000)>>3).
Последний раз редактировалось VladislavS Пт мар 18, 2022 08:34:23, всего редактировалось 2 раза.
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение AlanDrakes »

[uquote="The Rock",url="/forum/viewtopic.php?p=4200202#p4200202"]Скорость немного подросла
было 2.7 секунд
стало 1.4 секунды....

Надо ещё както ускорить в 10 раз....[/uquote]
А вы можете использовать пины более... компактно? Или так разведено на плате?
Кстати, если контроллер изначально должен работать с экраном через параллельный порт и через FMC / FSMC шину, то ускорить вывод в него можно легко. Где-то, раз в 80.

Если же вы сами так раскидали пины... то всё очень грустно. Рекомендую скомпоновать их в восемь бит одного порта. Тогда писать можно будет всего за несколько тактов:

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

// Сброс пинов 0..7 порта B (шина напрямую сопоставлена D0 -> PB0, D1 -> PB1, ... D7 -> PB7
 GPIOB->BSRR = GPIO_BSRR_BR0 | GPIO_BSRR_BR1 | GPIO_BSRR_BR2 <...> GPIO_BSRR_BR7;
// Выводим байт в порт. "Нижние" биты [0..15] вызвают установку соответствующих пинов порта.
 GPIOB->BSRR = (uint8_t)NEXT_DATA_BYTE;
// Опускаем /CS, затем /WR
 GPIOx->BSRR = GPIO_BSRR_BR_cs_pin_n;
 GPIOx->BSRR = GPIO_BSRR_BR_wr_pin_n;
// Поднимаем /WR, затем /CS
 GPIOx->BSRR = GPIO_BSRR_BS_cs_pin_n;
 GPIOx->BSRR = GPIO_BSRR_BS_wr_pin_n;
В случае же с записью через FSMC, будет ещё интереснее:

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

// Запись байта данных
 FSMC_REGION_DATA = (uint8_t)Next_Data_Byte;
// Запись команды
 FSMC_REGION_CMD = (uint8_t)Command_Byte;
Но в этом случае нужно подключать дисплей в соответствии с распиновкой FSMC / FMC контроллера.
Например, для STM32F7 сопоставление пинов выглядит так (взял из комментариев в своём коде):

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

	// PORTD[0,1,4,5,7,11,13,14,15] = D2, D3, Rd, Wr, Cs, A16, D0, D1
	// PORTE[7-10] = D4, D5, D6, D7
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение VladislavS »

[uquote="AlanDrakes",url="/forum/viewtopic.php?p=4200235#p4200235"]А вы можете использовать пины более... компактно? Или так разведено на плате?[/uquote]Там Nucleo с шилдом. Даже с такой разводкой можно что-то выжать. Просто надо поработать, чтобы всё нормально оптимизировалось и заинлайнилось по скорости.

Добавлено after 1 hour 2 minutes 35 seconds:
С таблицей перекодировки как-то так

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

// В глобальной области
#define MB(X) (((GPIO_PIN_10|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_3) << 16)\
               | ((X&1)?(1<<3):0)\
               | ((X&2)?(1<<5):0)\
               | ((X&4)?(1<<4):0)\
               | ((X&8)?(1<<10):0))

const uint32_t MaskB[16] = { MB(0), MB(1), MB(2), MB(3),
                             MB(4), MB(5), MB(6), MB(7),
                             MB(8), MB(9), MB(10), MB(11),
                             MB(12), MB(13), MB(14), MB(15) };

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

GPIOB->BSRR = MaskB[(dt>>3)&0xF];
Добавлено after 1 hour 19 minutes 18 seconds:
Ещё наблюдение. Вы много-много раз пишете TFT9488_Write8(hi); TFT9488_Write8(lo); с одним и тем же значением hi и lo. И при каждом вызове функции вычисляются маски портов A,B,C. Можно это сделать один раз и передавать в TFT9488_Write8 указатель на структуру из трёх масок.

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

struct MASKS
{
  uint32_t MaskA;
  uint32_t MaskB;
  uint32_t MaskC;
};

void TFT9488_Wr(MASKS *masks)
{
  GPIOA->BSRR = masks->MaskA;
  GPIOB->BSRR = masks->MaskB;
  GPIOC->BSRR = masks->MaskC;
}
Красота

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

//void TFT9488_Wr(MASKS *masks)
//{
//  GPIOA->BSRR = masks->MaskA;
      LDR.N    R1,??DataTable2
      LDR      R2,[R0, #+0]
      STR      R2,[R1, #+0]
//  GPIOB->BSRR = masks->MaskB;
      LDR      R3,[R0, #+4]
      STR      R3,[R1, #+1024]
//  GPIOC->BSRR = masks->MaskC;
      LDR      R0,[R0, #+8]
      STR      R0,[R1, #+2048]
//}
      BX       LR
Если всё это заинлайнится, то и загрузка регистров R0-R3 дополнительно оптимизируется. Будет как пулемёт работать.
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

VladislavS писал(а):На какой скорости работает процессор и какой уровень оптимизации?
Уровень оптимизации не знаю где смотреть, я пишу в Cube. Про оптимизатор слышал только в видео про keil.

Скорости стоят максимальные SYSCLK 64 MHz и по портам тоже все по максимуму
VladislavS писал(а):Для начала вот так
Спасибо! Такое ещё 0.2 сек убрало с результата. Теперь экран перекрашивается не за 2.7с, а за 0.7с.
VladislavS писал(а):С таблицей перекодировки как-то так
К сожалению, я вообще не понимаю что тут написано ( Буду разбираться. Спасибо!
AlanDrakes писал(а):В случае же с записью через FSMC, будет ещё интереснее:
У меня 103RB, там вроде как нет FSMC...
AlanDrakes писал(а):А вы можете использовать пины более... компактно? Или так разведено на плате?
У меня nucleo плата и туда через ардуино разъем вставлен ардуиношилд с TFT. Поэтому такая и фигня с портами, обязательно, для теста оптимизированного кода подключу правильно логично все на 1 порт, и замерю скорость. Но пока хочется выжать из этого максималку.... Ибо уже и так благодаря помощи удалось снизить с 2.7 до 0.7с. Причем самый огромный прирост это с 2.7 до 1.1 сек дал переход на BSRR

Добавлено after 17 minutes 44 seconds:
Пересмотрел видео с AVR ( https://youtu.be/95gqElRb074?t=1862 )

Вроде как у меня экран уже с похожей скоростью перекрашивается, хотя мой и значительно больше

Добавлено after 22 minutes:
Замерил стробы на WR при помощи анализатора,
Вложения
else.png
Вот так стробит, когда hi!=lo , как я понимаю, это будет основной режим работы
(67.06 КБ) 93 скачивания
if(hi==lo).png
Вот так стробит когда hi==lo
(67.31 КБ) 108 скачиваний
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение VladislavS »

Я думаю, без асма около 10 кадров в секунду должно получиться.

У F103 72 МГц штатная тактовая, включайте. Оптимизацию -О3 ставьте, ищите где.
К сожалению, я вообще не понимаю что тут написано
В порт B пишутся 4 бита одной группой, но они переставленны местами. 4 бита дают 16 разных значений для записи в BSRR. Их можно вычислить заранее, положить в массив и из него выбирать ставя в соответствие.
Вроде как у меня экран уже с похожей скоростью перекрашивается
Так вы ещё оптимизировать, по большому счёту, ещё не начали :)
Последний раз редактировалось VladislavS Пт мар 18, 2022 19:38:17, всего редактировалось 1 раз.
The Rock
Открыл глаза
Сообщения: 46
Зарегистрирован: Вт июн 05, 2012 23:32:13

Re: Медленный вывод на STM32 8 битной шины (дисплей)

Сообщение The Rock »

VladislavS писал(а):У F103 72 МГц штатная тактовая, включайте. Оптимизацию -О3 ставьте, ищите где.
IDE не может поставить 72 MHz, при этом в ручную в умножителе я ничего менять не могу... а руками кодить тактирование даже и не учился

https://img.radiokot.ru/files/74784/med ... k3i6h7.png
Ответить

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