Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 24.10.2019, 01:59  
Юрий_48
Частый гость
 
Регистрация: 24.10.2019
Сообщений: 13
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Юрий_48 на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Использую вот такой дисплей 240x320 2,8" SPI TFT (ILI9341), STM32F103C8. С трудом смог его запустить с использованием HAL. Работает медленно. Пока отлаживал меня это особо не волновало. Но, вот, захотел ускорить работу. Для этого функцию передачи байта
Нажмите, чтобы открыть спойлер
void TFT9341_Write8(uint8_t dt)
{
HAL_SPI_Transmit(&hspi1,&dt,1,1);
}

заменил на такую, более ничего не трогая
Нажмите, чтобы открыть спойлер
void TFT9341_Write8(uint8_t dt)
{
while((SPI1-›SR & SPI_SR_TXE)==RESET){}
SPI1-›DR = dt;
}

Скорость вывода разительно увеличилась. Но при этом начались заморочки. Само изображение выводиться правильно, но его позиционирование не соответствует заданному. Первый вывод выводится с позиционированием в верхнем левом углу с небольшим смещением в право (скажем дельта) вне зависимости от того, какое позиционирование задано. Если попытаться ещё раз вывести, то изображение сместится вниз на величину своей высоты и в право на величину дельта. И так далее при следующих выводах. Функция позиционирования выглядит так
Нажмите, чтобы открыть спойлер
void TFT9341_SetAddrWindow(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
//HAL_Delay(10);
unsigned long t;
//CS_ACTIVE;
t = x1;
t‹‹=16;
t |= x2;
TFT9341_WriteRegister32(0x2A,t);//Column Addres Set
t = y1;
t‹‹=16;
t |= y2;
TFT9341_WriteRegister32(0x2B,t);//Page Addres Set
}

Совершенно не могу понять, как процедура вывода байта может повлиять на позиционирование. Может, что то там не успевает и нужно где то поставить задержки. Так же в голову не приходит методика поиска этой заморочки. Что посоветуете?
Реклама:
Юрий_48 вне форума  
Непрочитано 24.10.2019, 10:44  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,504
Сказал спасибо: 401
Сказали Спасибо 2,217 раз(а) в 1,315 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Изучите, что такое DMA, и настройте передачу по SPI через DMA. Даже с HAL это будет гораздо быстрее, чем отдельная передача по одному байту/
Что касается сдвига, то просто передаете неправильно байты. Сверьтесь с мануалом ILI9341. Если сделаете точно по мануалу, все будет работать правильно

Последний раз редактировалось NewWriter; 24.10.2019 в 10:49.
NewWriter вне форума  
Непрочитано 24.10.2019, 11:25  
Юрий_48
Частый гость
 
Регистрация: 24.10.2019
Сообщений: 13
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Юрий_48 на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Сообщение от NewWriter Посмотреть сообщение
Что касается сдвига, то просто передаете неправильно байты. Сверьтесь с мануалом ILI9341. Если сделаете точно по мануалу, все будет работать правильно
С этим спорить не приходится. Но не понятно как это, когда в рабочей программе побайтный вывод, сделанный мощью функции HAL, идёт без вопросов, только что медленно. А если эту же функцию побайтного вывода сделать на CMSIS ничего более не трогая, то вывод идёт быстро, но позиционирование не верное.
Что касается
Сообщение от NewWriter Посмотреть сообщение
Изучите, что такое DMA, и настройте передачу по SPI через DMA. Даже с HAL это будет гораздо быстрее, чем отдельная передача по одному байту/
то скорость по второму варианту меня вполне устраивает. И мне видеться, что на допиливание этого варианта время потрачу меньше, чем на проработку использования DMA. Но эта позиция, конечно, спорная.
Юрий_48 вне форума  
Непрочитано 25.10.2019, 01:30  
ProtAS-13
Прописка
 
Регистрация: 17.03.2015
Сообщений: 287
Сказал спасибо: 0
Сказали Спасибо 209 раз(а) в 121 сообщении(ях)
ProtAS-13 на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Сообщение от Юрий_48 Посмотреть сообщение
Совершенно не могу понять, как процедура вывода байта может повлиять на позиционирование. Может, что то там не успевает и нужно где то поставить задержки. Так же в голову не приходит методика поиска этой заморочки. Что посоветуете?
Скорее всего, Вы забыли про флаг BSY. На картинке - как должно быть.
Т.е., анализируя только TXE, Вы попадаете в ситуацию, когда последний байт команды еще не передался, а Вы уже готовы "дернуть" DC/CS дисплея.
Чтобы проверить это предположение, достаточно поставить задержку в конец Вашей функции TFT9341_Write8, чтобы гарантировать корректную передачу последнего байта команды.
При этом, вывод на дисплей начнет работать медленно, но позиционнирование отображаемых элементов должно соответствовать ожидаемому.
Если так и произошло, то выкидывайте задержку и думайте куда поставить анализ флага BSY.
Миниатюры:
Нажмите на изображение для увеличения
Название: pic1.jpg
Просмотров: 0
Размер:	153.0 Кб
ID:	146616  
ProtAS-13 вне форума  
Сказали "Спасибо" ProtAS-13
Юрий_48 (26.10.2019)
Непрочитано 26.10.2019, 00:51  
Юрий_48
Частый гость
 
Регистрация: 24.10.2019
Сообщений: 13
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Юрий_48 на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

ProtAS-13, огромное спасибо за ответ по существу.
Сообщение от ProtAS-13 Посмотреть сообщение
Если так и произошло, то выкидывайте задержку и думайте куда поставить анализ флага BSY.
Именно так и произошло. На сегодня моя думалка ничего лучшего не придумала, как поставить проверку BSY в конец передачи команды
Нажмите, чтобы открыть спойлер

void TFT9341_WriteRegister32(unsigned char r, unsigned long d)
{
CS_ACTIVE;
CD_COMMAND;
TFT9341_Write8(r);
CD_DATA;
TFT9341_Write8(d››24);
//HAL_Delay(10);
TFT9341_Write8(d››16);
TFT9341_Write8(d››;
TFT9341_Write8(d);
while((SPI1-›SR & SPI_SR_BSY)!=0) {}
}

Но ничего не изменилось. Сегодня уже нет возможности копать, завтра попробую - всего то у меня на эту работу есть пару часов вечером. Очень радует, что определилась проблема. А от куда у Вас эта временная диаграмма? У меня в официальном описании ILITEK такого нет.
И ещё меня сильно удивило (в хорошем смысле) отношение количества "Спасибо" к количеству сообщений - где то 1. Это высокий класс, такого ещё не видел, снимаю шляпу.

Последний раз редактировалось Юрий_48; 26.10.2019 в 00:59.
Юрий_48 вне форума  
Непрочитано 26.10.2019, 02:10  
sat_art
Вид на жительство
 
Регистрация: 27.11.2007
Сообщений: 428
Сказал спасибо: 19
Сказали Спасибо 39 раз(а) в 30 сообщении(ях)
sat_art на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Сообщение от Юрий_48 Посмотреть сообщение
Совершенно не могу понять, как процедура вывода байта может повлиять на позиционирование. Может, что то там не успевает и нужно где то поставить задержки. Так же в голову не приходит методика поиска этой заморочки. Что посоветуете?
Такая реакция очень напоминает ситуацию с неправильным количеством. Проверьте все ли в свое время и в своем месте передается.
sat_art вне форума  
Непрочитано 26.10.2019, 18:11  
dkm
Вид на жительство
 
Регистрация: 10.04.2010
Сообщений: 301
Сказал спасибо: 25
Сказали Спасибо 136 раз(а) в 79 сообщении(ях)
dkm на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Сообщение от Юрий_48 Посмотреть сообщение
то скорость по второму варианту меня вполне устраивает. И мне видеться, что на допиливание этого варианта время потрачу меньше, чем на проработку использования DMA. Но эта позиция, конечно, спорная.
Вы же HAL используете, Куб за вас все сделает или воспользуйтесь примерами, что там "прорабатывать" ? Можете даже и не вникать в работу DMA, если уж так лень. Подготовили массив и выплюнули. Правда смысл есть, если массив большой, а не по точкам отрисовывать.
dkm вне форума  
Непрочитано 26.10.2019, 20:48  
ProtAS-13
Прописка
 
Регистрация: 17.03.2015
Сообщений: 287
Сказал спасибо: 0
Сказали Спасибо 209 раз(а) в 121 сообщении(ях)
ProtAS-13 на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Сообщение от Юрий_48 Посмотреть сообщение
Но ничего не изменилось.
Еще кое чего не хватает
Вы попадаете, как я уже сказал, в ситуацию, когда байт данных еще не передался полностью, а Вы уже "дергаете" DC:
Код:
TFT9341_Write8(r);
=====› Вот ЗДЕСЬ ‹======
CD_DATA;
Поэтому, нужно в этом месте анализировать конец передачи байта.
Делается это просто - анализируете флаг RXNE.
Приведу простой рабочий пример:

Нажмите, чтобы открыть спойлер
Код:
/**************************************************  *****************************
 * brief : Write LCD-Command with Parameters.
 * note  : This variadic function send LCD-Command to SPI.
 * param : size: number of parameters without command code.
 * param : codeCMD: command code
 * retval: None
**************************************************  *****************************/
void LCD_WriteCMD(uint16_t size, uint8_t codeCMD, ...)
{
  va_list vl;                               // Type to hold information about variable arguments
  va_start(vl,codeCMD);                     // Initialize a variable argument list
  LCD_CS_YES;                               // Chip select  (CS) -› ENABLE
  LCD_DC_COM;                               // Data/Command (DC) -› COMMAND
  while(!LL_SPI_IsActiveFlag_TXE(SPI2)){}   // Wait Tx buffer empty
  LL_SPI_TransmitData8(SPI2,codeCMD);       // Transmit command code
  SPI_WaitOneTransmitEnd(SPI2);             // Wait transmit command code
  LCD_DC_DAT;                               // Data/Command (DC) -› DATA
                                            // Transmit command parameters
  for (int i=0; i‹size; i++)
  {
    while(!LL_SPI_IsActiveFlag_TXE(SPI2)){}
    LL_SPI_TransmitData8(SPI2,(uint8_t)va_arg(vl,int));
  }
  SPI_WaitAllTransmitEnd(SPI2);             // Wait transmit full LCD-Command
  LCD_CS_NO;                                // Chip select  (CS) -› DISABLE
}
/**************************************************  *****************************
...
/**************************************************  *****************************
 * brief : Wait transmit one data frame (8- or 16-bit).
 * note  : After the last sampling clock edge the RXNE bit is set.
 *         When the SPI_DR register is read, RXNE bit is clearing.
 * param : SPIx: SPI Instance
 * retval: None
**************************************************  *****************************/
__STATIC_INLINE void SPI_WaitOneTransmitEnd(SPI_TypeDef *SPIx)
{
                                            // Wait last sampling clock edge
  while(READ_BIT(SPIx-›SR, SPI_SR_RXNE)!=SPI_SR_RXNE){}
  READ_REG(SPIx-›DR);                       // Clearing of the RXNE bit
}
/**************************************************  *****************************
 * brief : Wait transmit all data frames (n*8- or n*16-bit).
 * note  : The BSY flag is set when a transfer starts.
 *         It is cleared when a transfer is finished.
 *         In master mode, the BSY flag is kept high during all the transfers.
 * param : SPIx: SPI Instance
 * retval: None
**************************************************  *****************************/
__STATIC_INLINE void SPI_WaitAllTransmitEnd(SPI_TypeDef *SPIx)
{
                                            // Wait ending all transfers
  while(READ_BIT(SPIx-›SR, SPI_SR_BSY)==SPI_SR_BSY){}
  READ_REG(SPIx-›DR);                       // Clearing of the RXNE bit
}
ProtAS-13 вне форума  
Непрочитано 28.10.2019, 00:25  
Юрий_48
Частый гость
 
Регистрация: 24.10.2019
Сообщений: 13
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Юрий_48 на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Сообщение от ProtAS-13 Посмотреть сообщение
Вы попадаете, как я уже сказал, в ситуацию, когда байт данных еще не передался полностью, а Вы уже "дергаете" DC:
Код:
TFT9341_Write8(r);
=====› Вот ЗДЕСЬ ‹======
CD_DATA;
Поэтому, нужно в этом месте анализировать конец передачи байта.
Делается это просто - анализируете флаг RXNE.
ProtAS-13, Здесь что то не понимаю. Каким боком участвует флаг RXNE - он же относится к принимаемым "мной" данным. Ваше замечание о том, что "а Вы уже "дергаете" DC", я прочувствовал, спасибо. Но всё, что туда не подпихивал не давало эффекта. Единственный вариант, который заработал быстро и правильно это такой
Нажмите, чтобы открыть спойлер
void TFT9341_Write8(uint8_t dt)
{
//HAL_SPI_Transmit(&hspi1,&dt,1,1);
while (!(SPI1-›SR & SPI_SR_TXE));
SPI1-›DR = dt;
while (SPI1-›SR & SPI_SR_BSY);
}

Понятно, что это не совсем рационально, поскольку тут посылка нового байта происходит только, когда предыдущий полностью передался, но всё равно быстро.
Что касается Вашего примера, то в общих чертах он понятен, если не считать RXNE. Попробую разобраться более детально. Правда в первой функции что то не хватает. Не знаю сознательно это или случайно.
Юрий_48 вне форума  
Непрочитано 28.10.2019, 04:49  
ProtAS-13
Прописка
 
Регистрация: 17.03.2015
Сообщений: 287
Сказал спасибо: 0
Сказали Спасибо 209 раз(а) в 121 сообщении(ях)
ProtAS-13 на пути к лучшему
По умолчанию Re: ILI9341 + stm32f103c8t6

Сообщение от Юрий_48 Посмотреть сообщение
Но всё, что туда не подпихивал не давало эффекта.
Добавление анализа флагов в функцию "TFT9341_Write8" - это плохое решение.
Перенесите анализ BSY туда, где я написал "=====› Вот ЗДЕСЬ ‹======".
Т.е. в функции "TFT9341_WriteRegister32" у Вас должно ДВА раза анализироваться BSY.
Можно сделать и по другому - анализировать BSY перед изменение DC/CS.
Что касается RXNE.
Если перевести SPI в "full-duplex mode", то RXNE будет косвенно указывать на конец передачи КАЖДОГО одного байта (см. картинку).
Отличие "Transmit-only mode" от "full-duplex mode" лишь в том, что контакт входного сигнала (MISO) можно использовать как GPIO.
При этом нигде ЯВНО не описано, вырабатывается ли RXNE в "Transmit-only mode".
Если Вы SPI перевели в "Transmit-only mode", то можете попробовать в функции "TFT9341_WriteRegister32" вместо "=› Вот ЗДЕСЬ ‹=" поставить анализ RXNE, оставив в конце анализ BSY.
Если не сработает, то будем ТОЧНО знать, что флаг RXNE в "Transmit-only mode" не формируется.
Миниатюры:
Нажмите на изображение для увеличения
Название: pic1.jpg
Просмотров: 0
Размер:	190.5 Кб
ID:	146751  
ProtAS-13 вне форума  
Сказали "Спасибо" ProtAS-13
Юрий_48 (29.10.2019)
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ili9341 SPI dimdidim ARM 35 02.12.2018 20:29
Дисплей ILI9341 на STM32F429 по SPI radian ARM 4 12.11.2017 05:55
Продам три дисплея 3,2" ILI9341 AndrFV Барахолка электронных компонентов 2 19.09.2017 09:43
поворот графических элементов на любой градус ILI9341, stm32 dimdidim ARM 17 17.09.2016 21:06
STM32F103C8T6 Таймер и прерывание по окончании счета zeon13 ARM 13 23.08.2016 09:18


Часовой пояс GMT +4, время: 21:22.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot