*Внимание!* В видео рассматривается старый релиз библиотеки версии 1.1. Новый релиз (версия 1.4 ) библиотеки требует настройки DMA (Mode) не в режиме Circular, как в видео, а в режиме Normal. Свежий релиз доступен на гитхабе: github.com/vadrov/stm32-display-spi-dma Там же подробное описание использования и варианты решения проблем. Пожалуйста, не используйте версию 1.1. Подключение дисплея st7789 по spi c dma на CMSIS и LL рассмотрено в видео kzbin.info/www/bejne/bqWse2Rsp859p9E Подключение SD-карты по spi с dma на CMSIS и LL рассмотрено в видео kzbin.info/www/bejne/sGqck3-eodOooa8 Подключение кнопок на таймере с прерыванием на CMSIS и LL с устранением дребезга, автоповтором и буферов ввода (прямо как на PC 😉) рассмотрено в видео kzbin.info/www/bejne/m17aZnuJbJqhm8k Файловый менеджер (структура и код) рассмотрен в видео kzbin.info/www/bejne/apTCgaqkltiErNU Подключение аудио-цап (audio dac) по интерфейсу i2s на CMSIS и LL рассмотрено в видео kzbin.info/www/bejne/pmGsmYtjjc6cn7M К каждому из перечисленных видео есть ссылка в описании на проект для скачивания. Поддержать канал: yoomoney.ru/to/4100117522443917 Комплектующие в видео: плата разработки stm32f401ccu6 1.3" дисплей ST7789 (spi)
@Alexcymantrene2 ай бұрын
Огромное спасибо! Дай бог вам здоровья! Сделал на 411, все работает! Лайк, подписка! Кладезь знаний
@alexshu1609 Жыл бұрын
5:05 Настройки SPI 5:55 Переименуем ноги для SPI 6:45 Настройки SPI для дисплея 7:00 DataSize 16Bits 7:35 ClockPolarity Hight 8:15 Настроим DMA 8:42 Mode Circular (Кольцевой режим передачи данных из памяти в SPI) 8:55 DataWidth Half Word (Ширина передаваемых данных 16бит это пол слова ) 9:50 Настройка пинов(выводов) Res, DC 11:30 Назначаем ноги МК на выход и обзываем их 12:45 Выбор выхода подсветки BLK 13:05 TIM3->Channel1=PWM Generation CH1 14:40 Prescaler = 999 Делим частоту шины STM32 15:00 Counter Period = 209 Период счета от 0 до 209 15:05 Pulse = 104 Скважность ШИМ(PWM) (104 это 50% от 209) 17:07 Включаем Serial Wire :) 17:36 Отключаем HAL 18:30 Копируем библиотеку для дисплея в папку с проектом 18:37 Подключаем папку Библиотеки к Проекту(чтобы не прописывать полные пути для подключаемых библиотек) 19:16 В настройках проекта (MCU Post build outputs) Convert to binary file ставим галочку чтобы при компиляции проекта получить исполняемый файл для заливки в STM32 19:45 Optimization->Optimization level = Optimization for size чтобы бинарник был наименьшего размера 20:00 В main.c инклюдим "display.h" и "St77889.h" 21:00 Открываем "display.h" копируем прототип функции инициализзации и вставляем в main.c
@himikym Жыл бұрын
В данном коде есть косяк, указатель *lcd объявлен в main и по этому не доступен в других функциях что делает невозможным работу функций дисплея при их вызове из других функций. Как починить: объявляем указатель глобально LCD_Handler *lcd; а в main заменяем LCD_Handler *lcd = LCD; на lcd = LCD; это делает обработчик доступным из любого участка кода.
@VadRov Жыл бұрын
Никакого "косяка" нет. Список дисплеев LCD объявлен глобально в display.c и прописан "экстерном" в display. h Пользователю достаточно прописать "хидер" display. h в любом "сорце", и будет получен доступ к любому ранее созданному дисплею в функции main через список дисплеев LCD, где LCD указывает на первый созданный дисплей, LCD->next - на второй и т.д. Например, "перебрать" дисплеи в списке и вывести на них одно и тоже сообщение можно так: LCD_Handler *lcd = LCD; while (lcd) { LCD_WriteString(lcd, 0, 0,"Hello, world!", &Font_8x13, COLOR_YELLOW, COLOR_BLUE, LCD_SYMBOL_PRINT_FAST); lcd = lcd->next; } Теперь самое главное. Вы пишите о недоступности обработчика дисплея в других функциях, в том случае, если обработчик дисплея не объявить глобально. Вы, наверное, забываете о том, что любой функции можно передавать параметры (в соответствии с ее объявлением). Ничто не мешает передать в любую внешнюю функцию указатель на обработчик дисплея, созданный в функции main, а далее от этой функции в другую функцию и т.д. Далее. Переменная, созданная в main "живет" до окончания работы программы. Т.е. вы можете передавать указатель на эту переменную в любую функцию, и он будет всегда валиден, на весь период работы программы. Резюмируя. "Косяка" нет. Есть Ваше стремление к тому, что все переменные в программах должны объявляться глобально, чтобы их можно было использовать в любом месте (в любых функциях) программы. Подход понятный, но лично для меня неприемлемый. Я исхожу из того, что глобальную переменную следует использовать только тогда, когда без нее невозможно обойтись.
@VadRov Жыл бұрын
Я расширил свой ответ. Утром времени не было на более подробное изложение.
@ПавелШкурат-ъ6б Жыл бұрын
Добрый день. В Вашем коде при использовании на STM32F103C8T при настройке на ноги ругается на типы структур LCD_SPI_Connected_data и LCD_BackLight_data в частности типы uint16_t надо заменить на uint32_t. Это актуально для номеров пинов от 8.
@VadRov Жыл бұрын
Приветствую. Да, именно так и будет ругаться при номере пина от 8 до 15.
@gdv2306 Жыл бұрын
Уважаемый автор! Откуда у Вас такой уровень знаний? Как к этому прийти?
@VadRov Жыл бұрын
🙂Интерес, постоянное самообучение, чтение спецификаций и т.п.. Прийти к этому можно при наличии желания. Уровень знаний у меня небольшой (по моей оценке), есть еще куда стремиться.
@dmitriycold690611 ай бұрын
А под HAL ее не особо сложно будет переделать?
@VadRov11 ай бұрын
Несложно. Тут даже проще избавиться от LL, перейдя только на cmsis, и сделать её таким образом универсальной: подходящей и для hal, и для ll. Где-то у меня была такая версия (посмотрю после нг).
@andrezsa232 жыл бұрын
ПРИВЕТ очень хорошее видео есть функция которая позволяет мне печатать переменную какого-то датчика, как я могу добавить больше источников и печатать значки
@VadRov2 жыл бұрын
Здравствуйте. Значки можно печатать с использованием функции LCD_DrawImage(LCD_Handler* lcd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t *data, uint8_t dma_use_flag), где x, y - координаты левого верхнего угла значка на дисплее; w, h - ширина и высота значка, data указатель на блок данных с изображением выводимого значка в формате R5G6B5 (16 бит на точку); dma_use_flag - флаг, который определяет используется или нет DMA при выводе значка. Не понял про количество источников. Наверное, это погрешности перевода. Строку к печати можно подготовить, например, использовав функцию sprintf. Можете посмотреть видео про файловый менеджер. В проекте файлового менеджера используется вывод иконок файлов: kzbin.info/www/bejne/apTCgaqkltiErNU
@backtracklive2 жыл бұрын
Прикольно 😁 Перенёс Вашу библиотеку под F411, получил 55 кадров при отрисовке с циклом и 60 кадров без цикла. Частота 100 мГц) Крутая библиотека) Но это на версии, что на видео, новую не удалось завести пока что
@valikaleshevich16182 жыл бұрын
здравствуйте. а можете кодом поделиться?
@MrDred91Ай бұрын
У меня дисплей с ST7789V внутри(240х320). Вы в видео говорите, что полярность Clock в SPI нужно ставить в Hight, но с другой библиотекой у меня работает только в Low. Разве могут отличаться ST7789 и ST7789V? Даташит вроде один на все ST7789. Вашу библиотеку так и смог подключить. Не подскажите, куда копать? Видимо я что-то делаю не так.
@VadRovАй бұрын
К какому MCU подключаете?
@MrDred91Ай бұрын
К f411ceu6, использовал вашу новую библиотеку
@VadRovАй бұрын
@@MrDred91 , подтяжку линий spi к питанию (pull_up) делали?
@VadRovАй бұрын
Попробуйте этот проект для данного MCU: drive.google.com/file/d/1pHNDM6Lu4bAQuD1-xPyvwAucWCF7nRKr/view?usp=sharing
@MrDred91Ай бұрын
Нет, подтяжку не делал. Спасибо за ссылку, попробую!
@gorchitsАй бұрын
Не пойму что у меня за проблема, миллион раз все перепроверил. STM32F407VET6 + ST7789, компилирую и каждый раз разная картинка. То куска буквы нет, то черный экран, то вообще синий был почему то. Говорю про этот код: LCD_Handler *lcd = LCD; //указатель на первый дисплей в списке LCD_Init(lcd); LCD_Fill(lcd, COLOR_RED); LCD_WriteString(lcd, 0, 0, "Hello, world!", &Font_15x25, COLOR_YELLOW, COLOR_BLUE, LCD_SYMBOL_PRINT_FAST);
@VadRovАй бұрын
Подтяжка линий spi к питанию есть? /* SPI1 GPIO Configuration PA5 ------> SPI1_SCK PA7 ------> SPI1_MOSI */ GPIO_InitStruct.Pin = LCD_SCL_Pin|LCD_SDA_Pin; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; /* Подтяжка к питанию есть */ GPIO_InitStruct.Alternate = LL_GPIO_AF_5; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); Полярность тактового сигнала spi (см. в настройках spi параметр CPOL - Clock Polarity) - HIGH ?
@VadRovАй бұрын
Вот проект собрал под этот MCU+spi st7789: drive.google.com/file/d/183g06RgY7biFJ2kUptKJUNzSPKF4oTXB/view?usp=sharing Заработало с первого раза.
@gorchitsАй бұрын
@@VadRov Спасибо большое за проект! Запустил проект вышла такая штука, разбираюсь с ней: No source available for "Reset_Handler() at 0x8000794" .
@VadRovАй бұрын
@@gorchits , причина, наверное, в версии CubeIDE. У меня версия 1.15, а firmware для F4 версии 1.27.1
@gorchitsАй бұрын
@@VadRov странно, поставил версию 1.15 и firmaware F4 1.27.1. Ничего не выводится на экран, в этот раз при каждой компиляции. После того как запускаю в режиме дебагинга выскакивает "Reset_Handler() at 0x8000794" и No source available for "main() at 0x8000298"
@_Dmitry_Pavlov Жыл бұрын
Всё было понятно до "подключаем библиотеку". Где её взять и как скачать?
@VadRov Жыл бұрын
Ссылка на проект есть в описании к видео и в закреплённом комментарии.
@_Dmitry_Pavlov Жыл бұрын
@@VadRov , спасибо, я понял, но он по другому называется: stm32-display-spi-dma-main А в файле display.h из этого проекта вообще все по другому :( Если запустить программу без подключенных библиотек, хотя бы случайный набор пикселей на дисплее получится?
@VadRov Жыл бұрын
@@_Dmitry_Pavlov , Вы просто скачиваете демо-проект с гитхаба и открываете его в среде STM32CudeIDE. Собираете проект и прошиваете м/к. Если все правильно подключено, то на дисплее будет в течение двух секунд приветствие "Hello, world!". А дальше случайный фон и количество кадров заливки этим фоном дисплея в секунду. Описание есть на гитхабе.
@alexshu1609 Жыл бұрын
Вопрос на засыпку!!! Кто ни будь пробовал читать память экрана ? Там есть команда на чтение куска памяти и в ili93 и в st77 (причем код команды один и тот же 2Eh ) - а там по поводу оперативы очень жирно !!! . Но как бы MOSI у экрана есть, а MISO как бы нет . У экрана эти два вывода как бы к одному подключены, или нет? Это нужно для работы со спрайтами. Кто ни будь пробовал что либо делать в эту сторону . Как вы это сделали ? И что получилось? Ну или в какую сторону копать?
@VadRov Жыл бұрын
Приветствую 🙂 Копать надо в другую сторону. Есть нюансы при чтении памяти дисплеев. Я о них видос сегодня краткий выложу в качестве ответа.
@VadRov Жыл бұрын
Сегодня, к сожалению, не успеваю. github.com/vadrov/stm32-display-spi-dma скачайте обновление. Посмотрите функцию ReadImage. Я там набросал комментарии. Разберетесь. Отпишитесь по результату.
@alexshu1609 Жыл бұрын
@@VadRov Спасибо . Будем посмотреть
@VadRov Жыл бұрын
@@alexshu1609 , там еще корректировка будет. Проблема в том, что я работаю с контроллером, можно сказать, методом "обратного инжиниринга", т.к. спецификация оказалась еще тем фуфлом. Ну, впрочем, пока получается.
@VadRov Жыл бұрын
@@alexshu1609 , я его победил 🤣 t.me/vadrov_channel/73 Демка: github.com/vadrov/stm32f401ccu6_ili9341_ReadImage
@og3gpr10 ай бұрын
У мне не STREAM в DMA а LL_DMA_CHANNEL_3 из-за этого всё крашиться(
@VadRov10 ай бұрын
Правильно, значит у Вашего м/к другой контроллер DMA. На моем гитхабе есть аналогичный драйвер для stm32f0/g0 серии и stm32f103xx. Подойдет и для других серий м/к stm32 c аналогичным контроллером DMA. Какой у Вас м/к?
@VlNvm9 ай бұрын
Повторил все, что в видео. Получилось и на STM32F411. Подскажите пожалуйста, почему не получается запустить часы? Точнее с LSI работает RTC. А с внешним кварцем LSE зависает на строчке while(LL_RCC_LSE_IsReady() != 1) в фунции void SystemClock_Config(void). CubeIDE перед while сгенерировал две строчки: LL_PWR_EnableBkUpAccess(); LL_RCC_LSE_Enable();. Но наверное этого не достаточно? Что добавить или куда копать?
@VadRov9 ай бұрын
Какая версия CubeIDE у Вас? Может, флаг VOS опрашивается не там, где следует? У меня вот так работает на 411: void SystemClock_Config(void) { LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_3) ; LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_RCC_HSE_Enable(); while(LL_RCC_HSE_IsReady() != 1) ; LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_25, 200, LL_RCC_PLLP_DIV_2); LL_RCC_PLL_Enable(); while(LL_RCC_PLL_IsReady() != 1) ; while (LL_PWR_IsActiveFlag_VOS() == 0) ; LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) ; LL_Init1msTick(100000000); LL_SetSystemCoreClock(100000000); LL_RCC_SetTIMPrescaler(LL_RCC_TIM_PRESCALER_TWICE); }
@VlNvm9 ай бұрын
@@VadRovVersion: 1.15.0
@VadRov9 ай бұрын
@@VlNvm , до 1.15 не обновлялся. У меня 1.14.1. С моим кодом работает?
@VlNvm9 ай бұрын
@@VadRovмои ответы здесь исчезают :(.
@VadRov9 ай бұрын
@@VlNvm , отправил скрин настроек тактирования. Ваши комментарии на почте вижу, а здесь нет. Глюки ютуба, скорее всего.
@MrDrunkHedgehog Жыл бұрын
Уважаемый автор! Подскажите, как к Вашей библиотеке подключить сторонние шрифты? Сам я не осилил этот момент. Очень надо=)
@VadRov Жыл бұрын
Качаем программу PixelFontGenerator: drive.google.com/open?id=105Z92oXuPc31tbzNCNSIot0m41IIiUxG Формируем код для требуемого шрифта с нужным размером (ширина на выходе до 32 пикселей). Вставляем код в библиотеку (fonts.h, fonts.c), подредактировав его по аналогии с имеющимися в библиотеке шрифтами.
@MrDrunkHedgehog Жыл бұрын
@@VadRov Спасибо! Есть ли способ вывести шрифт шириной больше 32 пикселей? Мне нужны крупные циферки шрифта Arial.
@VadRov Жыл бұрын
@@MrDrunkHedgehog , способ есть всегда. Если хранить символы большого размера в памяти, то это потребует много flash памяти. Выход есть. Как вариант, масштабирование символа методом "ближайшего соседа". Если символ на выходе получится "угловатым", то можно применить сглаживание.
@MrDrunkHedgehog Жыл бұрын
@@VadRov Понял, ещё раз спасибо!!
@TheDJs3000 Жыл бұрын
Спасибо! Искал что-то подобное.
@ЕКББерезовский11 ай бұрын
Подключил дисплей ST7789 к микроконтроллеру STM32401RCT6. Заливка экрана выполняется. Текст на экран выводится. Количество кадров вычисляется. Но выявился глюк при выполнении процедуры LL_mDelay(mls). Вставил процедуру задержки между перечисленными выше операциями. При выполнении программы, если mls > 150 происходит блокировка(зависание) . При нажатии кнопки reset на контроллере зависания иногда не происходит. Это мой второй эксперимент с мк STM32. Первый - мигающий диод. Длина проводников от мк до дисплея - 10 см. Опыта как такового нет( Чтобы это могло быть?
@VadRov11 ай бұрын
Отредактируйте мой вот этот комментарий, чтобы код был, как у Вас: while (1) { frames = 0; tick = millis; while (millis - tick < 1000) { LCD_Fill(lcd, (r
@VadRov11 ай бұрын
Еще такой момент. Вы читали описание возможных проблем на гитхабе? Там одной из проблем названо отсутствие подтяжки к питанию сигнальных линий SPI (особенно важно для дисплея st7789). Вот как раз такое поведение с reset и может вызвать эта проблема.
@ЕКББерезовский11 ай бұрын
@@VadRov Сделал. Откомпилировал. прошил. После выполнения кода на экране отображается число 47 на серо-синем фоне. Спустя 10 секунд экран гаснет. Это же повторяется после нажатия кнопки reset на плате контроллера.
@VadRov11 ай бұрын
@@ЕКББерезовский , скиньте проект на почту. Так быстрее будет.
@ЕКББерезовский11 ай бұрын
@@VadRov Скинул.
@NoviSavvy10 ай бұрын
Очень, очень сложно всё это запустить, пока что не удаётся.. Как вы до этого дошли? У меня весь код написан на HAL, вывод одной строчки на дисплей тормозит весь код на 0.8 секунды. МК f334. Переписать всё на LL это ещё года полтора нужно, как с HAL эту же библиотеку подключить, подскажите пожалуйста?
@VadRov10 ай бұрын
Какой м/к и дисплей?
@NoviSavvy10 ай бұрын
@@VadRov F334 и ST7789 240x240
@VadRov10 ай бұрын
@@NoviSavvy , spi и dma для stm32f33x в целом аналогичны stm32g0 серии. Вот ссылка на демо-проект с моим драйвером для stm32g0 серии. Драйвер на CMSIS, т.е. инициализацию используемой периферии можно делать и на CMSIS, и на HAL, и на LL (в проекте инициализация на LL). Если будете использовать HAL, то в обработчике канала DMA, обслуживающего SPI (см. файл stm32xxxx_it.c) закомментируйте вызов обработчика HAL и пропишите обработчик драйвера дисплея Display_TC_Callback с соответствующими параметрами (в случае с LL просто пропишите этот обработчик). Номера каналов таймера для подсветки и DMA указывайте непосредственно цифрами, как в примере. Первому каналу таймера соответствует цифра 1, второму - 2 и т.д., аналогично с DMA. drive.google.com/file/d/10l37EzC4NxO1LesGLQnjfyV8bf80cOyJ/view?usp=sharing Попробуйте создать аналогичный проект, но на HAL и подключите к проекту этот драйвер дисплея.
@NoviSavvy10 ай бұрын
@@VadRov Большое спасибо! Буду пробовать
@coronas14 Жыл бұрын
Отличная работа. Прекрасный пример для F411, но не могли бы Вы, уважаемый VadRov, показать как Вашу библиотеку совместить с LVGL. Я уже написал Вам в Дзене. Инициализация дисплея Вашей библиотекой проходит на Ура, но вот вывести текст посредством LVGL уже не получается. Могу прислать Вам весь проект если скажете как и куда - выкладывать на всеобщее обозрение пока не готов так как все оооочень сыро.
@VadRov Жыл бұрын
Здравствуйте. Для LVGL, насколько знаю, надо написать функцию вывода блока данных на дисплей, в которой связываются LVGL и дисплейный драйвер. Параметры этой функции - координаты окна и блок данных для пересылки на дисплей. Блок данных на дисплей отправляется функцией моей библиотеки LCD_DrawImage(LCD_Handler* lcd, uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint16_t *data, uint8_t dma_use_flag). Написали ли Вы связку LVGL с драйвером? Прислать проект можно на почту (в описании канала -"О канале"), но я, честно говоря, не люблю "ковырять" чужие проекты, т.к. в них приходится иногда долго вникать.
@coronas14 Жыл бұрын
@@VadRov Спасибо. Я отправил Вам письмо. Я предполагаю, что ошибся только в одном месте.
@VadRov Жыл бұрын
@@coronas14 , ответ с проектом смотрите на своей почте 😉
@DIMAL Жыл бұрын
Прикольно, но чесговоря не понял каким образом фреймбуффер в 240*240 байт влезает в стэк размером 0х400 :\
@VadRov Жыл бұрын
А нам не нужен фреймбуфер. Мы волшебники.🙂 Для заливки одним цветом используется всего 2 байта из памяти - цвет заливки в формате 16 бит. У самого дисплея память есть, в которую мы пишем цветовые данные, передавая их по spi.
@DIMAL Жыл бұрын
@@VadRov Обычно на стороне проца делают буффер на весь экран, и далее запускают ДМА в кольцевом режиме для поточного обновления дисплея. Дальнейшая работа с экраном сводится к записи нужной инфы в тело буффера, это происходит асинхронно, на высокой скорости. При этом проц не блокируется на промежуток передачи. В вашем варианте видимо при каждой отправке, дма передает только тот кусок - который необходимо обновить, это выгодно для всяких менюшных дел, но если требуется гнать видеопоток, то такой способ автоматом превращается в метод описанный выше.
@VadRov Жыл бұрын
@@DIMAL , все правильно, и я вообще не спорю с тем, что имея МК за *= 100 р. и внешнюю RAM (если необходимо), а не МК за 200-300 р. и полное отсутствие внешней RAM можно более эффективно решать задачи. А пока имеем то, что имеем, т.е. рассматриваемый нами сейчас вопрос вообще выходит за рамки предмета рассмотренного в видео, т.к. применим к иному классу МК (в которых могут быть к тому же интерфейсы FSMC, LTDC, аппаратное ускорение графики, аппаратные декодера jpeg и пр.). Описанный Вами способ с фреймбуфером позволяет не только "гнать поток", например, по spi средствами DMA, работающем в кольцевом режиме, но и делать всякие более эффективные, с позиций производительности, "штучки" типа прозрачности для OSD и прочего смешивания/наложения цветов. Это все известно и применимо в том случае, если есть необходимое количество RAM и производительное ядро. Теперь спустимся на землю. 🙂Что касается видеопотока. Давайте порассуждаем. У нас есть, допустим, программный декодер и пусть будет полнокадровый фреймбуфер (хотя, здесь он для этого МК невозможен) с кольцевым DMA. Ядро пусть будет то же, что и в этом видео (cortex-m4f) и пусть работает на той же частоте (84 МГц). Соответственно, самое шустрое spi для этой конфигурации даст max 42 Мбит/с. Фреймбуфер 240х240х2 = 115 200 байт. Т.е. предел для указанной скорости у нас в районе 46 кадров в секунду (что и показано в этом видео при заливке дисплея). Возвратимся к видеопотоку. Пусть видеопоток будет из последовательности jpeg изображений 240х240 px (например, avi с видеопотоком типа motion jpeg). Допустим, мы не слишком сильно заморачивались с написанием декодера, но немного все-таки вспотели и получили при не самом плохом качестве, что один кадр декодируется во фреймбуфер в среднем за 70 мс, что соответствует примерно 14 кадрам в секунду при доступном максимуме в 46 кадров/с. Для такого примера отпадает всякий смысл во фреймбуфере (который к тому же здесь невозможен), т.к. с учетом накладных расходов на организацию лишних spi посылок можно получить те же 12-13 кадров/с, но без фреймбуфера. А если поднапрячь мозг, то можно получить и 20-25 кадров, да еще со звуком и с "водяными знаками" поверх видеокадров и все без фреймбуфера на 64 кБ RAM. Еще раз. Я все прекрасно понимаю, но давайте исходить из того, что есть, т.е. нет у нас памяти под полнокадровый фреймбуфер. Но это не значит, что ничего сделать нельзя. Можно сделать то же самое и без фреймбуфера. Для этого и существует программирование, чтобы решать задачи. Я так думаю. Вот, кстати, пример без фреймбуфера в моем телеграмме: t.me/vadrov_channel/66 Ну, это же не просто менюшки. А фоном может быть и видео со звуком. Все делается. Вопрос в цене (временные затраты на разработку и оптимизацию).
@АндрейВласов-п2п Жыл бұрын
Не работает. Возможно дело в новой библиотеке. Два раза пошагово прошел все. Ошибок не вижу. Собирается и заливается нормально. Но не работает. По своим причинам делал на SPI2 и TIM1, но не думаю, что в этом причина.
@VadRov Жыл бұрын
Версия cube? Дело не в новой версии. Она обкатана в множестве программ. Исходник проекта отправьте мне на почту из описания канала (о канале из версии для ПК)
@АндрейВласов-п2п Жыл бұрын
@@VadRov Написал. Для тех, кто еще будет это читать. Не знаю пока в чем проблема, но похоже, что в работе с драйверами LL, а не в библиотеке автора.
@VadRov Жыл бұрын
Добрый день. Проблема, как я писал в телеграм t.me/vadrov_channel/81 в разработчиках cube. Удалите строчку while (LL_PWR_IsActiveFlag_VOS() == 0) { } в функции SystemClock_Config
@АндрейВласов-п2п Жыл бұрын
В итоге оказалось, что у автора с кодом все в порядке. Проблема действительно в LL-драйверах. Конкретно не запускался таймер для сигнала яркости.
@VadRov Жыл бұрын
Андрей, TIM1 является таймером с расширенным управлением, в котором присутствует регистр BDTR. Для включения выхода/выходов таймера необходимо устанавливать бит MOE этого регистра. В настройках таймера среды cubemx необходимо задать параметр Automatic Output State в значение Enable либо скорректировать, код инициализации таймера, например, для LL: TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_ENABLE; У Вас этот параметр был в состоянии "Отключено" (DISABLE). Как вариант, также на "на регистрах" в коде включения таймера/счетчика/канала можно прописать так: TIM1->BDTR |= TIM_BDTR_MOE;
@egordpua Жыл бұрын
Здравствуйте. использую версию: 1.1 LL на STM32F103C8Tx Уменя не работал дисплей через DMA, кофигуратор расположил MX_DMA_Init(); в конце списка, после перемещения его перед MX_SPI1_Init(); DMA заработал. При использовании функций драйвера вне функции main.c (где определяется LCD_Handler *lcd = LCD_Create ... ) выдает ошибку: 'lcd' undeclared. Помогите решить эту проблему.
@VadRov Жыл бұрын
Приветствую. Я так понимаю, у Вас старая версия STM32CubeIDE, если конфигуратор располагает инициализацию DMA после инициализации SPI. Желательно обновиться. Второе. Пожалуйста, не используйте 1.1 версию она морально и интеллектуально (🙂🙂) устарела. Я, вроде, на нее ссылки удалил. Версия 1.4 эффективнее и грамотней. Upd.: не надо проект присылать. я понял в чем проблема. Ниже комментарий.
@VadRov Жыл бұрын
LCD_Handler *lcd; объявите глобально, т.е. вне тела main, например, после includ-ов. Конечно, он не видит переменную вне main, т.к. она локально объявлена в main. Если lcd будете использовать вне файла main, то пропишите в тех файлах, где будете ее использовать extern LCD_Handler *lcd; Совет. Перейдите на версию 1.4
@egordpua Жыл бұрын
Спасибо за быстрый ответ. Разобрался ! Я объявлял глобальную переменную LCD_Handler *lcd , затем в main объявлял локально LCD_Handler *lcd, а это новая, совсем другая lcd, ...Так можно долго "объявлять" )
@VadRov Жыл бұрын
@@egordpua , скидывайте проект на почту (в описании канала). Так будет быстрее.
@VadRov Жыл бұрын
@@egordpua , а я вот только Вам хотел об этом написать, потому что мне присылали уже пару проектов, в которых пытались использовать и локальную, и глобальную переменную с одним именем. Бывает. Помню в 90-хх турбо С на подобное ругался, а потом такое стало нормой, а, может, ошибаюсь. Давно это было 🙂
@xxxx9320 Жыл бұрын
Что-то не получается пока запустить на f103 дисплей GMT020-02 320x240 (ST7789V, без BLK вывода). С другой библиотекой работает (она жутко медленная, тупое переключение spi и т.п.). DMA пока вырезал. По другим регистрами есть несоответствие с f401? Или куда копать?
@VadRov Жыл бұрын
SPI в stm32F103 такой же, как в stm32F401, а DMA такой же как в серии stm32G0. Для серии stm32g0 есть проект на моем гитхабе. Если "скрестить" два проекта, то должно получиться что-то типа этого: drive.google.com/file/d/107oePGideK91Tk8abCDTH0n3BkbwIDs0/view?usp=sharing "Состряпал на скорую руку" и не проверял. Попробуйте. В принципе, должно заработать. Правда, подключено к spi1, где скорость ограничена 18 Мбит/сек. Ну, и разрешение дисплея в проекте скорректируйте.
@VadRov Жыл бұрын
Это пример для stm32f103c8t6.
@xxxx9320 Жыл бұрын
@@VadRov О спасибо, дисплей заработал (только таймер не срабатывает, millis не считаются, но это уже не проблема)
@VadRov Жыл бұрын
@@xxxx9320 , там еще надо millis прописать volatile: /* USER CODE BEGIN PTD */ volatile uint32_t millis = 0; /* USER CODE END PTD */ т.к. у нас millis изменяется в прерывании, и компилятор должен знать об этом при каждой итерации в цикле ожидания.
@xxxx9320 Жыл бұрын
@@VadRov разобрался, благодарю! Не хватало строчки: /* USER CODE BEGIN SysInit */ //настраиваем системный таймер (прерывания 1000 раз в секунду) SysTick_Config(SystemCoreClock/1000); /* USER CODE END SysInit */ Получил ~16fps (для 240x320)
@IvanEng747 Жыл бұрын
А интерфейс 8080 на 8 или 16 бит - быстрее DMA или SPI?
@VadRov Жыл бұрын
Если я правильно понял смысл Вашего вопроса, то ответ такой. Параллельный интерфейс, естественно, гораздо быстрее SPI, являющегося последовательным (в силу значительной разницы в ширинах шины данных). В свою очередь, 8-битный параллельный интерфейс медленнее аналогичного 16-битного (шина-то Уже). DMA можно применять не только для spi, но и для параллельного интерфейса, например, при использовании периферии FSMC в МК, если она доступна. В таком случае DMA настраивается на режим mem-to-mem. На реальных задачах скорость с DMA выше для обоих случаев (и для последовательного, и для параллельного интерфейсов). А вообще в видео показан дисплей с последовательным интерфейсом.
@IvanEng747 Жыл бұрын
@@VadRov Спасибо. Вы знаете, чем отличие драйвера дисплея ST7789V от ST7789? Даташиты сравниваю и не вижу разницы... Разве, что наличие VSYNC INTERFACE. Оно?
@VadRov Жыл бұрын
@@IvanEng747 , если честно, то даже голову по этому поводу не ломал, потому что этих версий контроллеров, как и разных версий спецификаций на них в сети очень много (vw, s, h2, v3... и прочие). Лично для меня главное отличие таких и подобных дисплеев - это как в контроллере организована карта памяти: альбом или портрет. От этого зависит то, как мы будем определять активное окно для вывода информации о цвете.
@IvanEng747 Жыл бұрын
@@VadRov Подскажите, ваша библиотека совместима с функциями adafruit? Библиотека обрабатывает только SPI подключения или возможен и параллельный 8080-интерфейс? При работе через DMA - 16 бит данных из МК сразу попадают в ROM памяти дисплея, минуя флеш память МК?
@VadRov Жыл бұрын
@@IvanEng747 , что понимается под adafruit? Adafruit - это компания-производитель "интересных штучек", adafruit - это дисплей от одноименной компании или adafruit - это библиотека? Если adafruit - это дисплей и он на контроллере st7789 или ili9341 с разъемом под spi, то работать будет. Если adafruit - это библиотека, то никогда не ставил перед собой цели делать совместимое с чем-то "чужим" по функциям и т.п.. Если смотрели видео, то я говорю, что *представленный* *драйвер* *дисплея* *работает* *со* *spi* *дисплеями.* Ну, а последний вопрос непонятен. Во-первых, известно, что DMA работает только с RAM, с flash не работает. Во-вторых, у дисплея "экранная память" - это такая же энергозависимая RAM память, как и у микроконтроллера. DMA непосредственно направляет данные из RAM памяти в периферию (spi). Если надо отправить данные из flash памяти МК на дисплей с использованием DMA, то сначала придется скопировать данные из flash в RAM, а затем запустить процесс передачи через DMA, так, повторюсь, DMA работает только с RAM (и это ни Вы, ни я изменить не может, так решил изготовитель микроконтроллера).
@allallall23212 жыл бұрын
Спасибо большое!)
@valikaleshevich16182 жыл бұрын
код не собирается на сегодняшний день (хотя последний коммит в гите пару дней тому)...
@VadRov2 жыл бұрын
Какие сообщения выдает?
@VadRov2 жыл бұрын
Сейчас попробуйте. Кто-то в мейне (main.c) съел две косых черточки в самом начале кода (в комментировании). 🤣
@valikaleshevich16182 жыл бұрын
@@VadRov да, собралось и даже заработало кое-как на 411 МК!! сейчас пощагово смотрю ваше видео, собираюсь так сказать портировать ваш код на 411 МК. проблема усугубляется тем, что я в последний раз брался за Си-код лет 15 тому и уже даже забыл кое-какие ключевые слова и вообще семантику. но ничего, главное что дисплей хоть что-то показал, а то до сегодняшнего дня мне удалось только какую-то одну ардуино-библиотеку заставить его хоть что-то рисовать, но и там была масса нюансов да и ардуино-либы мне и даром не нужны. в общем спасибо вам огромное! буду дерзать!..))
@VadRov2 жыл бұрын
@@valikaleshevich1618 , вот для 411 проект: drive.google.com/file/d/1CZy-chLyj962SopGKMDD8xdpRuJh7q14/view?usp=sharing
@valikaleshevich16182 жыл бұрын
@@VadRov а этот не работает, хоть и собрался без ошибок (за исключением одного объявления, там нужно было добавить...). не работает - то есть просто ничего не выводит вообще. тогда как собранный 401, как он есть на гитхабе, и тупо залитый в 411 все же показывает начальный "хеллооу ворлд", потом какие-то цифры в углу.. а дальше как будто бы синхронизация срывается или типа того. в общем я не знаю как диагностировать проблему. аж расстроился...
@sergatmel8242 Жыл бұрын
Спасибо !
@avr_stm_pro29552 жыл бұрын
Взял бы исходник выложил ,
@VadRov2 жыл бұрын
Он выложен вообще-то.
@VadRov2 жыл бұрын
У меня когда -то очень давно там был аккаунт, который я не пользовал. Если есть острая необходимость в этом коде на гитхабе, то можно и залить.
@VadRov2 жыл бұрын
Свежий релиз библиотеки из этого видео доступен на гитхабе: github.com/vadrov/stm32-display-spi-dma А что не работает? У меня, вроде, все мои "хотелки" работают с кучей прерываний и внешней периферией, в т.ч., висящей на одном spi.
@VadRov2 жыл бұрын
@KEEP CALM and BE GAMER , только что специально скачал в гугл-драйва тот старый проект и собрал его в разных вариациях для двух разных дисплеев: st7789 и ili9341 и трех камней: 401ccu6, 411ceu6 и 407vet6. Все варианты сборок работают так, как и запрограммировано. Собственно, есть вопросы: 1. Какая скорость spi используется. 2. Какой дисплей подключается. 3. Какая плата (микроконтроллер) используется. 4. Какая среда разработки используется. Да, а сборка ругается только на дубль объявления переменной millis (я не стал тогда перезаливать проект на гугл-драйв).
@VadRov2 жыл бұрын
@KEEP CALM and BE GAMER , получается, что проблема в работе с памятью. А без DMA работает, если закомментить DMA2 и поставить вместо нее 0 в строке: LCD_DMA_TypeDef dma_tx = { 0 /*DMA2*/, LL_DMA_STREAM_3 };?