Перейти к содержанию
    

STM32F429-Disco, CubeMX и TouchGFX Designer. Тема будет долгой....

1 час назад, MementoMori сказал:

Обратитесь ко мне, с удовольствием сделаю проектик для Вас. Вы только скажите что за камень. 

Вряд ли стоит вам ради меня заниматься посторонними делами. А речь идет о плате STM32F429-Disco, как это следует из названия темы. Если у вас такой платы нет, то заниматься этим вам и подавно не имеет смысла, т.к. проблема не столько в контроллере, сколько в дисплее. А целевая задача - чтобы он "Hello world!" сказал :).

P.S. Прошу не советовать мне воспользоваться демо-программой, которая к этой плате прилагается. Этот вопрос даже обсуждать не хочу, потому что эту программу уже видела.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нид э хелб! конфигурирую кубМХ под stm32f746, не под дискавери, а просто под контроллер. Не активна вкладка Multimedia->Graphics. Все остальное настроил(sdram, ...), но видимо не все..Подскажите кто знает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, dr.v сказал:

Не активна вкладка Multimedia->Graphics. Все остальное настроил(sdram, ...), но видимо не все..Подскажите кто знает?

Там в Кубе встроенная подсказка нормальная. Наводишь на опцию, он пишет, какие ошибки.
Плюс в документации есть главы:
Tutorial 9: Using STM32CubeMX Graphics simulator
"necessary peripherals: CRC, DMA2D (optional, for Graphics acceleration), FMC SDRAM mode, RCC HSE, LTDC ..."
Tutorial 10: Using ST-TouchGFX framework
ST-TouchGFX required peripherals and middleware: FreeRTOS, DMA2D, TIM, FMC (SDRAM or SRAM), LTDC in DSI mode, DSIHOST (requires RCC HSE).

Это для Куба включая версию МХ.5.4.0
В последнем МХ.5.5.0 они все изменили, теперь отдельный конфигуратор графики.
"Removed native support of STemWin and TouchGFX graphical stacks configuration"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 18.03.2020 в 22:49, Xenia сказал:

... проблема не столько в контроллере, сколько в дисплее. А целевая задача - чтобы он "Hello world!" сказал...

На сайте STM-овцев есть архив с демопроектами для этой платы.

В числе этих проектов есть примеры работы с экраном. Вы хотите, чтобы экран отхэллоуворлдил, но демопроектами пользоваться не хотите... Так?

Или под демопрограммой Вы подразумеваете ту фиговину, что с платой "заставкой" шла? Я ее, кстати, уже через минуту затер своими наработками:wink:

 

Но повторюсь, если хотите надписи элементарно повыводить да посмотреть как там примерно что-то делается, то есть демопроекты. Прям на сайте.

Вот ради интереса скачал и отредачил какой-то пример с LCD под себя, пять минут и

Спойлер

CIVFnF0gBS8.jpg

 

Если интересно, выложу архив. А ссылка на "сборную солянку" - тут.

 

Хотя кой смысл выкладывать архив, если я поправил лишь main под себя в данном случае...

#include "main.h"

#include "stm32f4xx.h"
#include "stm32f429i_discovery.h"
#include "stm32f429i_discovery_lcd.h"

int main(void)
{ 
  LCD_Init();
  LCD_LayerInit();
  LTDC_Cmd(ENABLE);
  LCD_SetLayer(LCD_FOREGROUND_LAYER);
  LCD_SetTransparency(0);
  LCD_SetLayer(LCD_BACKGROUND_LAYER);
  LCD_SetColors(LCD_COLOR_YELLOW, LCD_COLOR_BLACK);
  LCD_SetFont(&Font16x24);
  LCD_Clear(LCD_COLOR_BLACK);
  
  LCD_DisplayStringLine(LCD_LINE_2, (uint8_t *)"  Hello from");
  LCD_DisplayStringLine(LCD_LINE_3, (uint8_t *)"    Arlleex");
  LCD_SetColors(LCD_COLOR_RED, LCD_COLOR_BLACK);
  LCD_DisplayStringLine(LCD_LINE_5, (uint8_t *)"       to");
  LCD_DisplayStringLine(LCD_LINE_6, (uint8_t *)" electronix.ru");
 
  while (1)
  {
  }
}

 

Проект там называется LTDC_Display_2Layers в папке демок периферии.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 минут назад, Arlleex сказал:

LCD_DisplayStringLine(LCD_LINE_2, (uint8_t *)"  Hello from");

Интересные у них примеры. Например координаты здесь не задать получается. И на каком слое идет печать BG или FG?

 

21 минуту назад, Arlleex сказал:

LCD_Init();

Тоже какая-то странная инициализация, интересно, разрешение экрана там где задавать, походу оно "прибито гвоздями" где-то в хидерах...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, mantech сказал:

Интересные у них примеры. Например координаты здесь не задать получается. И на каком слое идет печать BG или FG?

Тоже какая-то странная инициализация, интересно, разрешение экрана там где задавать, походу оно "прибито гвоздями" где-то в хидерах...

Это примеры для конкретной платы. Для конкретной той, что с маленьким таким экраном. Той, что на картинке у меня, она же STM32F429I-Disco.

Печать идет на текущем активном слое. Задается сначала LCD_SetLayer(), потом на этом слое происходят остальные махинации (стирание, отрисовка и т.д.).

В той функции LCD_Init() все параметры LCD взяты из даташита на этот экран (размерности HSYNC/VSINV, длительности импульсов гашения и т.д.).

Настраивается SDRAM там же, настраивается LTDC контроллера. В SRDAM размещаются два буфера - один для переднего, другой для заднего слоев.

Для быстрого старта этого более, чем достаточно.

 

И что значит разрешение экрана где задавать?

Конечно же либо в самой функции magic number-ами, либо define-ами, как еще.

За коим чертом в микроконтроллерном девайсе с мелким экраном менять разрешение?

Ну если так хочется, то можно просто на лету переконфигурировать LTDC. Ток нафига...

 

P.S. Для примеров там все достаточно прозрачно

Спойлер

void LCD_Init(void)
{ 
  LTDC_InitTypeDef       LTDC_InitStruct;
  
  /* Configure the LCD Control pins ------------------------------------------*/
  LCD_CtrlLinesConfig();
  LCD_ChipSelect(DISABLE);
  LCD_ChipSelect(ENABLE);
  
  /* Configure the LCD_SPI interface -----------------------------------------*/
  LCD_SPIConfig(); 
  
  /* Power on the LCD --------------------------------------------------------*/
  LCD_PowerOn();
  
  /* Enable the LTDC Clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_LTDC, ENABLE);
  
  /* Enable the DMA2D Clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2D, ENABLE); 
  
  /* Configure the LCD Control pins */
  LCD_AF_GPIOConfig();  
  
  /* Configure the FMC Parallel interface : SDRAM is used as Frame Buffer for LCD */
  SDRAM_Init();
  
  /* LTDC Configuration *********************************************************/  
  /* Polarity configuration */
  /* Initialize the horizontal synchronization polarity as active low */
  LTDC_InitStruct.LTDC_HSPolarity = LTDC_HSPolarity_AL;     
  /* Initialize the vertical synchronization polarity as active low */  
  LTDC_InitStruct.LTDC_VSPolarity = LTDC_VSPolarity_AL;     
  /* Initialize the data enable polarity as active low */
  LTDC_InitStruct.LTDC_DEPolarity = LTDC_DEPolarity_AL;     
  /* Initialize the pixel clock polarity as input pixel clock */ 
  LTDC_InitStruct.LTDC_PCPolarity = LTDC_PCPolarity_IPC;
  
  /* Configure R,G,B component values for LCD background color */                   
  LTDC_InitStruct.LTDC_BackgroundRedValue = 0;            
  LTDC_InitStruct.LTDC_BackgroundGreenValue = 0;          
  LTDC_InitStruct.LTDC_BackgroundBlueValue = 0;  
  
  /* Configure PLLSAI prescalers for LCD */
  /* Enable Pixel Clock */
  /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
  /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz */
  /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAI_R = 192/4 = 48 Mhz */
  /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 48/8 = 6 Mhz */
  RCC_PLLSAIConfig(192, 7, 4);
  RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div8);
  
  /* Enable PLLSAI Clock */
  RCC_PLLSAICmd(ENABLE);
  /* Wait for PLLSAI activation */
  while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET)
  {
  }
  
  /* Timing configuration */  
  /* Configure horizontal synchronization width */     
  LTDC_InitStruct.LTDC_HorizontalSync = 9;
  /* Configure vertical synchronization height */
  LTDC_InitStruct.LTDC_VerticalSync = 1;
  /* Configure accumulated horizontal back porch */
  LTDC_InitStruct.LTDC_AccumulatedHBP = 29; 
  /* Configure accumulated vertical back porch */
  LTDC_InitStruct.LTDC_AccumulatedVBP = 3;  
  /* Configure accumulated active width */  
  LTDC_InitStruct.LTDC_AccumulatedActiveW = 269;
  /* Configure accumulated active height */
  LTDC_InitStruct.LTDC_AccumulatedActiveH = 323;
  /* Configure total width */
  LTDC_InitStruct.LTDC_TotalWidth = 279; 
  /* Configure total height */
  LTDC_InitStruct.LTDC_TotalHeigh = 327;
  
  LTDC_Init(&LTDC_InitStruct);
}


void LCD_LayerInit(void)
{
  LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct; 
  
  /* Windowing configuration */
  /* In this case all the active display area is used to display a picture then :
  Horizontal start = horizontal synchronization + Horizontal back porch = 30 
  Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1
  Vertical start   = vertical synchronization + vertical back porch     = 4
  Vertical stop   = Vertical start + window height -1  = 4 + 320 -1      */      
  LTDC_Layer_InitStruct.LTDC_HorizontalStart = 30;
  LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_PIXEL_WIDTH + 30 - 1); 
  LTDC_Layer_InitStruct.LTDC_VerticalStart = 4;
  LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_PIXEL_HEIGHT + 4 - 1);
  
  /* Pixel Format configuration*/
  LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565;
  /* Alpha constant (255 totally opaque) */
  LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255; 
  /* Default Color configuration (configure A,R,G,B component values) */          
  LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0;        
  LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0;       
  LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0;         
  LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0;
  /* Configure blending factors */       
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_CA;    
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA;
  
  /* the length of one line of pixels in bytes + 3 then :
  Line Lenth = Active high width x number of bytes per pixel + 3 
  Active high width         = LCD_PIXEL_WIDTH 
  number of bytes per pixel = 2    (pixel_format : RGB565) 
  */
  LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_PIXEL_WIDTH * 2) + 3);
  /* the pitch is the increment from the start of one line of pixels to the 
  start of the next line in bytes, then :
  Pitch = Active high width x number of bytes per pixel */ 
  LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_PIXEL_WIDTH * 2);
  
  /* Configure the number of lines */  
  LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_PIXEL_HEIGHT;
  
  /* Start Address configuration : the LCD Frame buffer is defined on SDRAM */    
  LTDC_Layer_InitStruct.LTDC_CFBStartAdress = LCD_FRAME_BUFFER;
  
  /* Initialize LTDC layer 1 */
  LTDC_LayerInit(LTDC_Layer1, &LTDC_Layer_InitStruct);
  
  /* Configure Layer2 */
  /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */     
  LTDC_Layer_InitStruct.LTDC_CFBStartAdress = LCD_FRAME_BUFFER + BUFFER_OFFSET;
  
  /* Configure blending factors */       
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA;    
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA;
  
  /* Initialize LTDC layer 2 */
  LTDC_LayerInit(LTDC_Layer2, &LTDC_Layer_InitStruct);
  
  /* LTDC configuration reload */  
  LTDC_ReloadConfig(LTDC_IMReload);
  
  /* Enable foreground & background Layers */
  LTDC_LayerCmd(LTDC_Layer1, ENABLE); 
  LTDC_LayerCmd(LTDC_Layer2, ENABLE);
  
  /* LTDC configuration reload */  
  LTDC_ReloadConfig(LTDC_IMReload);
  
  /* Set default font */    
  LCD_SetFont(&LCD_DEFAULT_FONT); 
  
  /* dithering activation */
  LTDC_DitherCmd(ENABLE);
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

За коим чертом в микроконтроллерном девайсе с мелким экраном менять разрешение?

Не менять на лету, а возможность в ините задать параметры дисплея, например интерфейс, разрешение и глубину цвета, чтоб не искать в разных файлах соотв. дефайны, магические цифры и пр... Это просто удобно ИМХО.

При чем тут мелкий экран - непонятно, у них тоже не только 320х200 бывает разрешение...

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не менять на лету, а возможность в ините задать параметры дисплея, например интерфейс, разрешение и глубину цвета, чтоб не искать в разных файлах соотв. дефайны, магические цифры и пр... Это просто удобно ИМХО.

Ну вон в коде фигурируют LCD_PIXEL_WIDTH, LCD_PIXEL_HEIGHT, LTDC_Pixelformat_RGB565 и другие настройки. Что, в принципе, удобно.

Особенно удобно, если надо хоть от чего-то оттолкнуться, если лень RM читать.

Тот пример как раз демонстрационный для LTDC, соответственно экран программно переводится в режим RGB-интерфейса. Так что можно быстро начать курить LTDC даже не сильно вдаваясь в мануал.

 

Я лет 5 назад, когда надо было очень быстро запилить проект на таком камне, но с экраном 800x480, именно этот проект брал за основу.

Сначала тупо увеличил размеры буферов в SDRAM и переназначил параметры экрана. Заработало сразу. А если с нуля - как минимум неделя улетела бы на поднятие SDRAM/LTDC/отрисовку примитивов.

А потом по ходу работы проект был перепилен на 99%. Так что как отправная точка самое оно (ведь @Xenia, как я понял, пока что большего и не нужно):wink2:

 

16 часов назад, mantech сказал:

Например координаты здесь не задать получается.

Кстати, тут Вы не совсем правы. Индусы (или STM-ные студенты?) все-таки сделали API для минимально необходимых компонентов

Спойлер

void     LCD_DeInit(void);   
void     LCD_Init(void);
void     LCD_LayerInit(void);
void     LCD_ChipSelect(FunctionalState NewState);
void     LCD_SetLayer(uint32_t Layerx);
void     LCD_SetColors(uint16_t _TextColor, uint16_t _BackColor); 
void     LCD_GetColors(uint16_t *_TextColor, uint16_t *_BackColor);
void     LCD_SetTextColor(uint16_t Color);
void     LCD_SetBackColor(uint16_t Color);
void     LCD_SetTransparency(uint8_t transparency);
void     LCD_ClearLine(uint16_t Line);
void     LCD_Clear(uint16_t Color);
uint32_t LCD_SetCursor(uint16_t Xpos, uint16_t Ypos);
void     LCD_SetColorKeying(uint32_t RGBValue);
void     LCD_ReSetColorKeying(void);
void     LCD_DrawChar(uint16_t Xpos, uint16_t Ypos, const uint16_t *c);
void     LCD_DisplayChar(uint16_t Line, uint16_t Column, uint8_t Ascii);
void     LCD_SetFont(sFONT *fonts);
sFONT *  LCD_GetFont(void);
void     LCD_DisplayStringLine(uint16_t Line, uint8_t *ptr);
void     LCD_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Height, uint16_t Width);
void     LCD_WindowModeDisable(void);
void     LCD_DrawLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length, uint8_t Direction);
void     LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Height, uint16_t Width);
void     LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
void     LCD_DrawEllipse(int Xpos, int Ypos, int Radius, int Radius2);
void     LCD_DrawFullEllipse(int Xpos, int Ypos, int Radius, int Radius2);
void     LCD_DrawMonoPict(const uint32_t *Pict);
void     LCD_WriteBMP(uint32_t BmpAddress);
void     LCD_DrawUniLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void     LCD_DrawFullRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
void     LCD_DrawFullCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
void     LCD_PolyLine(pPoint Points, uint16_t PointCount);
void     LCD_PolyLineRelative(pPoint Points, uint16_t PointCount);
void     LCD_ClosedPolyLine(pPoint Points, uint16_t PointCount);
void     LCD_ClosedPolyLineRelative(pPoint Points, uint16_t PointCount);
void     LCD_FillPolyLine(pPoint Points, uint16_t PointCount);
void     LCD_Triangle(pPoint Points, uint16_t PointCount);
void     LCD_FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
void     LCD_WriteCommand(uint8_t LCD_Reg);
void     LCD_WriteData(uint8_t value);
void     LCD_PowerOn(void);
void     LCD_DisplayOn(void);
void     LCD_DisplayOff(void);
void     LCD_CtrlLinesConfig(void);
void     LCD_CtrlLinesWrite(GPIO_TypeDef* GPIOx, uint16_t CtrlPins, BitAction BitVal);
void     LCD_SPIConfig(void);

 

 

Так что "ездящий текст" или прямоугольники какие-нить можно сделать:paint2: Ну, типа

265369526_VID_20200327_111416(9).gif.09751572d618cd52a7b31bea389d1b1d.gif

 

Правда, немного намудрили они с функциями, поэтому для .gif выше я дописал пару функций в ~2 строки каждая.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, Arlleex сказал:

Так что "ездящий текст" или прямоугольники какие-нить можно сделать

И как это у вас реализовано? Внешная SRDAM используется или нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

42 минуты назад, Xenia сказал:

И как это у вас реализовано? Внешная SRDAM используется или нет?

Без буфера в ОЗУ все это реализовать можно, но будет просто ужасно несмотрибельно выглядеть из-за мерцания.
Обычно стирают старую картинку/рисуют новую в буфере в ОЗУ, а только потом это все выводят на экран (передают контроллеру дисплея, который выводит на матрицу).

Мне тут начальство подкинуло без консультаций для ознакомления плату от Mikroe - Mikromedia 7 с 7" TFT 800x480 на STM32F746ZG.
Так начал разбираться - ужаснулся и прослезился. Сербы подключили дисплей через SSD1963 просто к двум разным портам 8+8 бит. Все "ногодрыгом". Дополнительное ОЗУ отсутствует как класс :fool:
С трудом удалось запустить на их плате STemWin, но мигает все при перерисовке - просто ужас.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

47 минут назад, Xenia сказал:

И как это у вас реализовано? Внешная SRDAM используется или нет?

SDRAM используется, да.

 

Та гифка работает под вот этим кодом

Спойлер

#include "main.h"

#include "stm32f4xx.h"
#include "stm32f429i_discovery.h"
#include "stm32f429i_discovery_lcd.h"

int main(void)
{ 
  LCD_Init();
  LCD_LayerInit();
  LTDC_Cmd(ENABLE);
  LCD_SetFont(&Font16x24);
  LCD_Clear(LCD_COLOR_BLACK);
  
  u32 bn = 0;               // номер буфера в SDRAM
  
  s32 x = 0, y = 0;         // координаты надписи "ARLLEEX"
  s32 dirx = 1, diry = 1;   // шаг приращения координат надписи
  
  s32 x1 = 5, y1 = 5;       // координаты кружочка
  s32 dirx1 = 4, diry1 = 4; // шаг приращения координат кружочка
  
  while(1)
  {
    // двигаем надпись
    x += dirx;   y += diry;
    if(x >= 125)  dirx = -1;
    if(y >= 270)  diry = -1;
    if(x == 0)    dirx =  1;
    if(y == 0)    diry =  1;
    
    // двигаем кружочек
    x1 += dirx1;   y1 += diry1;
    if(x1 >= 115)  dirx1 = -4;
    if(y1 >= 155)  diry1 = -4;
    if(x1 <= 5)    dirx1 =  4;
    if(y1 <= 5)    diry1 =  4;
    
    // один из слоев выводим
    LCD_SetBuf(!bn);
    
    // даем небольшую паузу (костыль), чтобы экран прорисовался новым буфером
    // + эта задержка ну типа минимальный тик для задания межкадрового интервала
    for(u32 i = 0; i < 500000; ++i);
    
    // задаем слой, противоположный выводимому
    LCD_SetXY(0, 0, bn);
    
    // рисуем на нем кружочек...
    LCD_Clear(LCD_COLOR_BLACK);
    LCD_SetXY(x1, y1, bn);
    LCD_SetColors(LCD_COLOR_GREEN, LCD_COLOR_BLACK);
    LCD_DrawFullEllipse(x1, y1, 5, 5);
    
    // ...и надпись
    LCD_SetXY(x, y, bn);
    LCD_SetColors(LCD_COLOR_WHITE, LCD_COLOR_BLACK);
    LCD_DisplayStringLine(LCD_LINE_1, (uint8_t *)"ARLLEEX");
    
    bn ^= 1; // меняем активный буфер
  }
}



...



#define LCD_FRAME_BUFFER       ((uint32_t)0xD0000000)
#define BUFFER_OFFSET          ((uint32_t)0x25800) 

void LCD_SetXY(uint32_t x, uint32_t y, uint32_t BufN)
{
  if(!BufN)
    CurrentFrameBuffer = LCD_FRAME_BUFFER + 2*(x + (LCD_PIXEL_WIDTH*y));
  else
    CurrentFrameBuffer = LCD_FRAME_BUFFER + BUFFER_OFFSET + 2*(x + (LCD_PIXEL_WIDTH*y));
}

void LCD_SetBuf(uint32_t BufN)
{
  LTDC_LayerAddress(LTDC_Layer1, LCD_FRAME_BUFFER + BufN*BUFFER_OFFSET);
  LTDC_ReloadConfig(LTDC_IMReload);
}

// все-таки подправил "библиотечную" функцию (BUFFER_OFFSET/2, а не BUFFER_OFFSET)
void LCD_Clear(uint16_t Color)
{
  uint32_t index = 0;
  
  for (index = 0x00; index < BUFFER_OFFSET/2; index++)
    *(__IO uint16_t*)(CurrentFrameBuffer + (2*index)) = Color;
}

// ну и второй слой выключил нафих
void LCD_LayerInit(void)
{
  LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct; 
  
  /* Windowing configuration */
  /* In this case all the active display area is used to display a picture then :
  Horizontal start = horizontal synchronization + Horizontal back porch = 30 
  Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1
  Vertical start   = vertical synchronization + vertical back porch     = 4
  Vertical stop   = Vertical start + window height -1  = 4 + 320 -1      */      
  LTDC_Layer_InitStruct.LTDC_HorizontalStart = 30;
  LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_PIXEL_WIDTH + 30 - 1); 
  LTDC_Layer_InitStruct.LTDC_VerticalStart = 4;
  LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_PIXEL_HEIGHT + 4 - 1);
  
  /* Pixel Format configuration*/
  LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565;
  /* Alpha constant (255 totally opaque) */
  LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255; 
  /* Default Color configuration (configure A,R,G,B component values) */          
  LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0;        
  LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0;       
  LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0;         
  LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0;
  /* Configure blending factors */       
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_CA;    
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA;
  
  /* the length of one line of pixels in bytes + 3 then :
  Line Lenth = Active high width x number of bytes per pixel + 3 
  Active high width         = LCD_PIXEL_WIDTH 
  number of bytes per pixel = 2    (pixel_format : RGB565) 
  */
  LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_PIXEL_WIDTH * 2) + 3);
  /* the pitch is the increment from the start of one line of pixels to the 
  start of the next line in bytes, then :
  Pitch = Active high width x number of bytes per pixel */ 
  LTDC_Layer_InitStruct.LTDC_CFBPitch = (LCD_PIXEL_WIDTH * 2);
  
  /* Configure the number of lines */  
  LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_PIXEL_HEIGHT;
  
  /* Start Address configuration : the LCD Frame buffer is defined on SDRAM */    
  LTDC_Layer_InitStruct.LTDC_CFBStartAdress = LCD_FRAME_BUFFER;
  
  /* Initialize LTDC layer 1 */
  LTDC_LayerInit(LTDC_Layer1, &LTDC_Layer_InitStruct);
  
  /* Configure Layer2 */
  /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */     
  LTDC_Layer_InitStruct.LTDC_CFBStartAdress = LCD_FRAME_BUFFER + BUFFER_OFFSET*2;
  
  /* Configure blending factors */       
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA;    
  LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA;
  
  /* Initialize LTDC layer 2 */
  LTDC_LayerInit(LTDC_Layer2, &LTDC_Layer_InitStruct);
  
  /* LTDC configuration reload */  
  LTDC_ReloadConfig(LTDC_IMReload);
  
  /* Enable foreground & background Layers */
  LTDC_LayerCmd(LTDC_Layer1, ENABLE); 
  //LTDC_LayerCmd(LTDC_Layer2, ENABLE);
  
  /* LTDC configuration reload */  
  LTDC_ReloadConfig(LTDC_IMReload);
  
  /* Set default font */    
  LCD_SetFont(&LCD_DEFAULT_FONT); 
  
  /* dithering activation */
  LTDC_DitherCmd(ENABLE);
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Arlleex сказал:

SDRAM используется, да.

Именно поэтому я сразу заявила, что демо-программу обсуждать не хочу. И вообще всё, где торчит хедер

 "stm32f429i_discovery.h"

Потому что он что ни попадя переопределяет на свой лад. Я же говорила, что эту программу видела (в кодах разбиралась), а потому и видеть ее больше не желаю. Тогда как вы, вероятно, дальше main() не заглядывали, а потому

  LCD_Init();
  LCD_LayerInit();

кажется вам легким и простым, т.к. вы не видели всего того дерьма, которое за этой простотой стоит.

 

 

3 часа назад, Baser сказал:

Без буфера в ОЗУ все это реализовать можно, но будет просто ужасно несмотрибельно выглядеть из-за мерцания.
Обычно стирают старую картинку/рисуют новую в буфере в ОЗУ, а только потом это все выводят на экран (передают контроллеру дисплея, который выводит на матрицу).

Так я же не видеофильмы на этом дисплее собралась крутить, а время от времени (не чаще 1 раз в секунду) обновлять на экране текст. Типа измерялка у меня на этом МК работает, а человеческий глаз все равно цифирь, меняющуюся чаще, чем 1 Гц, не воспринимает. Типичный пример - напольные весы :). У меня хоть и не весы, но ситуация похожая - надо каждую секунду число на экране обновлять, если оно изменилось. Отсюда и мое желание вывести на экран текст (число у меня 7-значное), а не показывать мультики, непрерывно гоняя содержимое SDRAM на экран. Причем SDRAM мне нужна для иных целей - для накопления данных. Я понимаю, что такой дисплей, какой установлен на этой плате, для моих целей не нужен (избыточен). Но не вырывать же мне его с корнем, раз уж он там уже стоит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Baser сказал:

С трудом удалось запустить на их плате STemWin, но мигает все при перерисовке - просто ужас.

Так может сербы не для емвина ее делали, а для статических картинок?)))

ЗЫ Хотя пишут -  "represents a perfect solution for any type of multimedia application.

Смешно...

3 часа назад, Baser сказал:

Дополнительное ОЗУ отсутствует как класс

А чем бы оно тут помогло?

4 часа назад, Baser сказал:

Без буфера в ОЗУ все это реализовать можно, но будет просто ужасно несмотрибельно выглядеть из-за мерцания.

Все-таки так и не понял, как это будет работать без внешней памяти? Дисплей, как понял по иниту - просто матрица без ОЗУ, т.е. если его использовать, то ОЗУ размером X*Y*байты цвета все равно нужно, причем не важно с какой частотой там текст рисовать, раз в сек или 10 раз...

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, Baser сказал:

С трудом удалось запустить на их плате STemWin, но мигает все при перерисовке - просто ужас.

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...