08.07.2016, 18:27
|
|
Частый гость
Регистрация: 13.06.2016
Сообщений: 37
Сказал спасибо: 6
Сказали Спасибо 2 раз(а) в 1 сообщении
|
ili9341 SPI
Всем привет. Есть желание разобраться с кодом для дисплея ILI9341 для STM32 на HAL. Если использовать SPI 8 бит вроде бы как все работает, но очень медленно даже на прерываниях - заливка экрана около 1 секунды. Если слать данные через DMA ( HAL_SPI_Transmit_DMA вместо HAL_SPI_Transmit_IT), то результат такой же (все те же 8 бит) - медленное обновление.
Как для HAL организовать шуструю отправку данных на дисплей (заливка, рисование, текст, картинки)? С 16 битным режимом на HAL странность какая-то, в stm32f1xx_hal_spi.h все функции передачи данных только 8 бит.
Поделитесь, пожалуйста, примером для HAL для этого дисплея.
|
|
|
|
08.07.2016, 18:34
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: ili9341 SPI
Не должно такого быть. 100мс предел. Какая скорость интерфейса?
|
|
|
|
08.07.2016, 18:44
|
|
Частый гость
Регистрация: 13.06.2016
Сообщений: 37
Сказал спасибо: 6
Сказали Спасибо 2 раз(а) в 1 сообщении
|
Re: ili9341 SPI
STM32F103C8 частота 72 МГц, прескалер для SPI 4 - частота SPI 18 МГц, DC и CS вручную дергаю (даже если NSS включить в SPI, и не дергать 1 пин вручную, то на скорость не влияет)
Цитата:
|
// шлем команду
void LCD_SendCommand(uint8_t com) {
HAL_GPIO_WritePin(TFT_DC_PORT, TFT_DC_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(TFT_CS_PORT, TFT_CS_PIN, GPIO_PIN_RESET);
HAL_SPI_Transmit_DMA(&hspi1, &com, 1);
HAL_GPIO_WritePin(TFT_CS_PORT, TFT_CS_PIN, GPIO_PIN_SET);
}
// шлем данные
void LCD_SendData(uint8_t data) {
HAL_GPIO_WritePin(TFT_DC_PORT, TFT_DC_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(TFT_CS_PORT, TFT_CS_PIN, GPIO_PIN_RESET);
HAL_SPI_Transmit_DMA(&hspi1, &data, 1);
HAL_GPIO_WritePin(TFT_CS_PORT, TFT_CS_PIN, GPIO_PIN_SET);
}
|
Последний раз редактировалось dimdidim; 08.07.2016 в 18:52.
|
|
|
|
08.07.2016, 19:55
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: ili9341 SPI
У вас разрешение 1024х768 что ли?
|
|
|
|
09.07.2016, 10:26
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: ili9341 SPI
Эк вы там наворотили со своим ХАЛом, что скорость заливки аж в 10 раз упала, и это на 72 МГц то!
Блин, я как-то по-приколу на ПИК16 на 8 МГц за полсекунды заливал дисплей и даже с неким формируемым на ходу изображением. Ну правда по параллельному интерфейсу... Но у вас - СПИ на 18 МГц - и вдруг 1 сек на заливку - эт надо еще постараться так.
То есть, вы еще и неправильно с самим дисплеем работаете - вероятно, для каждого пикселя передаете сначала команду записи, а затем данные одного пикселя?
Не разбираюсь в ХАЛе, но судя по функции, у вас там в функциях один байт команды или один байт данных передается, и каждый байт - дергание CS. При вызове функции, вы берете один байт (а это половина или даже треть пикселя, в зависимости от режима), дергатете CS и D/C, заталкиваете зачем-то в DMA этот один байт, DMA каким-то образом передает этот один байт в дисплей, и вы обратно убираете CS. И так каждый раз. Вот и зачем вам DMA, если вы передаете по одному байту за раз от одного вызова функции? Вы в DMA должны запихнуть некий массив, ну хотябы одну строку дисплея, чтоли, а желательно, часть кадра дисплея. И пусть DMA сам передает. По окончании передачи буфера можно будет снова поднять CS, если желаете.
И вообще, команду записи в дисплей Memory Write (0х2C, однобайтная) можно передать лишь один раз, и дальше передавать данные пикселей непрерывным потоком, до конца фрейма (кадра). В принципе, новый кадр можно начинать тоже без передачи Memory Write, если не требуется никаких изменений в формате вывода.
CS вообще дергать в каждом байте не нужно. Данные могут передаваться сплошным потоком, перед этим выставив CS в 0. Количество байт для пикселя будет зависеть от настроенного ранее режима дисплея.
Например, вот так, для 65k цветов:
Размер буфера дисплея для полного фрейма при 65k цветов потребуется в 150 кбайт, а столько есть не у всех МК. Но сам дисплей умный - у него есть команды для назначения блока записи (чтения) произвольного размера, в пределах которого будет перерисовываться дисплей. По умолчанию, после включения дисплея размер блока равен полному размеру кадра дисплея.
Последний раз редактировалось NewWriter; 09.07.2016 в 12:56.
|
|
|
Сказали "Спасибо" NewWriter
|
|
|
09.07.2016, 19:41
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.11.2010
Адрес: г. Дзержинск Нижегородская обл.
Сообщений: 1,734
Сказал спасибо: 130
Сказали Спасибо 1,112 раз(а) в 530 сообщении(ях)
|
Re: ili9341 SPI
Да... Использовать DMA для пересылки одного байта - это вообще за пределами добра и зла. Это все должно работать немного по другому.
Замечания:
1) CS не дергай. Данный вывод предназначен для адресации устройств на шине. У тебя единственное устройство на шине? Если - "да" - выстави его в активное состояние и не трогай.
2) Все ( многие) подобные чипы не требуют пересылать каждый пиксель "отдельной" командой. Выставил начальные координаты, дал команду "запись" и дальше непрерывный поток данных в видеобуфер. И до заполнения экрана. Писать каждый пиксель отдельно конечно можно, но скорость ...
Обычно, если есть место в ОЗУ, делают так:
1) Выделяют 2 буфера, каждый размером в видеопамять чипа.
2) Заполняют буфер данными
3) Запускают через DMA копирование в видеочип.
4) Далее заполняют следующий кадр в втором буфере. Первый скорее всего уже с копировался. Но можно проверить.
5) Стартуем DMA с второго буфера, а сами рисуем в первый.
Смысл - в параллельной работе. Пока DMA пихает данные в SPI мы не теряя времени готовим следующий кадр.
В любом случае нужно сначала дать команду "запись", а потом льем массив данных. Целиком. Не забыв дать команду типа "GotoXY 0,0".
|
|
|
Сказали "Спасибо" DanilinSA
|
|
|
10.07.2016, 10:53
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: ili9341 SPI
Однако, не зря ведь этот дисплей такой умный и с таким обширным набором команд.
Допустим, выводится текстовая строка, ну или перерисовывается какая-то небольшая область. Для этого нет необходимости использовать буфер размером в полный кадр. При выводе текстов на каком-то произвольном фоне достаточно иметь буфер размером например в одну текстовую строку.
Для этого, воспользуемся командами установки области - CASET (Column Address Set) и PASET (Page Address Set). Эти команды устанавливают номера начальных и конечных столбцов и строк, пересечения которых будут давать область, в которой и будет вестись чтение и запись дисплея (сразу после включения или сброса дисплея размер области равен всему кадру от 0, 0 до 240, 320).
Каждая команда передается пятью байтами - код команды и 4 байта, содержащие номера начала и конца строк или столбцов.
После установки области подается команда чтения видеопамяти дисплея Memory Read. Теперь можно считывать содержимое установленной области в буфер МК размером в эту самую область - одна текстовая строка. В буфере МК накладываем текст на прочитанный фон. Затем посылаем в дисплей команду Memory Write и отправляем содержимое буфера. В дисплей оно будет записываться с начального адреса установленной ранее области.
Для заполнения следующей текстовой строки подаются две команды установки нового положения области чтения/записи и все повторяется.
Но вот если требуется заменить один текст другим, фон все же придется сформировать заново, чтобы затереть предыдущий текст.
Конечно, при заполнении большого количества текстовых строк такой способ по скорости окажется медленнее, чем перерисовка полного кадра из буфера, но зато можно сэкономить на оперативке МК.
Для МК со сравнительно небольшим размером оперативки вариантов практически нет, кроме как использовать внешнюю скоростную SRAM, либо передавать в дисплей частями.
Ну, вобщем, до этого топикстартер еще не скоро доберется Ему б одолеть хотябы одноцветную заливку с частотой раз 5 в секунду.
Сообщение от DanilinSA
|
Не забыв дать команду типа "GotoXY 0,0".
|
Когда передается команда Memory Write (Memory Read), запись (чтение) начнется с начала установленной ранее области, независимо от того, где остановилась предыдущая запись (чтение). Если область не менялась на другую после включения дисплея, то начнется с координат дисплея 0, 0.
Другая пара команд - Memory Write (Read) Continue не будет менять текущей позиции и запись (чтение) продолжится с того места, откуда оно было прервано.
Сообщение от DanilinSA
|
если есть место в ОЗУ,
|
-›
Сообщение от dimdidim
|
STM32F103C8
|
◾Memories
◾20 Kbytes of SRAM
Другого выбора у топикстартера просто нет. Либо внешняя скоростная SRAM (благо, с точки зрения МК она будет как бы единим адресным пространством), либо передача небольшими блоками. Размер блока на вскидку, примерно 240*24 или для ровного счета 240*16. (при этом, если ведется запись без чтения, то передавать команды установки области не нужно, можно просто приостанавливать передачу в дисплей, формировать новое изображение в RAM и отправлять в дисплей).
При внешней SRAM скорость заполнения полного кадра окажется невысокой. Особенно, если продолжить использование ХАЛ (и в частности SPI), то о каком-то практическом применении - рисование, картинки - можно будет забыть. Всё-таки, это довольно большой, да еще и цветной дисплей.
Монохромные типа 128*64 (или даже больше) - запросто без заморочек, да. Всего-то 1 килобайт видеобуфера на полный кадр, 1 байт - 8 пикселей, а у ILI9341 - один байт на полпикселя при 65k цветов. И есть даже режим 262k цветов с 18 битным цветом, размещенным в трех байтах для каждого пикселя... А пикселей-то 76800, как бы вотьььь...
PS. У дисплея есть еще 8 вариантов развертки, то есть, поворота изображения и направления вывода. Это отдельная тема для пое%$@
Последний раз редактировалось NewWriter; 10.07.2016 в 12:28.
|
|
|
Эти 2 пользователя(ей) сказали Спасибо NewWriter за это сообщение:
|
|
|
10.07.2016, 13:44
|
|
Заблокирован
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
|
Re: ili9341 SPI
Понаписали всякой хрени от нехрен делать! Начните сначала. ХАЛ - гавно, СПЛ - гавно, ардуина - гавно! Есть можно, но можно отравиться и пользы никакой. Хотите скорости? Берите калькулятор, считайте максимальную теоретичкскую скорость, изучайте железо МК и воплощайте свою мечту. В большинстве случаев получение скорости близкой к максимальной не такая уж заоблачная задача.
|
|
|
|
10.07.2016, 19:04
|
|
Частый гость
Регистрация: 13.06.2016
Сообщений: 37
Сказал спасибо: 6
Сказали Спасибо 2 раз(а) в 1 сообщении
|
Re: ili9341 SPI
NewWriter, спасибо, подойду к проблеме по-другому
я приемов работы с дисплеями пока не очень знаю, так как только начал ковыряться в них, поэтому такие у меня грабли, как и у большинства, наверно
UP.. Да, передавать массивами значительно быстрее, чем попиксельно. Так можно добиться приличной скорости обновления экрана и без DMA
Последний раз редактировалось dimdidim; 11.07.2016 в 11:55.
|
|
|
|
10.07.2016, 23:17
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: ili9341 SPI
dimdidim, так ведь в даташите на драйвер дисплея всё есть
Вы его даже не скачивали, правда?
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 02:55.
|
|