LAS9891 0 9 января, 2021 Опубликовано 9 января, 2021 (изменено) · Жалоба Я пытаюсь выводить картинку на дисплей через LTDC. Контроллер STM32H743IIT6, дисплей UG-6028GDEBF02. Дисплей имеет разрешение 160x128. Цвет каждого пикселя определяется данными, которые поступают за три такта пиксельной частоты — по такту на цвет (R, G, B). Я хочу выводить Ч/Б изображение используя пиксельный формат L8. Для этого каждый пиксель буду определять тремя одинаковыми значениями по цветам (R=G=B). Раз каждый пиксель определяется тремя тактами пиксельной частоты, то в одной строке должно быть 160х3 = 480 тактов — или 480 пикселей. Таким образом для LTDC мое изображение преобразуется в 480х128. Дисплей можно настроить на режим работы 160х120 (с помощью встроенного в дисплей контроллера), что я и сделал. Попробовал вывести на дисплей изображение формата 160х120 с помощью встроенного в дисплей контроллера — все получилось как и должно быть.Теперь пытаюсь выводить на дисплей картинку по интерфейсу RGB используя LTDC. Настроил все на регистрах и по ДШ. Сформировал массив на 57600 пикселей (160х120х3). В массиве закрасил первый пиксель в первой строке (нулевой пиксель в нулевой строке), первый пиксель в третьей строке (нулевой пиксель во второй строке) и последний пиксель в кадре 57600 (57599). Вывожу на дисплей — вижу картинку как на картинке. Первый пиксель в первой строке горит не в начале дисплея, он смещен вправо, также как и первый пиксель в третьей строке. Последний горит слева от первого. Картинка отобразилась не до конца, почему то LTDC не отобразил весь буфер, а не дождавшись конца начал отображать первый пиксель, хотя адрес для нового кадра взял не первый в буфере, а тот с которого он прекратил отображать.Пробовал поиграться с настройками — проблему не победил. Не подскажите что-нибудь дельное? С какими регистрами поиграть и как? Возможно я косячу с параметрами синхронизации. Вот все что относится к RGB интерфейсу дисплея: Если я косячу с параметрами синхронизации, то что тут принять за них? Я принял следующие: #define HSYNC_WIDTH ((uint16_t)3) #define VSYNC_WIDTH ((uint16_t)1) #define HBP ((uint16_t)0) #define VBP ((uint16_t)0) #define ACTIVE_WIDTH ((uint16_t)480) #define ACTIVE_HEIGHT ((uint16_t)120) #define HFP ((uint16_t)0) #define VFP ((uint16_t)0) Полный код прилагаю: lar_ltdc.h lar_ltdc.c Изменено 9 января, 2021 пользователем LAS9891 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 10 января, 2021 Опубликовано 10 января, 2021 · Жалоба 12 часов назад, LAS9891 сказал: Попробовал вывести на дисплей изображение формата 160х120 с помощью встроенного в дисплей контроллера — все получилось как и должно быть Т.е. через его SPI? 12 часов назад, LAS9891 сказал: Таким образом для LTDC мое изображение преобразуется в 480х128 У Вас же такой дисплей: 12 часов назад, LAS9891 сказал: дисплей UG-6028GDEBF02. Дисплей имеет разрешение 160x128 12 часов назад, LAS9891 сказал: Полный код прилагаю: Можно этот код не прикладывать, а в сообщении прямо показать (его можно и нужно сделать "сворачиваемым")? Это не совсем удобно скачивать отдельно файлы (2 тут их), открывать и смотреть. Тут же есть встроенный редактор кода, с подсветкой причем и почему Вы не хотите им пользоваться? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 10 января, 2021 Опубликовано 10 января, 2021 (изменено) · Жалоба 15 hours ago, AleksBak said: Т.е. через его SPI? Можно сказать и так. Для этих целей вместо SPI я использую 80 series parallel interface. С этим проблем нет - все работает. 15 hours ago, AleksBak said: У Вас же такой дисплей: Все верно. В используемом дисплее цвет одного пикселя определяется за три такта пиксельной частоты. За эти три такта на линии данных должны быть установлены данные для каждого из трех цветов (RGB). Подробнее в datasheet на дисплей. UG-6028GDEBF02_21.03.2013.pdf Такого режима работы у LTDC нет. Но можно для LTDC указать ширину строки не 160, а 160х3 = 480. Тогда LTDC будет формировать нужное количество тактов пиксельной частоты. 15 hours ago, AleksBak said: Можно этот код не прикладывать, а в сообщении прямо показать (его можно и нужно сделать "сворачиваемым")? Это не совсем удобно скачивать отдельно файлы (2 тут их), открывать и смотреть. Тут же есть встроенный редактор кода, с подсветкой причем и почему Вы не хотите им пользоваться? Я подумал, что не стоит марать пост. Но раз уж Вы настаиваете...Source: Spoiler /* Includes ------------------------------------------------------------------*/ #include "lar_ltdc.h" #include "stm32h7xx_ll_rcc.h" /*----------------------------------------------------------------------------*/ void LTDC_Init (void) { LTDC_LayerCfgTypeDef LayerCfg; //LTDC_LayerCfgTypeDef *pLayerCfg = &LayerCfg; LTDC_SystemClock_Config(); LAR_LTDC_Init(); LayerCfg.WindowX0 = 0; LayerCfg.WindowX1 = 480; LayerCfg.WindowY0 = 0; LayerCfg.WindowY1 = 120; LayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_L8; LayerCfg.Alpha = 255; LayerCfg.Alpha0 = 0; LayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; LayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; LayerCfg.FBStartAdress = 0; LayerCfg.ImageWidth = 480; LayerCfg.ImageHeight = 120; LayerCfg.Backcolor.Blue = 0; LayerCfg.Backcolor.Green = 0; LayerCfg.Backcolor.Red = 0; LAR_LTDC_ConfigLayer (LAYER1, &LayerCfg); /* LayerCfg.WindowX0 = 0; LayerCfg.WindowX1 = 480; LayerCfg.WindowY0 = 0; LayerCfg.WindowY1 = 120; LayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB4444; LayerCfg.Alpha = 255; LayerCfg.Alpha0 = 0; LayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; LayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; LayerCfg.FBStartAdress = 0; LayerCfg.ImageWidth = 480; LayerCfg.ImageHeight = 120; LayerCfg.Backcolor.Blue = 0; LayerCfg.Backcolor.Green = 0; LayerCfg.Backcolor.Red = 0; LAR_LTDC_ConfigLayer (LAYER2, &LayerCfg); */ } /** * @brief System Clock Configuration for LTDC * @retval None */ void LTDC_SystemClock_Config(void) { LL_RCC_PLL3R_Enable(); LL_RCC_PLL3_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16); LL_RCC_PLL3_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE); LL_RCC_PLL3_SetM(1); // DIVM3 LL_RCC_PLL3_SetN(7); // DIVN3 LL_RCC_PLL3_SetP(2); // DIVP3 LL_RCC_PLL3_SetQ(2); // DIVQ3 LL_RCC_PLL3_SetR(20); // DIVR3 LL_RCC_PLL3_Enable(); /* Wait till PLL is ready */ while(LL_RCC_PLL3_IsReady() != 1) { } } void LAR_LTDC_MspInit (void) { /* ENABLE - PF10 DOTCLK - PE14 VSYNC - PI9 HSYNC - PI10 G0 - PE5 G1 - PE6 G2 - PH13 G3 - PE11 G4 - PB10 G5 - PH4 G6 - PI11 G7 - PG8 */ RCC->APB3ENR |= RCC_APB3ENR_LTDCEN; // LTDC clock enable. while (!(RCC->APB3ENR & RCC_APB3ENR_LTDCEN)) LL_mDelay(1); // Delay after an RCC peripheral clock enabling. RCC->AHB4ENR |= RCC_AHB4ENR_GPIOEEN; // GPIOE clock enable. RCC->AHB4ENR |= RCC_AHB4ENR_GPIOIEN; RCC->AHB4ENR |= RCC_AHB4ENR_GPIOFEN; //RCC->AHB4ENR |= RCC_AHB4ENR_GPIOCEN; //RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN; RCC->AHB4ENR |= RCC_AHB4ENR_GPIOHEN; RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN; //RCC->AHB4ENR |= RCC_AHB4ENR_GPIODEN; RCC->AHB4ENR |= RCC_AHB4ENR_GPIOGEN; //------------------------Сброс линий RGB в 0--------------------------------------------------------- GPIOF -> BSRR |= (ENABLE_Pin << 16); // Устанавливаем лог. 0 на линии ENABLE. GPIOE -> BSRR |= ( (DOTCLK_Pin | // Устанавливаем лог. 0 на линии DOTCLK. G0_Pin | // Устанавливаем лог. 0 на линии G0. G1_Pin | // Устанавливаем лог. 0 на линии G1. G3_Pin) << 16); // Устанавливаем лог. 0 на линии G3. GPIOI -> BSRR |= ( (VSYNC_Pin | // Устанавливаем лог. 0 на линии VSYNC. HSYNC_Pin | // Устанавливаем лог. 0 на линии HSYNC. G6_Pin) << 16); // Устанавливаем лог. 0 на линии G6. GPIOH -> BSRR |= ( (G2_Pin | // Устанавливаем лог. 0 на линии G2. G5_Pin) << 16); // Устанавливаем лог. 0 на линии G5. GPIOB -> BSRR |= (G4_Pin << 16); // Устанавливаем лог. 0 на линии G4. GPIOG -> BSRR |= (G7_Pin << 16); // Устанавливаем лог. 0 на линии G7. //------------------------------------------------------------------------------------------------------ //----------------Выключение подтяжки линий RGB--------------------------------------------------------- GPIOF -> PUPDR = 0; // No pull-up, pull-down. GPIOE -> PUPDR = 0; GPIOI -> PUPDR = 0; GPIOH -> PUPDR = 0; GPIOB -> PUPDR = 0; GPIOG -> PUPDR = 0; //------------------------------------------------------------------------------------------------------ //----------------Установка скорости работы линий RGB--------------------------------------------------- GPIOF -> OSPEEDR &= (~GPIO_OSPEEDR_OSPEED10_Msk); // Clear OSPEEDR10 bits. GPIOF -> OSPEEDR |= GPIO_OSPEEDR_OSPEED10_1; // ENABLE_Pin (PF10) -> GPIO port output High speed. GPIOE -> OSPEEDR &= (~(GPIO_OSPEEDR_OSPEED14_Msk | // Clear OSPEEDR14 bits. GPIO_OSPEEDR_OSPEED5_Msk | // Clear OSPEEDR5 bits. GPIO_OSPEEDR_OSPEED6_Msk | // Clear OSPEEDR6 bits. GPIO_OSPEEDR_OSPEED11_Msk)); // Clear OSPEEDR11 bits. GPIOE -> OSPEEDR |= ( GPIO_OSPEEDR_OSPEED14_1 | // DOTCLK_Pin (PE14) -> GPIO port output High speed. GPIO_OSPEEDR_OSPEED5_1 | // G0_Pin (PE5) -> GPIO port output High speed. GPIO_OSPEEDR_OSPEED6_1 | // G1_Pin (PE6) -> GPIO port output High speed. GPIO_OSPEEDR_OSPEED11_1 ); // G3_Pin (PE11) -> GPIO port output High speed. GPIOI -> OSPEEDR &= (~(GPIO_OSPEEDR_OSPEED9_Msk | // Clear OSPEEDR9 bits. GPIO_OSPEEDR_OSPEED10_Msk | // Clear OSPEEDR10 bits. GPIO_OSPEEDR_OSPEED11_Msk)); // Clear OSPEEDR11 bits. GPIOI -> OSPEEDR |= ( GPIO_OSPEEDR_OSPEED9_1 | // VSINC_Pin (PI9) -> GPIO port output High speed. GPIO_OSPEEDR_OSPEED10_1 | // HSINC_Pin (PI10) -> GPIO port output High speed. GPIO_OSPEEDR_OSPEED11_1 ); // G6_Pin (PI11) -> GPIO port output High speed. GPIOH -> OSPEEDR &= (~(GPIO_OSPEEDR_OSPEED13_Msk | // Clear OSPEEDR13 bits. GPIO_OSPEEDR_OSPEED4_Msk)); // Clear OSPEEDR4 bits. GPIOH -> OSPEEDR |= ( GPIO_OSPEEDR_OSPEED13_1 | // G2_Pin (PH13) -> GPIO port output High speed. GPIO_OSPEEDR_OSPEED4_1 ); // G5_Pin (PH4) -> GPIO port output High speed. GPIOB -> OSPEEDR &= (~GPIO_OSPEEDR_OSPEED10_Msk); // Clear OSPEEDR10 bits. GPIOB -> OSPEEDR |= GPIO_OSPEEDR_OSPEED10_1; // G4_Pin (PB10) -> GPIO port output High speed. GPIOG -> OSPEEDR &= (~GPIO_OSPEEDR_OSPEED8_Msk); // Clear OSPEEDR8 bits. GPIOG -> OSPEEDR |= GPIO_OSPEEDR_OSPEED8_1; // G7_Pin (PG8) -> GPIO port output High speed. //------------------------------------------------------------------------------------------------------------ //----------------Настройка линий RGB на Alternate function mode---------------------------------------------- GPIOF -> MODER &= (~GPIO_MODER_MODE10_Msk); // Clear MODER10 bits. GPIOF -> MODER |= GPIO_MODER_MODE10_1; // ENABLE_Pin (PF10) -> Alternate function mode. GPIOE -> MODER &= (~(GPIO_MODER_MODE14_Msk | // Clear MODER14 bits. GPIO_MODER_MODE5_Msk | // Clear MODER5 bits. GPIO_MODER_MODE6_Msk | // Clear MODER6 bits. GPIO_MODER_MODE11_Msk)); // Clear MODER11 bits. GPIOE -> MODER |= ( GPIO_MODER_MODE14_1 | // DOTCLK_Pin (PE14) -> Alternate function mode. GPIO_MODER_MODE5_1 | // G0_Pin (PE5) -> Alternate function mode. GPIO_MODER_MODE6_1 | // G1_Pin (PE6) -> Alternate function mode. GPIO_MODER_MODE11_1 ); // G3_Pin (PE11) -> Alternate function mode. GPIOI -> MODER &= (~(GPIO_MODER_MODE9_Msk | // Clear MODER9 bits. GPIO_MODER_MODE10_Msk | // Clear MODER10 bits. GPIO_MODER_MODE11_Msk)); // Clear MODER11 bits. GPIOI -> MODER |= ( GPIO_MODER_MODE9_1 | // VSINC_Pin (PI9) -> Alternate function mode. GPIO_MODER_MODE10_1 | // HSINC_Pin (PI10) -> Alternate function mode. GPIO_MODER_MODE11_1 ); // G6_Pin (PI11) -> Alternate function mode. GPIOH -> MODER &= (~(GPIO_MODER_MODE13_Msk | // Clear MODER13 bits. GPIO_MODER_MODE4_Msk)); // Clear MODER4 bits. GPIOH -> MODER |= ( GPIO_MODER_MODE13_1 | // G2_Pin (PH13) -> Alternate function mode. GPIO_MODER_MODE4_1 ); // G5_Pin (PH4) -> Alternate function mode. GPIOB -> MODER &= (~GPIO_MODER_MODE10_Msk); // Clear MODER10 bits. GPIOB -> MODER |= GPIO_MODER_MODE10_1; // G4_Pin (PB10) -> Alternate function mode. GPIOG -> MODER &= (~GPIO_MODER_MODE8_Msk); // Clear MODER8 bits. GPIOG -> MODER |= GPIO_MODER_MODE8_1; // G7_Pin (PG8) -> Alternate function mode. //-------------------------------------------------------------------------------------------------------------- //----------------Выбор альтернативных функций для линий RGB---------------------------------------------------- GPIOF -> AFR[1] &= (~GPIO_AFRH_AFSEL10_Msk); // Clear AFR10 bits. GPIOF -> AFR[1] |= ( GPIO_AFRH_AFSEL10_1 | // ENABLE_Pin (PF10) -> Alternate function LCD_DE. GPIO_AFRH_AFSEL10_2 | GPIO_AFRH_AFSEL10_3); GPIOE -> AFR[1] &= (~(GPIO_AFRH_AFSEL14_Msk | // Clear AFR14 bits. GPIO_AFRH_AFSEL11_Msk)); // Clear AFR11 bits. GPIOE -> AFR[0] &= (~(GPIO_AFRL_AFSEL5_Msk | // Clear AFR5 bits. GPIO_AFRL_AFSEL6_Msk)); // Clear AFR6 bits. GPIOE -> AFR[1] |= ( GPIO_AFRH_AFSEL14_1 | // DOTCLK_Pin (PE14) -> Alternate function LCD_CLK. GPIO_AFRH_AFSEL14_2 | GPIO_AFRH_AFSEL14_3 | GPIO_AFRH_AFSEL11_1 | // G3_Pin (PE11) -> Alternate function LCD_G3. GPIO_AFRH_AFSEL11_2 | GPIO_AFRH_AFSEL11_3); GPIOE -> AFR[0] |= ( GPIO_AFRL_AFSEL5_1 | // G0_Pin (PE5) -> Alternate function LCD_G0. GPIO_AFRL_AFSEL5_2 | GPIO_AFRL_AFSEL5_3 | GPIO_AFRL_AFSEL6_1 | // G1_Pin (PE6) -> Alternate function LCD_G1. GPIO_AFRL_AFSEL6_2 | GPIO_AFRL_AFSEL6_3); GPIOI -> AFR[1] &= (~(GPIO_AFRH_AFSEL9_Msk | // Clear AFR9 bits. GPIO_AFRH_AFSEL10_Msk | // Clear AFR10 bits. GPIO_AFRH_AFSEL11_Msk)); // Clear AFR11 bits. GPIOI -> AFR[1] |= ( GPIO_AFRH_AFSEL9_1 | // VSINC_Pin (PI9) -> Alternate function LCD_VSYNC. GPIO_AFRH_AFSEL9_2 | GPIO_AFRH_AFSEL9_3 | GPIO_AFRH_AFSEL10_1 | // HSYNC_Pin (PI10) -> Alternate function LCD_HSYNC. GPIO_AFRH_AFSEL10_2 | GPIO_AFRH_AFSEL10_3 | GPIO_AFRH_AFSEL11_0 | // G6_Pin (PI11) -> Alternate function LCD_G6. GPIO_AFRH_AFSEL11_3); GPIOH -> AFR[1] &= (~GPIO_AFRH_AFSEL13_Msk); // Clear AFR13 bits. GPIOH -> AFR[0] &= (~GPIO_AFRL_AFSEL4_Msk); // Clear AFR4 bits. GPIOH -> AFR[1] |= ( GPIO_AFRH_AFSEL13_1 | // G2_Pin (PH13) -> Alternate function LCD_G2. GPIO_AFRH_AFSEL13_2 | GPIO_AFRH_AFSEL13_3); GPIOH -> AFR[0] |= ( GPIO_AFRL_AFSEL4_0 | // G5_Pin (PH4) -> Alternate function LCD_G5. GPIO_AFRL_AFSEL4_3); GPIOB -> AFR[1] &= (~GPIO_AFRH_AFSEL10_Msk); // Clear AFR10 bits. GPIOB -> AFR[1] |= ( GPIO_AFRH_AFSEL10_1 | // G4_Pin (PB10) -> Alternate function LCD_G4. GPIO_AFRH_AFSEL10_2 | GPIO_AFRH_AFSEL10_3); GPIOG -> AFR[1] &= (~GPIO_AFRH_AFSEL8_Msk); // Clear AFR10 bits. GPIOG -> AFR[1] |= ( GPIO_AFRH_AFSEL8_1 | // G7_Pin (PG8) -> Alternate function LCD_G7. GPIO_AFRH_AFSEL8_2 | GPIO_AFRH_AFSEL8_3); //-------------------------------------------------------------------------------------------------------------- } void LAR_LTDC_Init (void) { LAR_LTDC_MspInit(); //---Configure the HS, VS, DE and PC polarity----------------------------------------------------------------------------- LTDC->GCR &= (~LTDC_GCR_HSPOL); // Horizontal synchronization polarity: horizontal synchronization polarity is active low. LTDC->GCR &= (~LTDC_GCR_VSPOL); // Vertical synchronization polarity: vertical synchronization polarity is active low. LTDC->GCR |= LTDC_GCR_DEPOL; // Not data enable polarity: not data enable polarity is active high. LTDC->GCR |= LTDC_GCR_PCPOL; // Pixel clock polarity: pixel clock polarity is active high - inverted input. //------------------------------------------------------------------------------------------------------------------------ //---Set Synchronization size---------------------------------------------------------------------------------------- LTDC->SSCR &= ~(LTDC_SSCR_VSH | LTDC_SSCR_HSW); LTDC->SSCR |= ( (HSYNC_WIDTH - 1) << 16 | (VSYNC_WIDTH - 1)); //---Set Accumulated Back porch-------------------------------------------------------------------------------------- LTDC->BPCR &= ~(LTDC_BPCR_AHBP | LTDC_BPCR_AVBP); LTDC->BPCR |= ((HSYNC_WIDTH + HBP - 1) << 16 | (VSYNC_WIDTH + VBP - 1)); //---Set Accumulated Active Width and Active Height------------------------------------------------------------------ LTDC->AWCR &= ~(LTDC_AWCR_AAH | LTDC_AWCR_AAW); LTDC->AWCR |= ((HSYNC_WIDTH + HBP + ACTIVE_WIDTH - 1) << 16 | (VSYNC_WIDTH + VBP + ACTIVE_HEIGHT - 1)); //---Set Total Width and Height-------------------------------------------------------------------------------------- LTDC->TWCR &= ~(LTDC_TWCR_TOTALH | LTDC_TWCR_TOTALW); LTDC->TWCR |= ((HSYNC_WIDTH + HBP + ACTIVE_WIDTH + HFP - 1) << 16 | (VSYNC_WIDTH + VBP + ACTIVE_HEIGHT + VFP - 1)); //---Set the background color value---------------------------------------------------------------------------------- LTDC->BCCR &= ~(LTDC_BCCR_BCBLUE | LTDC_BCCR_BCGREEN | LTDC_BCCR_BCRED); LTDC->BCCR |= ( (BACKCOLOR_RED << 16) | (BACKCOLOR_GREEN << 8) | (BACKCOLOR_BLUE) ); //---Enable LTDC interrupts---------------------------------------------------------------- LTDC->IER &= 0xFFFFFFF0; // Disable all interrupts. LTDC->ICR |= 0x0000000F; // Clear interrupts flags. /* LTDC->LIPCR |= LTDC_IER_LIE; // These bits configure the line interrupt position. LTDC->IER |= LTDC_IER_LIE; // Line interrupt enable. */ LTDC->LIPCR |= LTDC_IER_FUIE; // FIFO underrun Interrupt enable. //LTDC->LIPCR |= LTDC_IER_TERRIE; // Transfer error interrupt enable. //LTDC->LIPCR |= LTDC_IER_RRIE; // Register reload interrupt enable. //--- LTDC interrupt Init------------------------------------------------------------------------------------- uint32_t prioritygroup; prioritygroup = NVIC_GetPriorityGrouping(); NVIC_SetPriority(LTDC_IRQn, NVIC_EncodePriority(prioritygroup, 0, 0)); // Sets the priority of an interrupt. NVIC_EnableIRQ(LTDC_IRQn); // Enable interrupt. //------------------------------------------------------------------------------------------------------------ LTDC->GCR |= LTDC_GCR_LTDCEN; // Enable LTDC by setting LTDCEN bit. } /** * @brief Configures the LTDC peripheral * @param pLayerCfg Pointer LTDC Layer Configuration structure * @param LayerIdx LTDC Layer index. * This parameter can be one of the following values: LAYER_1 (0) or LAYER_2 (1) * @retval None */ void LAR_LTDC_ConfigLayer (uint8_t LayerIdx, LTDC_LayerCfgTypeDef *pLayerCfg) { uint32_t tmp = 0; //---Configure the horizontal start and stop position------------------------------------------------------------------------------------------ LTDC_LAYER(LayerIdx)->WHPCR &= ~(LTDC_LxWHPCR_WHSTPOS | LTDC_LxWHPCR_WHSPPOS); // Clear LTDC layer x window horizontal position configuration register. LTDC_LAYER(LayerIdx)->WHPCR = ( ( (pLayerCfg->WindowX1 + ((LTDC->BPCR & LTDC_BPCR_AHBP) >> 16)) << 16 ) | (pLayerCfg->WindowX0 + ((LTDC->BPCR & LTDC_BPCR_AHBP) >> 16) + 1) ); //---Configure the vertical start and stop position-------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->WVPCR &= ~(LTDC_LxWVPCR_WVSTPOS | LTDC_LxWVPCR_WVSPPOS); LTDC_LAYER(LayerIdx)->WVPCR = ( ( (pLayerCfg->WindowY1 + (LTDC->BPCR & LTDC_BPCR_AVBP)) << 16) | (pLayerCfg->WindowY0 + (LTDC->BPCR & LTDC_BPCR_AVBP) + 1) ); //---Specifies the pixel format---------------------------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->PFCR &= ~(LTDC_LxPFCR_PF); LTDC_LAYER(LayerIdx)->PFCR = (pLayerCfg->PixelFormat); //---Configure the default color values-------------------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->DCCR &= ~(LTDC_LxDCCR_DCBLUE | LTDC_LxDCCR_DCGREEN | LTDC_LxDCCR_DCRED | LTDC_LxDCCR_DCALPHA); LTDC_LAYER(LayerIdx)->DCCR = (pLayerCfg->Backcolor.Blue | ((uint32_t)(pLayerCfg->Backcolor.Green) << 8) | ((uint32_t)(pLayerCfg->Backcolor.Red) << 16) | (pLayerCfg->Alpha0 << 24) ); //---Specifies the constant alpha value-------------------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->CACR &= ~(LTDC_LxCACR_CONSTA); LTDC_LAYER(LayerIdx)->CACR = (pLayerCfg->Alpha); //---Specifies the blending factors------------------------------------------------------------------------------------------------------------ LTDC_LAYER(LayerIdx)->BFCR &= ~(LTDC_LxBFCR_BF2 | LTDC_LxBFCR_BF1); LTDC_LAYER(LayerIdx)->BFCR = (pLayerCfg->BlendingFactor1 | pLayerCfg->BlendingFactor2); //---Configure the color frame buffer start address-------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->CFBAR &= ~(LTDC_LxCFBAR_CFBADD); LTDC_LAYER(LayerIdx)->CFBAR = pLayerCfg->FBStartAdress; if (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) tmp = 4; else if (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB888) tmp = 3; else if((pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) || (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_AL88)) tmp = 2; else tmp = 1; //---Configure the color frame buffer pitch in byte---------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->CFBLR &= ~(LTDC_LxCFBLR_CFBLL | LTDC_LxCFBLR_CFBP); LTDC_LAYER(LayerIdx)->CFBLR = (((pLayerCfg->ImageWidth * tmp) << 16) | (((pLayerCfg->WindowX1 - pLayerCfg->WindowX0) * tmp) + 7)); //---Configure the frame buffer line number------------------------------------------------------------------------------------------------------ LTDC_LAYER(LayerIdx)->CFBLNR &= ~(LTDC_LxCFBLNR_CFBLNBR); LTDC_LAYER(LayerIdx)->CFBLNR = pLayerCfg->ImageHeight; //---Enable LTDC_Layer by setting LEN bit-------------------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->CR |= (uint32_t)LTDC_LxCR_LEN; //---Set the Immediate Reload type--------------------------------------------------------------------------------------------------------------- LTDC->SRCR = LTDC_SRCR_IMR; } void LAR_LTDC_SetAddress (uint32_t Address, uint8_t LayerIdx) { //---Configure the color frame buffer start address-------------------------------------------------------------------------------------------- LTDC_LAYER(LayerIdx)->CFBAR &= ~(LTDC_LxCFBAR_CFBADD); LTDC_LAYER(LayerIdx)->CFBAR = Address; //---Set the Immediate Reload type--------------------------------------------------------------------------------------------------------------- LTDC->SRCR = LTDC_SRCR_IMR; } Header: Spoiler #include "main.h" /* Defines -------------------------------------------------------------------*/ //#define LTDC_LAYER(__HANDLE__, __LAYER__) ((LTDC_Layer_TypeDef *)((uint32_t)(((uint32_t)((__HANDLE__)->Instance)) + 0x84 + (0x80*(__LAYER__))))) #define LTDC_LAYER(__LAYER__) ((LTDC_Layer_TypeDef *)((uint32_t)(((uint32_t)(LTDC)) + 0x84 + (0x80*(__LAYER__))))) /* *************************** Timings for display********************************* * * HSW = (HSYNC_WIDTH - 1) * VSH = (VSYNC_WIDTH - 1) * AHBP = (HSYNC_WIDTH + HBP - 1) * AVBP = (VSYNC_WIDTH + VBP - 1) * AAW = (HSYNC_WIDTH + HBP + ACTIVE_WIDTH - 1) * AAH = (VSYNC_WIDTH + BVBP + ACTIVE_HEIGHT - 1) * TOTALW = (HSYNC_WIDTH + HBP + ACTIVE_WIDTH + HFP - 1) * TOTALH = (VSYNC_WIDTH + BVBP + ACTIVE_HEIGHT + VFP - 1) */ #define HSYNC_WIDTH ((uint16_t)3) #define VSYNC_WIDTH ((uint16_t)1) #define HBP ((uint16_t)0) #define VBP ((uint16_t)0) #define ACTIVE_WIDTH ((uint16_t)480) #define ACTIVE_HEIGHT ((uint16_t)120) #define HFP ((uint16_t)0) #define VFP ((uint16_t)0) #define BACKCOLOR_RED ((uint8_t)0) #define BACKCOLOR_GREEN ((uint8_t)0) #define BACKCOLOR_BLUE ((uint8_t)0) #define LAYER1 0 // Номер слоя. #define LAYER2 1 // Номер слоя. /** @defgroup LTDC_Pixelformat LTDC Pixel format * @{ */ #define LTDC_PIXEL_FORMAT_ARGB8888 (0x00000000U) /*!< ARGB8888 LTDC pixel format */ #define LTDC_PIXEL_FORMAT_RGB888 (0x00000001U) /*!< RGB888 LTDC pixel format */ #define LTDC_PIXEL_FORMAT_RGB565 (0x00000002U) /*!< RGB565 LTDC pixel format */ #define LTDC_PIXEL_FORMAT_ARGB1555 (0x00000003U) /*!< ARGB1555 LTDC pixel format */ #define LTDC_PIXEL_FORMAT_ARGB4444 (0x00000004U) /*!< ARGB4444 LTDC pixel format */ #define LTDC_PIXEL_FORMAT_L8 (0x00000005U) /*!< L8 LTDC pixel format */ #define LTDC_PIXEL_FORMAT_AL44 (0x00000006U) /*!< AL44 LTDC pixel format */ #define LTDC_PIXEL_FORMAT_AL88 (0x00000007U) /*!< AL88 LTDC pixel format */ /** * @} */ /** @defgroup LTDC_BlendingFactor1 LTDC Blending Factor1 * @{ */ #define LTDC_BLENDING_FACTOR1_CA (0x00000400U) /*!< Blending factor : Cte Alpha */ #define LTDC_BLENDING_FACTOR1_PAxCA (0x00000600U) /*!< Blending factor : Cte Alpha x Pixel Alpha*/ /** * @} */ /** @defgroup LTDC_BlendingFactor2 LTDC Blending Factor2 * @{ */ #define LTDC_BLENDING_FACTOR2_CA (0x00000005U) /*!< Blending factor : Cte Alpha */ #define LTDC_BLENDING_FACTOR2_PAxCA (0x00000007U) /*!< Blending factor : Cte Alpha x Pixel Alpha*/ /** * @} */ /*----------------------------------------------------------------------------*/ /* Extern variables ----------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /** * @brief LTDC color structure definition */ typedef struct { uint8_t Blue; /*!< Configures the blue value. This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ uint8_t Green; /*!< Configures the green value. This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ uint8_t Red; /*!< Configures the red value. This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ uint8_t Reserved; /*!< Reserved 0xFF */ } LTDC_ColorTypeDef; /** * @brief LTDC Layer structure definition */ typedef struct { uint32_t WindowX0; /*!< Configures the Window Horizontal Start Position. This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ uint32_t WindowX1; /*!< Configures the Window Horizontal Stop Position. This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ uint32_t WindowY0; /*!< Configures the Window vertical Start Position. This parameter must be a number between Min_Data = 0x000 and Max_Data = 0x7FF. */ uint32_t WindowY1; /*!< Configures the Window vertical Stop Position. This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x7FF. */ uint32_t PixelFormat; /*!< Specifies the pixel format. This parameter can be one of value of @ref LTDC_Pixelformat */ uint32_t Alpha; /*!< Specifies the constant alpha used for blending. This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ uint32_t Alpha0; /*!< Configures the default alpha value. This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ uint32_t BlendingFactor1; /*!< Select the blending factor 1. This parameter can be one of value of @ref LTDC_BlendingFactor1 */ uint32_t BlendingFactor2; /*!< Select the blending factor 2. This parameter can be one of value of @ref LTDC_BlendingFactor2 */ uint32_t FBStartAdress; /*!< Configures the color frame buffer address */ uint32_t ImageWidth; /*!< Configures the color frame buffer line length. This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x1FFF. */ uint32_t ImageHeight; /*!< Specifies the number of line in frame buffer. This parameter must be a number between Min_Data = 0x000 and Max_Data = 0x7FF. */ LTDC_ColorTypeDef Backcolor; /*!< Configures the layer background color. */ } LTDC_LayerCfgTypeDef; /*----------------------------------------------------------------------------*/ /* Prototypes ---------------------------------------------------------------------------*/ void LTDC_Init (void); void LTDC_SystemClock_Config (void); void LAR_LTDC_MspInit (void); void LAR_LTDC_Init (void); void LAR_LTDC_ConfigLayer (uint8_t LayerIdx, LTDC_LayerCfgTypeDef *pLayerCfg); void LAR_LTDC_SetAddress (uint32_t Address, uint8_t LayerIdx); /*---------------------------------------------------------------------------------------*/ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __LAR_LTDC_H #define __LAR_LTDC_H #endif /* __LAR_LTDC_H */ /*********************************END OF FILE**********************************/ Объявление фрейм буфера и переключение адреса для вывода изображения: Spoiler /* Private variables ---------------------------------------------------------*/ uint8_t Test_frame [NUM_OF_PIX_IN_LINE * NUM_OF_LINE_IN_FRAME * 3]; /*----------------------------------------------------------------------------*/ void LAR_Init_Peripherals (void) { LAR_GPIO_Init(); SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // Разрешение прерывания по таймеру SysTick. LAR_DMA_Init(); LAR_ADC_Calibration (ADC1, DIFFERENTIAL); LAR_ADC_Init (ADC1); LAR_ADC_Enable (ADC1); // Function LAR_ADC_Enable enable the selected ADC, but does not start the conversion. LAR_TIM_Init(); LAR_DAC1_Init(); Display_Init(); LTDC_Init(); for (uint32_t i=0; i<(NUM_OF_PIX_IN_LINE * NUM_OF_LINE_IN_FRAME * 3); i++) { if ( (i<3) | // Певая строка первый пиксель ( (959<i) && (i<963) ) | // Третья строка первый пиксель ( (57596<i) && (i<57600) ) ) // Последний пиксель. Test_frame [i] = 0xFF; else Test_frame [i] = 0x0; } LAR_LTDC_SetAddress ((uint32_t) &Test_frame, LAYER1); } Изменено 10 января, 2021 пользователем LAS9891 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 10 января, 2021 Опубликовано 10 января, 2021 · Жалоба 45 минут назад, LAS9891 сказал: Я подумал, что не стоит марать пост 14 часов назад, AleksBak сказал: его можно и нужно сделать "сворачиваемым" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 10 января, 2021 Опубликовано 10 января, 2021 · Жалоба 32 minutes ago, AleksBak said: его можно и нужно сделать "сворачиваемым" как? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 10 января, 2021 Опубликовано 10 января, 2021 · Жалоба 1 минуту назад, LAS9891 сказал: как? Сначала копируете код, который хотите свернуть. Потом, например при изменениях своего поста, нажимаете такой "глаз" в окне редактирования поста. Появляется окошко для "скрытого" куска поста и туда вставляете этот свой код. И этот "глаз" находится слева возле смайлика в окне редактора поста. Еще добавлю - а после того как сделаете код "сворачиваемым", то уже "не сворачиваемый" кусок (который скопировали перед этим) удалите в посте. А все изменения в посте можно предварительно просмотреть при нажатии другой пиктограммки: "лупа на бумаге". Она (эта "лупа") - самая крайняя справа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 10 января, 2021 Опубликовано 10 января, 2021 (изменено) · Жалоба 1 hour ago, AleksBak said: его можно и нужно сделать "сворачиваемым" пожалуйте Изменено 10 января, 2021 пользователем LAS9891 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 11 января, 2021 Опубликовано 11 января, 2021 · Жалоба Доброе утро. Вот Вы говоритепишите насколько я понял, что у Вас дисплей такой, что поддерживает какой-то (извините я с таким не сталкивался) формат L8 ? И Вы хотите теперь чтобы и Ваш LTDC теперь также, с таким форматом, нормально тут работал. Правильно? И Вы проверили свой дисплей каким-то необычным способом (на сдвиговых регистрах может и т.п.), что дисплей поддерживает этот формат и тут все нормально? Надо теперь посмотреть настройки. Извините, что я может не то что-то пишу и не отвечаю на Ваш конкретный вопрос в теме - просто у меня тоже много проблем своих и пр. Вы пока тоже подумайте и подождите может кто-то тоже что-то ответит тут. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 11 января, 2021 Опубликовано 11 января, 2021 · Жалоба 2 hours ago, AleksBak said: Вот Вы говоритепишите насколько я понял, что у Вас дисплей такой, что поддерживает какой-то (извините я с таким не сталкивался) формат L8 ? Нет. Дисплей не поддерживает такой формат. LTDC поддерживает. Я в буфере формирую картинку в соответствии с форматом L8. Я буду выводить черно-белую картинку на цветной дисплей. В буфере кадра храню картинку в формате L8 (каждый пиксель 8 бит). А чтобы дисплей показывал черно-белую картинку я три раза отправляю одно значение пикселя для каждого цвета (RGB). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 11 января, 2021 Опубликовано 11 января, 2021 · Жалоба 1 час назад, LAS9891 сказал: А чтобы дисплей показывал черно-белую картинку я три раза отправляю одно значение пикселя для каждого цвета (RGB). Это называется "монохром", а не "ч/б". "ч/б" - это когда один бит на пиксель и только 2 цвета. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 11 января, 2021 Опубликовано 11 января, 2021 · Жалоба Вроде заработало Только как-то странно. Почему фон разного оттенка? Вот надпись STM, слева от буквы S фон светлее чем фон ниже надписи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 21 час назад, LAS9891 сказал: Вроде заработало Поздравляю. В этом дисплее, у контроллера имеется еще 8080-ый интерфейс (помимо RGB). Значит до этого Вы проверяли его на этом интерфейсе и тогда было все успешно. 21 час назад, LAS9891 сказал: Только как-то странно. Почему фон разного оттенка? Вот надпись STM, слева от буквы S фон светлее чем фон ниже надписи. У этого дисплея нужно питающие напряжения для самой матрицы снаружи подавать. А эти питающие напряжения у Вас соответствуют даташиту? Возможно из-за этого такие полоски и артефакты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 5 minutes ago, AleksBak said: У этого дисплея нужно питающие напряжения для самой матрицы снаружи подавать. Подаю снаружи. 6 minutes ago, AleksBak said: А эти питающие напряжения у Вас соответствуют даташиту? Возможно из-за этого такие полоски и артефакты. Если я заливаю дисплей одним цветом, то изображение однородно без полос. Это не оправдывает питание? При этом все равно питание может быть причиной полос на картинке? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 2 минуты назад, LAS9891 сказал: Если я заливаю дисплей одним цветом, то изображение однородно без полос. Это не оправдывает питание? Нет. 3 минуты назад, LAS9891 сказал: При этом все равно питание может быть причиной полос на картинке? Вот тут, у Вас, очень может быть. Проверьте питающие напряжения и их величины. Но только аккуратно. 4 минуты назад, LAS9891 сказал: Подаю снаружи. А каким образом вообще? Просто интересно. Может спец. платой какой-то готовой (они называются T CON)? На таких платах есть регулировки уровней пит. напряжений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 17 minutes ago, AleksBak said: Проверьте питающие напряжения и их величины Учтем на будущее. Пока изображение устраивает. Важнее теперь это. 18 minutes ago, AleksBak said: А каким образом вообще? Самодельный блок питания на импульсниках. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться