Jump to content

    
LAS9891

STM32, LTDC и дисплей UG-6028GDEBF02

Recommended Posts

Я пытаюсь выводить картинку на дисплей через 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). Вывожу на дисплей — вижу картинку как на картинке.

 

20210108_202151.thumb.jpg.433a651b9160076edea2bb5a6f40f29b.jpg

 

Первый пиксель в первой строке горит не в начале дисплея, он смещен вправо, также как и первый пиксель в третьей строке. Последний горит слева от первого. Картинка отобразилась не до конца, почему то LTDC не отобразил весь буфер, а не дождавшись конца начал отображать первый пиксель, хотя адрес для нового кадра взял не первый в буфере, а тот с которого он прекратил отображать.
Пробовал поиграться с настройками — проблему не победил. Не подскажите что-нибудь дельное? С какими регистрами поиграть и как?

 

Возможно я косячу с параметрами синхронизации. Вот все что относится к RGB интерфейсу дисплея:

541287843_09-01-2021155744.thumb.jpg.0119b0d5a5bd23b3e3cc60f21bf7596f.jpg

 

Если я косячу с параметрами синхронизации, то что тут принять за них? Я принял следующие:

 

#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

Edited by LAS9891

Share this post


Link to post
Share on other sites
12 часов назад, LAS9891 сказал:

Попробовал вывести на дисплей изображение формата 160х120 с помощью встроенного в дисплей контроллера — все получилось как и должно быть

Т.е. через его SPI?

12 часов назад, LAS9891 сказал:

Таким образом для LTDC мое изображение преобразуется в 480х128

У Вас же такой дисплей:

12 часов назад, LAS9891 сказал:

дисплей UG-6028GDEBF02. Дисплей имеет разрешение 160x128

 

12 часов назад, LAS9891 сказал:

Полный код прилагаю:

 

Можно этот код не прикладывать, а в сообщении прямо показать (его можно и нужно сделать "сворачиваемым")? Это не совсем удобно скачивать отдельно файлы (2 тут их), открывать и смотреть. Тут же есть встроенный редактор кода, с подсветкой причем и почему Вы не хотите им пользоваться?

Share this post


Link to post
Share on other sites
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);

}

 

 

Edited by LAS9891

Share this post


Link to post
Share on other sites
45 минут назад, LAS9891 сказал:

Я подумал, что не стоит марать пост

 

14 часов назад, AleksBak сказал:

его можно и нужно сделать "сворачиваемым"

 

Share this post


Link to post
Share on other sites
1 минуту назад, LAS9891 сказал:

как?

Сначала копируете код, который хотите свернуть. Потом, например при изменениях своего поста, нажимаете такой "глаз" в окне редактирования поста. Появляется окошко для "скрытого" куска поста и туда вставляете этот свой код.

 

И этот "глаз" находится слева возле смайлика в окне редактора поста.

Еще добавлю - а после того как сделаете код "сворачиваемым", то уже "не сворачиваемый" кусок (который скопировали перед этим) удалите в посте. А все изменения в посте можно предварительно просмотреть при нажатии другой пиктограммки: "лупа на бумаге".

Она (эта "лупа") - самая крайняя справа.

Share this post


Link to post
Share on other sites

Доброе утро.

Вот Вы говоритепишите насколько я понял, что у Вас дисплей такой, что поддерживает какой-то (извините я с таким не сталкивался) формат L8 ?

И Вы хотите теперь чтобы и Ваш LTDC теперь также, с таким форматом, нормально тут работал. Правильно?

И Вы проверили свой дисплей каким-то необычным способом (на сдвиговых регистрах может и т.п.), что дисплей поддерживает этот формат и тут все нормально?

Надо теперь посмотреть настройки. Извините, что я может не то что-то пишу и не отвечаю на Ваш конкретный вопрос в теме - просто у меня тоже много проблем своих и пр.

Вы пока тоже подумайте и подождите может кто-то тоже что-то ответит тут.

Share this post


Link to post
Share on other sites
2 hours ago, AleksBak said:

Вот Вы говоритепишите насколько я понял, что у Вас дисплей такой, что поддерживает какой-то (извините я с таким не сталкивался) формат L8 ?

Нет. Дисплей не поддерживает такой формат. LTDC поддерживает. Я в буфере формирую картинку в соответствии с форматом L8. Я буду выводить черно-белую картинку на цветной дисплей. В буфере кадра храню картинку в формате L8 (каждый пиксель 8 бит). А чтобы дисплей показывал черно-белую картинку я три раза отправляю одно значение пикселя для каждого цвета (RGB).

Share this post


Link to post
Share on other sites
1 час назад, LAS9891 сказал:

А чтобы дисплей показывал черно-белую картинку я три раза отправляю одно значение пикселя для каждого цвета (RGB).

Это называется "монохром", а не "ч/б". "ч/б" - это когда один бит на пиксель и только 2 цвета.

Share this post


Link to post
Share on other sites
21 час назад, LAS9891 сказал:

Вроде заработало

Поздравляю. В этом дисплее, у контроллера имеется еще 8080-ый интерфейс (помимо RGB). Значит до этого Вы проверяли его на этом интерфейсе и тогда было все успешно.

21 час назад, LAS9891 сказал:

Только как-то странно. Почему фон разного оттенка? Вот надпись STM, слева от буквы S фон светлее чем фон ниже надписи.

У этого дисплея нужно питающие напряжения для самой матрицы снаружи подавать. А эти питающие напряжения у Вас соответствуют даташиту? Возможно из-за этого такие полоски и артефакты.

Share this post


Link to post
Share on other sites
5 minutes ago, AleksBak said:

У этого дисплея нужно питающие напряжения для самой матрицы снаружи подавать.

Подаю снаружи.

 

6 minutes ago, AleksBak said:

А эти питающие напряжения у Вас соответствуют даташиту? Возможно из-за этого такие полоски и артефакты.

Если я заливаю дисплей одним цветом, то изображение однородно без полос. Это не оправдывает питание? При этом все равно питание может быть причиной полос на картинке?

Share this post


Link to post
Share on other sites
2 минуты назад, LAS9891 сказал:

Если я заливаю дисплей одним цветом, то изображение однородно без полос. Это не оправдывает питание?

Нет.

3 минуты назад, LAS9891 сказал:

При этом все равно питание может быть причиной полос на картинке?

Вот тут, у Вас, очень может быть. Проверьте питающие напряжения и их величины. Но только аккуратно.

4 минуты назад, LAS9891 сказал:

Подаю снаружи.

А каким образом вообще? Просто интересно. Может спец. платой какой-то готовой (они называются T CON)? На таких платах есть регулировки уровней пит. напряжений.

Share this post


Link to post
Share on other sites
17 minutes ago, AleksBak said:

Проверьте питающие напряжения и их величины

Учтем на будущее. Пока изображение устраивает. Важнее теперь это

 

18 minutes ago, AleksBak said:

А каким образом вообще?

Самодельный блок питания на импульсниках.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.