- /* Initialize the region corresponding to external RAM */
- #if defined ( __ICCARM__ )
- extern uint32_t __region_EXTRAM_start__;
- extern uint32_t __region_EXTRAM_end__;
- address = (uint32_t)&__region_EXTRAM_start__;
- size = (uint32_t)&__region_EXTRAM_end__ - (uint32_t)&__region_EXTRAM_start__ + 1;
- #elif defined (__CC_ARM) || defined(__ARMCC_VERSION)
- extern uint32_t Image$RW_EXTRAM$Base;
- extern uint32_t Image$RW_EXTRAM$ZI$Length;
- extern uint32_t Image$RW_EXTRAM$Length;
- address = (uint32_t)&Image$RW_EXTRAM$Base;
- size = (uint32_t)&Image$RW_EXTRAM$Length + (uint32_t)&Image$RW_EXTRAM$ZI$Length;
- #elif defined ( __GNUC__ )
- extern uint32_t __EXTRAM_BEGIN;
- extern uint32_t __EXTRAM_SIZE;
- address = (uint32_t)&__EXTRAM_BEGIN;
- size = (uint32_t)&__EXTRAM_SIZE;
- #else
- #error "Compiler toolchain is unsupported"
- #endif
- if (size != 0)
- {
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;
- MPU_InitStruct.Number = index;
- MPU_InitStruct.SubRegionDisable = 0u;
- MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
- MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
- MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
- MPU_AdjustRegionAddressSize(address, size, &MPU_InitStruct);
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
- index++;
- }
上面Image$$RW_EXTRAM$$Base;对应散列文件中RW_EXTRAM。
- RW_EXTRAM 0x90000000 0x2000000 {
- .ANY (+RW +ZI)
- }
分散加载文件这里加上.ANY (+RW +ZI),就可以在申请内存的时候自动使用外部RAM了。
2、DMA2D初始化:MX_DMA2D_Init();
DMA2D_R2M:寄存器到存储
- hdma2d.Instance = DMA2D;
- hdma2d.Init.Mode = DMA2D_R2M;
- hdma2d.Init.ColorMode = DMA2D_OUTPUT_ARGB4444;
- hdma2d.Init.OutputOffset = 0;
- if (HAL_DMA2D_Init(&hdma2d) != HAL_OK)
- {
- Error_Handler();
- }
3、LTDC初始化:MX_LTDC_Init();
其中配置了一个LAYER:pLayerCfg。
- hltdc.Instance = LTDC;
- hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
- hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
- hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
- hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
- hltdc.Init.HorizontalSync = 3;
- hltdc.Init.VerticalSync = 3;
- hltdc.Init.AccumulatedHBP = 11;
- hltdc.Init.AccumulatedVBP = 11;
- hltdc.Init.AccumulatedActiveW = 811;
- hltdc.Init.AccumulatedActiveH = 491;
- hltdc.Init.TotalWidth = 819;
- hltdc.Init.TotalHeigh = 499;
- hltdc.Init.Backcolor.Blue = 0;
- hltdc.Init.Backcolor.Green = 0;
- hltdc.Init.Backcolor.Red = 0;
-
- if (HAL_LTDC_Init(&hltdc) != HAL_OK)
- {
- Error_Handler();
- }
- pLayerCfg.WindowX0 = 0;
- pLayerCfg.WindowX1 = 800;
- pLayerCfg.WindowY0 = 0;
- pLayerCfg.WindowY1 = 480;
- pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
- pLayerCfg.Alpha = 255;
- pLayerCfg.Alpha0 = 0;
- pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
- pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
- pLayerCfg.FBStartAdress = (uint32_t)&g_ltdc_lcd_framebuf;
- pLayerCfg.ImageWidth = LAYER_SIZE_X;
- pLayerCfg.ImageHeight = LAYER_SIZE_Y;
- pLayerCfg.Backcolor.Blue = 0;
- pLayerCfg.Backcolor.Green = 0;
- pLayerCfg.Backcolor.Red = 0;
- if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
- {
- Error_Handler();
- }
为LTDS设置地址
/* DMA2D output address in SRAM : this is the buffer displayed on LCD screen */
HAL_LTDC_SetAddress(&hltdc, (uint32_t)(&g_ltdc_lcd_framebuf), LTDC_LAYER_1);
其中g_ltdc_lcd_framebuf设置成:
uint16_t g_ltdc_lcd_framebuf[1280][800];
可能设大,这么大的空间也只能放到外部RAM中。
二、添加DMA2D绘图函数
这部分参考野火资料
1、填充COLOR到目标地址
- static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize,
- uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)
- {
- hdma2d.Init.Mode = DMA2D_R2M;
- hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565;
- hdma2d.Init.OutputOffset = OffLine;
- hdma2d.Instance = DMA2D;
- /* DMA2D 初始化 */
- if (HAL_DMA2D_Init(&hdma2d) == HAL_OK) {
- if (HAL_DMA2D_ConfigLayer(&hdma2d, LayerIndex) == HAL_OK) {
- if (HAL_DMA2D_Start(&hdma2d, (uint32_t)ColorIndex, (uint32_t)pDst, xSize, ySize) == HAL_OK) {
- /* DMA轮询传输 */
- HAL_DMA2D_PollForTransfer(&hdma2d, 100);
- }
- }
- }
- }
2、画矩形
- void LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height,uint32_t Color)
- {
- uint32_t x_address = 0;
- /* 设置矩形开始地址 */
- if (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) {
- x_address = (hltdc.LayerCfg[0].FBStartAdress) + 4*(LCD_GetXSize()*Ypos + Xpos);
- } else if (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_RGB888) {
- x_address = (hltdc.LayerCfg[0].FBStartAdress) + 3*(LCD_GetXSize()*Ypos + Xpos);
- } else if ((hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
- (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
- (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_AL88)) {
- x_address = (hltdc.LayerCfg[0].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
- } else {
- x_address = (hltdc.LayerCfg[0].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
- }
- /* 填充矩形 */
- LL_FillBuffer(0, (uint32_t *)x_address, Width, Height, (LCD_GetXSize() - Width), Color);
- }
3、画横线
- void LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length,uint32_t Color)
- {
- uint32_t Xaddress = 0;
- if (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + 4*(LCD_GetXSize()*Ypos + Xpos);
- } else if (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_RGB888) {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + 3*(LCD_GetXSize()*Ypos + Xpos);
- } else if ((hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
- (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
- (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_AL88)) {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
- } else {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + (LCD_GetXSize()*Ypos + Xpos);
- }
- /* 填充数据 */
- LL_FillBuffer(0, (uint32_t *)Xaddress, Length, 1, 0, Color);
- }
4、画竖线
- void LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length,uint32_t Color)
- {
- uint32_t Xaddress = 0;
- if (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + 4*(LCD_GetXSize()*Ypos + Xpos);
- } else if (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_RGB888) {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + 3*(LCD_GetXSize()*Ypos + Xpos);
- } else if ((hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \
- (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
- (hltdc.LayerCfg[0].PixelFormat == LTDC_PIXEL_FORMAT_AL88)) {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + 2*(LCD_GetXSize()*Ypos + Xpos);
- } else {
- Xaddress = (hltdc.LayerCfg[0].FBStartAdress) + (LCD_GetXSize()*Ypos + Xpos);
- }
- /* 填充数据 */
- LL_FillBuffer(0, (uint32_t *)Xaddress, 1, Length, (LCD_GetXSize() - 1), Color);
- }
三、画个直方图
- typedef struct{
- uint16_t posX;
- uint16_t posY;
- uint16_t height;
- uint16_t width;
- uint32_t color;
- }ZFTU;
- ZFTU zftu[6];
- static void init_zftu(void)
- {
- uint8_t i;
- for(i=0;i<6;i++)
- {
- zftu[i].width=80;
- zftu[i].height=80+i*40;
- zftu[i].posX=120*i+50;
- zftu[i].posY=80;
- zftu[i].color=0x00FF0000>>i*2;
- }
- }
- static void draw_zftu(void)
- {
- uint8_t i;
- for(i=0;i<6;i++)
- {
- LCD_FillRect(zftu[i].posX,480-zftu[i].height-zftu[i].posY,zftu[i].width,zftu[i].height,zftu[i].color);
- }
- }