Top.Mail.Ru
Уведомления
Очистить все

[Решено] stm32 + nt35510

Страница 2 / 2
(@eduard)
Level 4 Moderator

Запись от: @matrex

То что предлагаете вы - это похоже на эмуляцию протокола.

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

Запись от: @matrex

по FSMC куб предусматривает несколько предопределенных вариантов подключения

И Вы правы. Подключать нужно к тем ногам, которые предлагает CubeIDE.

К STM32F407xxx подключается к таким ногам (FSMC впервые я завёл на нём):

// FSMC GPIO Конфигурация
//  PE7   ------> FSMC_D4
//  PE8   ------> FSMC_D5
//  PE9   ------> FSMC_D6
//  PE10  ------> FSMC_D7
//  PE11  ------> FSMC_D8
//  PE12  ------> FSMC_D9
//  PE13  ------> FSMC_D10
//  PE14  ------> FSMC_D11
//  PE15  ------> FSMC_D12
//  PD0   ------> FSMC_D2
//  PD1   ------> FSMC_D3
//  PD4   ------> FSMC_NOE                                                        // RD - чтение. Активный 0
//  PD5   ------> FSMC_NWE                                                        // WR - запись. Активный 0
//  PD7   ------> FSMC_NE1                                                        // CS - выбор. Активный 0
//  PG9   ------> FSMC_NE2                                                        // CS - выбор. Активный 0
//  PG10  ------> FSMC_NE3                                                        // CS - выбор. Активный 0
//  PG12  ------> FSMC_NE4                                                        // CS - выбор. Активный 0
//  PD8   ------> FSMC_D13
//  PD9   ------> FSMC_D14
//  PD10  ------> FSMC_D15
//  PF0   ------> FSMC_A0                                                         // RS - выбор данные/команда
//  PF1   ------> FSMC_A1                                                         // RS - выбор данные/команда
//  PF2   ------> FSMC_A2                                                         // RS - выбор данные/команда
//  PF3   ------> FSMC_A3                                                         // RS - выбор данные/команда
//  PF4   ------> FSMC_A4                                                         // RS - выбор данные/команда
//  PF5   ------> FSMC_A5                                                         // RS - выбор данные/команда
//  PF12  ------> FSMC_A6                                                         // RS - выбор данные/команда
//  PF13  ------> FSMC_A7                                                         // RS - выбор данные/команда
//  PF14  ------> FSMC_A8                                                         // RS - выбор данные/команда
//  PF15  ------> FSMC_A9                                                         // RS - выбор данные/команда
//  PG0   ------> FSMC_A10                                                        // RS - выбор данные/команда
//  PG1   ------> FSMC_A11                                                        // RS - выбор данные/команда
//  PG2   ------> FSMC_A12                                                        // RS - выбор данные/команда
//  PG3   ------> FSMC_A13                                                        // RS - выбор данные/команда
//  PG4   ------> FSMC_A14                                                        // RS - выбор данные/команда
//  PG5   ------> FSMC_A15                                                        // RS - выбор данные/команда
//  PD11  ------> FSMC_A16                                                        // RS - выбор данные/команда
//  PD12  ------> FSMC_A17                                                        // RS - выбор данные/команда
//  PD13  ------> FSMC_A18                                                        // RS - выбор данные/команда
//  PD14  ------> FSMC_D0
//  PD15  ------> FSMC_D1

Следует учесть, что сигнал RS может оказаться инверсным. У меня такое было у дисплея RA8875.

Это статьи, которыми я пользовался.

В моих статьях есть ссылка на яндекс диск (Ссылка). Там есть драйвера на С++ для ILI9341. Можно написать по образу и подобию. Правда я пробовал его на F407. Для других нужно править. Я его не дописал ещё. Нужды не было. И есть статья, где я начал рассматривать подключение дисплеев

ОтветитьЦитата
Размещено : 19.01.2024 07:56
(@andrej-8)
Level 1

@matrex указанный вами чип умеет без проблем работать с фцмс, пример (выше на два поста) без проблем заведётся на данном чипе...

ОтветитьЦитата
Создатель темы Размещено : 19.01.2024 13:58
(@eduard)
Level 4 Moderator

@matrex Вот схема подключения без сигнала RD. На этом дисплее у меня его не было.

ОтветитьЦитата
Размещено : 20.01.2024 09:27
(@andrej-8)
Level 1

@eduard у меня нет вашего дисплея, и я не знаю варианта кода инициализации драйвера дисплея без данных контактов... Вариант по которому я подключал написан в файлах, попробуйте "докинуть" недостающие - может прокатит инициализация и заведётся дисплей...

ОтветитьЦитата
Создатель темы Размещено : 20.01.2024 10:03
(@eduard)
Level 4 Moderator

@andrej-8 Не совсем Вас понял. Какие файлы докинуть? У меня всё работает.

ОтветитьЦитата
Размещено : 20.01.2024 10:42
(@andrej-8)
Level 1

@eduard извините, перепутал.

ОтветитьЦитата
Создатель темы Размещено : 20.01.2024 11:14
(@matrex)
Level 1

Спасибо за советы. Вот что удалось сделать за несколько дней.

Примеры, приведенные выше, разумеется, с первого раза не запустились. Оно и понятно – наверняка проблема в несовместимости драйверов.  Мой драйвер, судя по упаковке LCD - NT35510. Скопировал последовательность инициализации с примера в ваш код – поучил «шум» (рис. 1). Адаптировал китайский пример программы под свой STM на Keil uVision5 – поучил «шум». Переделал инициализацию под SW4STM32 + Cube – результат «шум». Проверил схему подключения, обрывы, КЗ – результат тот же. Попробовал запустить проект, под который собственно это все и затевалось ( https://habr.com/ru/post/524498/), получил нечто  похожее на результат (рис. 2), но опять же далекий от идеала.

Посему, мне кажется, что попался какой то экзотический драйвер дисплея, не NT35510 и не OTM8009A – ну или брак... Пока в раздумьях.

Спойлер
Шум
ris1

 

Спойлер
Что то похожее на результат
ris2

 

Спойлер
Проект SW4STM32 + Cube: STM32F407VGT6 + LCD - результат шум

 

ОтветитьЦитата
Размещено : 21.01.2024 17:47
(@eduard)
Level 4 Moderator

@matrex 

То, что у вас после инициализации появился шум, это просто отлично. Значит дисплей подключен правильно и понимает команды.

А шум просто случайные числа записанные в ОЗУ контроллера. Так всегда бывает при первом включении питания.

А то, что считаете за результат, он скорее и есть. Просто пример рассчитан на другой размер (количество пикселей по горизонтали и вертикали) экрана.

 

Если я не путаю, у вас дисплей должен быть 480х864, а в драйвере дисплея задаётся 480х800

 

ОтветитьЦитата
Размещено : 21.01.2024 18:27
(@matrex)
Level 1

@eduard 

Я связывался с автором проекта, как он говорит, это код по дисплей 800x480, правда под OTM8009A (у меня такой же 800х480 только драйвер NT35510). Я думаю что пока рано с ним разговаривать на эту тему, я хочу убедиться в том, что дисплей работает в принципе, поэтому хочу его хотя бы его просто запустить…

Вот вы говорите что в принципе хорошо что шум, типа LCD инициализируется, а в чем может быть проблема что дальше заливка не получается. Я и вашу функцию пробовал, и из примера… Странно как то… Может проблема в этих константах

// для записи данных
#define LCD_DATA ((uint32_t)0x60020000)

// для записи команд
#define LCD_REG ((uint32_t)0x60000000)

Хотя я пробовал их менять, дисплей перестает работать вообще, а в китайском примере я ничего такого вообще не нашел.

ОтветитьЦитата
Размещено : 21.01.2024 18:53
(@eduard)
Level 4 Moderator

@matrex Почитайте файлы, что я оставлял здесь на форуме. Там подробно расписано, что это за константы. Естественно не будет работать, если местами поменять.

Попробуйте сделать заливку одним цветом и не в цикле и покажите результат.

ОтветитьЦитата
Размещено : 21.01.2024 22:37
(@matrex)
Level 1

@eduard 

Да извините, почитал подробнее - теперь ясно на счет констант. По поводу заливки - собственно результата никакого - просто шум.

Вот код на всякий случай, инициализацию дисплея выпилил. Ну и функции для работы с памятью пришлось унифицировать, т.к. нужно было совместить ваш и китайский код. Цветом крашу при инициализации в initLCD().

Спойлер
Код
#include "lcd.h"
#include <stdint.h>

// Простенькая функция задержки
void delay(unsigned int delayTime)
{
 uint32_t i;
 for(i = 0; i < delayTime; i++);
}

void LCD_WR_DATA(unsigned int data)
{
 *(uint16_t *) (LCD_DATA)= data;
}

void LCD_WR_REG(unsigned int reg)
{
 *(uint16_t *) (LCD_REG) = reg;
}

void LCD_WriteReg(unsigned int reg,unsigned int value)
{
 *(uint16_t *) (LCD_REG) = reg;
 *(uint16_t *) (LCD_DATA) = value;
}

void LCD_WriteRAM_Prepare(void)
{
	unsigned int wramcmd=0x2C00;
	LCD_WR_REG(wramcmd);
}

void LCD_SetWindows(unsigned int xStar, unsigned int yStar,unsigned int xEnd,unsigned int yEnd)
{
	unsigned int setxcmd=0x2A00;
	unsigned int setycmd=0x2B00;

	LCD_WR_REG(setxcmd);LCD_WR_DATA(xStar>>8);
	LCD_WR_REG(setxcmd+1);LCD_WR_DATA(xStar&0XFF);
	LCD_WR_REG(setxcmd+2);LCD_WR_DATA(xEnd>>8);
	LCD_WR_REG(setxcmd+3);LCD_WR_DATA(xEnd&0XFF);
	LCD_WR_REG(setycmd);LCD_WR_DATA(yStar>>8);
	LCD_WR_REG(setycmd+1);LCD_WR_DATA(yStar&0XFF);
	LCD_WR_REG(setycmd+2);LCD_WR_DATA(yEnd>>8);
	LCD_WR_REG(setycmd+3);LCD_WR_DATA(yEnd&0XFF);

	LCD_WriteRAM_Prepare();	// GRAM
}

void LCD_Clear(unsigned int Color)
{
  unsigned int i;
	LCD_SetWindows(0,0,LCD_W,LCD_H);
	for(i=0;i<LCD_W*LCD_H;i++)
	{
		LCD_WR_DATA(Color);
	}
}

void LCD_ClearA(unsigned int Color)
{
	 // Начальный и конечный адреса по горизонтали
	LCD_WriteReg(0x0050, 0);
	LCD_WriteReg(0x0051, 239);
	 // Начальный и конечный адреса по вертикали
	LCD_WriteReg(0x0052, 0);
	LCD_WriteReg(0x0053, 319);
	LCD_WriteReg(32, 0);
	LCD_WriteReg(33, 0);
	LCD_WR_REG (34);
	 // Красный
	 for (int i = 0; i < 76800; i++) LCD_WR_DATA(Color);
}

void LCD_direction(char direction)
{
	switch(direction){
		case 0:
			LCD_WriteReg(0x3600,0x00);
		break;
		case 1:
			LCD_WriteReg(0x3600,(1<<5)|(1<<6));
		break;
		case 2:
			LCD_WriteReg(0x3600,(1<<7)|(1<<6));
		break;
		case 3:
			LCD_WriteReg(0x3600,(1<<7)|(1<<5));
		break;
		default:break;
	}
}

/*******************************************************************/
void initLCD()
{
	delay(1500);
        // инициализация из китайского примера
	delay(1500);

	// После этих команд появляется шум
        // Часть кода инициализация из китайского примера
	LCD_WR_REG(0x2900);
	LCD_WR_REG(0x2c00);

        // КИТАЙСКИЙ ПРИМЕР
        LCD_direction(USE_HORIZONTAL);//
	LCD_Clear(RED);//

	// ВАШ ПРИМЕР
	// LCD_ClearA( 0xF800); // красный
}

Слушайте, а может какой то косяк при инициализации FSMC - я то пользовался кубом - для меня этот контроллер пока новинка - может какой чекбокс пропустил...

Спойлер
Куб
kube
ОтветитьЦитата
Размещено : 22.01.2024 18:43
(@matrex)
Level 1

Или такой вопрос: необходимо ли явно настраивать порты STM32 к которым подключен LCD на "выход", или включение FSMC делает это автоматически. Я посмотрел, код который генирит куб. Настройки портов для связи с LCD в коде не прописываются (правда, может инициализация идет где-то глубже, например в HAL_SRAM_Init), в вашем же примере это сделано явно.

Спойлер
Код
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : Led_Pin */
  GPIO_InitStruct.Pin = Led_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(Led_GPIO_Port, &GPIO_InitStruct);

}

/* FSMC initialization function */
static void MX_FSMC_Init(void)
{
  FSMC_NORSRAM_TimingTypeDef Timing;

  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FSMC_NORSRAM_DEVICE;
  hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
  hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
  hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 15;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 255;
  Timing.BusTurnAroundDuration = 15;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FSMC_ACCESS_MODE_A;
  /* ExtTiming */

  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }

}
ОтветитьЦитата
Размещено : 22.01.2024 19:25
Aveal
(@aveal)
Top level Admin

Запись от: @matrex

Или такой вопрос: необходимо ли явно настраивать порты STM32 к которым подключен LCD на "выход", или включение FSMC делает это автоматически. Я посмотрел, код который генирит куб. Настройки портов для связи с LCD в коде не прописываются (правда, может инициализация идет где-то глубже, например в HAL_SRAM_Init), в вашем же примере это сделано явно.

Должен инициализировать автоматически в сгенерированном коде, может где-то в stm32xx_hal_msp.c.

 

ОтветитьЦитата
Размещено : 23.01.2024 12:01
Страница 2 / 2
Поделиться: