爱板网论坛

查看: 289|回复: 0

[教程] 18..STM32F469I---标准外设库DSI刷屏

[复制链接]

主题

好友

1万

积分

翰林

  • TA的每日心情
    郁闷
    10 小时前
  • 签到天数: 710 天

    连续签到: 5 天

    [LV.9]以坛为家II

    发表于 2018-1-12 14:56:54 |显示全部楼层
    【STM32F469I试用】标准外设库DSI刷屏【转】

    虽然意法现在主推HAL库,低功耗L系列的单片机甚至已不再提供标准外设库,HAL的资料越来越丰富,是接下来设计产品的主流,但现在也还有很大一部分工程师继续使用着标准外设库,或是之前项目工程是基于标准库,移植起来也相对方便。STM32F469这块板子ST在HAL库以及提供了DSI LCD部分的相关例程,使用起来真是方便。不过为了适配接下来RTT的移植(RTT是基于标准外设库),只能把HAL库的这部分的程序移植到标准外设库上。       先上两张图看看效果

    1.jpg


    2.jpg


    首先,是SDRAM的初始化,整体的程序参考标准外设库stm324x9i_eval_fmc_sdram.c文件里的初始化函数,不过由于我们采用RGB565的格式来储存像素点的数据,所以对初始化函数的内容也做相应的改动:SDRAM_MEMORY_WIDTH改为16b的宽度,以对应RGB565的两个字节数据。
    <span style="line-height: 1.5;">FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth  =</span><font color="#ff0000" style="line-height: 1.5;"> SDRAM_MEMORY_WIDTH</font><span style="line-height: 1.5;">;</span>
      FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;

    接下来是按照HAL库的初始化顺序,先后对DSI、LTDC初始化

    LCD_Reset();
      DSI_Config();
      LCD_Config();
      DSI_Start(DSI);
      OTM8009Setup(DSI, IMAGEFORMAT_RGB565);

    在LCD_Config中,值得注意的是LTDC_CFBStartAdress的设置,这个地址指向了LCD显存的地址,这里用SDRAM来作为显存,RGB565格式下,0xC0000000开始的连续两个地址代表一个像素点的颜色信息,所以打点函数也就是计算位置,往SDRAM中填入相应的颜色信息。

    LTDC_Layer_InitStruct.LTDC_CFBStartAdress = ((uint32_t)0xC0000000);
    /* the length of one line of pixels in bytes + 3 then :
    Line Length = Active high width x number of bytes per pixel + 3
    Active high width = 480
    number of bytes per pixel = 2 (pixel_format : RGB565) */
    LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((480 * 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 = (480 * 2);
    /* Configure the number of lines */
    LTDC_Layer_InitStruct.LTDC_CFBLineNumber = 800;
    /* Initializes the Layer */
    LTDC_LayerInit(LTDC_Layer1, <DC_Layer_InitStruct);
    /* Enable Layer 1 */
    LTDC_LayerCmd(LTDC_Layer1, ENABLE);
    /* Reload configuration of Layer 1 */
    LTDC_ReloadConfig(LTDC_IMReload);
    /* Enable The LCD */
    LTDC_Cmd(ENABLE);

    SDRAM显存与LCD显示的关系如下图:画得不是很好、呵呵、不过应该能大致了解。

    3.jpg


    整个屏幕实现横屏和竖屏的效果,由宏定义控制,其中0为横屏,1为竖屏。

    #define OTM_8009_sta  1   //横屏  0   竖屏  1

    横屏和竖屏的效果在最底层的打点函数上实现

    #if OTM_8009_sta==0  
    *(__IO uint16_t*) (LCD_FB_START_ADDRESS + (2*(Xpos*480 + 480-Ypos))) = RGB_Code;
    #else   
      /* Write data value to all SDRAM memory */
      *(__IO uint16_t*) (LCD_FB_START_ADDRESS + (2*(Ypos*480 + Xpos))) = RGB_Code;
    #endif

    其他的字符函数、画圆、画矩形函数都是基于上述打点函数,基本是从HAL库直接复制过来,基本不用修改。

    void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
    {
      int32_t   D;    /* Decision Variable */
      uint32_t  CurX; /* Current X Value */
      uint32_t  CurY; /* Current Y Value */
      D = 3 - (Radius << 1);
      CurX = 0;
      CurY = Radius;
      while (CurX <= CurY)
      {
        BSP_LCD_DrawPixel((Xpos + CurX), (Ypos - CurY), DrawProp[ActiveLayer].TextColor);
        BSP_LCD_DrawPixel((Xpos - CurX), (Ypos - CurY), DrawProp[ActiveLayer].TextColor);
        BSP_LCD_DrawPixel((Xpos + CurY), (Ypos - CurX), DrawProp[ActiveLayer].TextColor);
        BSP_LCD_DrawPixel((Xpos - CurY), (Ypos - CurX), DrawProp[ActiveLayer].TextColor);
        BSP_LCD_DrawPixel((Xpos + CurX), (Ypos + CurY), DrawProp[ActiveLayer].TextColor);
        BSP_LCD_DrawPixel((Xpos - CurX), (Ypos + CurY), DrawProp[ActiveLayer].TextColor);
        BSP_LCD_DrawPixel((Xpos + CurY), (Ypos + CurX), DrawProp[ActiveLayer].TextColor);
        BSP_LCD_DrawPixel((Xpos - CurY), (Ypos + CurX), DrawProp[ActiveLayer].TextColor);
        if (D < 0)
        {
          D += (CurX << 2) + 6;
        }
        else
        {
          D += ((CurX - CurY) << 2) + 10;
          CurY--;
        }
        CurX++;
      }
    }

    void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode)
    {
      uint16_t refcolumn = 1, i = 0;
      uint32_t size = 0, xsize = 0;
      uint8_t  *ptr = Text;
      /* Get the text size */
      while (*ptr++) size ++ ;
      /* Characters number per line */
      xsize = (OTM8009A_800X480_WIDTH/DrawProp[ActiveLayer].pFont->Width);
      switch (Mode)
      {
      case CENTER_MODE:
        {
          refcolumn = Xpos + ((xsize - size)* DrawProp[ActiveLayer].pFont->Width) / 2;
          break;
        }
      case LEFT_MODE:
        {
          refcolumn = Xpos;
          break;
        }
      case RIGHT_MODE:
        {
          refcolumn = - Xpos + ((xsize - size)*DrawProp[ActiveLayer].pFont->Width);
          break;
        }
      default:
        {
          refcolumn = Xpos;
          break;
        }
      }
      /* Check that the Start column is located in the screen */
      if ((refcolumn < 1) || (refcolumn >= 480))//0x8000
      {
        refcolumn = 1;
      }
      /* Send the string character by character on LCD */
      while ((*Text != 0) & (((OTM8009A_800X480_WIDTH - (i*DrawProp[ActiveLayer].pFont->Width)) & 0xFFFF) >= DrawProp[ActiveLayer].pFont->Width))
      {
        /* Display one character on LCD */
        BSP_LCD_DisplayChar(refcolumn, Ypos, *Text);
        /* Decrement the column position by 16 */
        refcolumn += DrawProp[ActiveLayer].pFont->Width;
        /* Point on the next character */
        Text++;
        i++;
      }
    }

    STM32F4xx_DSP_StdPeriph_Lib_V1.6.1.zip (1.32 MB, 下载次数: 0, 售价: 2 铜板)



    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /3 下一条

    手机版|爱板网

    GMT+8, 2018-9-21 10:54 , Processed in 0.109534 second(s), 14 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-5   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001056号

    Powered by Discuz!

    返回顶部