你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。

  1. /*************************************************************************************************************
  2. * 文件名                :        stm32f7_ltdc.c
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
  4. * 创建时间                :        2019-09-12
  5. * 最后修改时间        :        2019-09-12
  6. * 详细:        
  7. *************************************************************************************************************/        
  8. #include "stm32f7_ltdc.h"
  9. #include "SYSTEM.H"
  10. #include "stm32f7_sdram.h"
  11. #include "DMA2D.h"


  12. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式


  13. //记录全局层配置信息
  14. typedef struct
  15. {
  16.         u16 sx;                                        //层开始X坐标,从0开始
  17.         u16 sy;                                        //层开始Y坐标,从0开始
  18.         u16 width;                                //层宽度
  19.         u16 height;                                //层高度
  20.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化
  21. }LTDC_LayerConfig;



  22. //全局的LTDC配置信息
  23. typedef struct
  24. {
  25.         u16 lcd_width;                                                //显示器宽度
  26.         u16 lcd_height;                                                //显示器高度
  27.         LTDC_LayerConfig LayerConfig[2];        //层信息
  28. }LTDC_ConfigData;


  29. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置


  30. //显示屏信息
  31. typedef struct
  32. {
  33.         u16         Width;                //面板宽度,单位:像素
  34.         u16         Height;                //面板高度,单位:像素
  35.         u8          Thbp;                //水平后廊
  36.         u8          Thfp;                //水平前廊
  37.         u8          Thw;                //水平同步宽度
  38.         u8          Tvbp;                //垂直后廊
  39.         u8          Tvfp;                //垂直前廊
  40.         u8          Tvw;                //垂直同步宽度
  41.         u8          DCLK;                //时钟速度,MHz
  42.         
  43.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效
  44.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效
  45.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效
  46.         bool        PCPOL;                //像素时钟反向
  47. }LTDC_INFO_TYPE;


  48. LTDC_INFO_TYPE DefaultLCD_Info =
  49. {
  50.         480,        //面板宽度,单位:像素
  51.         272,        //面板高度,单位:像素
  52.         41,                //水平后廊
  53.         8,                //水平前廊
  54.         2,                //水平同步宽度
  55.         2,                //垂直后廊
  56.         4,                //垂直前廊
  57.         10,                //垂直同步宽度
  58.         9,                //时钟速度,MHz
  59.         0,                //水平同步极性,0:低电平有效;1:高电平有效
  60.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
  61.         1,                //数据使能极性,0:低电平有效;1:高电平有效
  62.         FALSE,        //像素时钟反向
  63. };

  64. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化


  65. /*************************************************************************************************************************
  66. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
  67. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)
  68. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度
  69. * 返回        :                        无
  70. * 依赖        :                        底层宏定义
  71. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  72. * 时间        :                        2019-10-28
  73. * 最后修改时间 :         2019-10-28
  74. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新
  75. *************************************************************************************************************************/
  76. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
  77. {
  78.         u32 temp;
  79.         u8 pixformat=0;
  80.         
  81.         if(LayerIndex==0)
  82.         {
  83.                 //基本配置
  84.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
  85.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
  86.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
  87.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
  88.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
  89.                 //配置窗口
  90.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
  91.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
  92.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
  93.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
  94.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式
  95.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
  96.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
  97.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
  98.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
  99.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
  100.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        
  101.                
  102.                 //记录层窗口大小位置信息
  103.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;               
  104.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        
  105.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        
  106.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
  107.         }else
  108.         {
  109.                 //基本配置
  110.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
  111.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
  112.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
  113.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
  114.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
  115.                 //配置窗口
  116.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
  117.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置
  118.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
  119.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
  120.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式
  121.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
  122.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
  123.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节
  124.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节
  125.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
  126.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        
  127.                
  128.                 //记录层窗口大小位置信息
  129.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
  130.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        
  131.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        
  132.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
  133.         }
  134. }



  135. /*************************************************************************************************************************
  136. * 函数        :                        void LTDC_Init(void)
  137. * 功能        :                        LTDC 接口初始化
  138. * 参数        :                        无
  139. * 返回        :                        无
  140. * 依赖        :                        底层宏定义
  141. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  142. * 时间        :                        2019-09-08
  143. * 最后修改时间 :         2019-09-08
  144. * 说明        :                         用于初始化STM32F7 LTDC 接口
  145. *************************************************************************************************************************/  
  146. void LTDC_Init(void)
  147. {
  148.         u32 temp;
  149.         
  150.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能
  151.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位
  152.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟
  153.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟
  154.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟
  155.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟
  156.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟

  157.         
  158.         //初始化IO
  159.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4
  160.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG12
  161.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15
  162.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7
  163.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15
  164.         
  165.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        
  166.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        
  167.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14
  168.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14
  169.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14
  170.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14
  171.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14
  172.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14
  173.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF14
  174.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14
  175.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14
  176.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14
  177.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
  178.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14
  179.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14
  180.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14
  181.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14
  182.         
  183.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF14
  184.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14
  185.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
  186.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14
  187.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14
  188.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14
  189.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14
  190.         
  191.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14
  192.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14
  193.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14
  194.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14
  195.         
  196.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz
  197.         //设置LTDC 全局控制寄存器 (LTDC_GCR)
  198.         temp = 0;
  199.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性
  200.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性
  201.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性
  202.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
  203.         LTDC->GCR = temp;
  204.         //LTDC 后沿配置寄存器 (LTDC_BPCR)
  205.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。
  206.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。
  207.         LTDC->BPCR=temp;        
  208.         
  209.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)
  210.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1
  211.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
  212.         LTDC->AWCR=temp;        
  213.         //LTDC 总宽度配置寄存器 (LTDC_TWCR)
  214.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1
  215.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
  216.         LTDC->TWCR=temp;                                

  217.         //背景设置
  218.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)
  219.         LTDC_Enable(TRUE);                                        //开启LTDC
  220.         //初始化层1
  221.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
  222.         //初始化层2
  223.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
  224.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色
  225.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色
  226.         LTDC_LayerEnable(0, TRUE);                        //使能层1
  227.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
  228.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示
  229. }

  230. /*************************************************************************************************************************
  231. * 函数                        :        void LTDC_LayerRefreshConfig(void)
  232. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
  233. * 参数                        :        无
  234. * 返回                        :        无
  235. * 依赖                        :        底层宏定义
  236. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  237. * 时间                        :        2019-10-29
  238. * 最后修改时间         :         2019-10-29
  239. * 说明                        :        修改层配置后必须重新加载,否则不会生效
  240. *************************************************************************************************************************/
  241. void LTDC_LayerRefreshConfig(void)
  242. {
  243.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
  244. }

  245. /*************************************************************************************************************************
  246. * 函数                        :        void LTDC_Enable(bool Enable)
  247. * 功能                        :        LTDC使能设置
  248. * 参数                        :        Enable:TRUE:使能;FALSE:失能
  249. * 返回                        :        无
  250. * 依赖                        :        底层宏定义
  251. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  252. * 时间                        :        2019-10-29
  253. * 最后修改时间         :         2019-10-29
  254. * 说明                        :        
  255. *************************************************************************************************************************/
  256. void LTDC_Enable(bool Enable)
  257. {
  258.         if(Enable)
  259.         {
  260.                 LTDC->GCR |= BIT0;                                        //打开LTDC
  261.         }
  262.         else
  263.         {
  264.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC
  265.         }
  266. }

  267. /*************************************************************************************************************************
  268. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
  269. * 功能                        :        LTDC 层使能设置
  270. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
  271. * 返回                        :        无
  272. * 依赖                        :        底层宏定义
  273. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  274. * 时间                        :        2019-10-29
  275. * 最后修改时间         :         2019-10-29
  276. * 说明                        :        
  277. *************************************************************************************************************************/
  278. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
  279. {
  280.         if(Enable)
  281.         {
  282.                 if(LayerIndex == 0)                                        //层1
  283.                 {
  284.                         LTDC_Layer1->CR |= BIT0;                //使能层1
  285.                 }
  286.                 else
  287.                 {
  288.                         LTDC_Layer2->CR |= BIT0;                //使能层2
  289.                 }
  290.         }
  291.         else
  292.         {
  293.                 if(LayerIndex == 0)                                        //层1
  294.                 {
  295.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1
  296.                 }
  297.                 else
  298.                 {
  299.                         LTDC_Layer2->CR &= ~BIT0;                //失能层2
  300.                 }
  301.         }
  302. }




  303. /*************************************************************************************************************************
  304. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        
  305. * 功能                        :        STM32F7 LTDC时钟初始化
  306. * 参数                        :        ClockFreq:时钟频率,2-168MHZ
  307. * 返回                        :        是否设置成功
  308. * 依赖                        :        底层宏定义
  309. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  310. * 时间                        :        2019-10-28
  311. * 最后修改时间         :         2019-10-28
  312. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432
  313. *************************************************************************************************************************/
  314. bool LTDC_ClockInit(u16 ClockFreq)
  315. {
  316.         u32 TimeOut = 0;
  317.         u32 VCO;
  318.         u32 PLLSAIR;                //PLLSAICFGR[30:28]
  319.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]
  320.         u32 temp;
  321.         
  322.         if(ClockFreq < 1)ClockFreq = 1;
  323.         if(ClockFreq > 100) ClockFreq = 100;
  324.         
  325.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟
  326.         TimeOut = 0;
  327.         while(RCC->CR&(1<<29))                                                //等待关闭成功
  328.         {
  329.                 nop;
  330.                 TimeOut ++;
  331.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时
  332.         }
  333.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频
  334.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
  335.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
  336.         if(ClockFreq <= 6)
  337.         {
  338.                 PLLSAIR = 4;        //4分频
  339.                 PLLSAIDIVR = 3;        //16分频
  340.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;
  341.         }
  342.         else if(ClockFreq <= 13)
  343.         {
  344.                 PLLSAIR = 4;        //4分频
  345.                 PLLSAIDIVR = 2;        //8分频
  346.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
  347.         }
  348.         else if(ClockFreq <= 26)
  349.         {
  350.                 PLLSAIR = 2;        //2分频
  351.                 PLLSAIDIVR = 2;        //8分频
  352.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
  353.         }
  354.         else if(ClockFreq <= 52)
  355.         {
  356.                 PLLSAIR = 2;        //2分频
  357.                 PLLSAIDIVR = 1;        //4分频
  358.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
  359.         }
  360.         else if(ClockFreq <= 104)
  361.         {
  362.                 PLLSAIR = 2;        //2分频
  363.                 PLLSAIDIVR = 0;        //2分频
  364.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;
  365.         }
  366.         //设置PLLSAICFGR
  367.         temp = RCC->PLLSAICFGR;
  368.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置
  369.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]
  370.         temp |= VCO << 6;                                                        //设置VCO
  371.         RCC->PLLSAICFGR = temp;
  372.         //设置DCKCFGR1
  373.         temp = RCC->DCKCFGR1;
  374.         temp &= ~(3<<16);                                                        //清除之前的设置
  375.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]
  376.         RCC->DCKCFGR1 = temp;
  377.         //启动时钟
  378.         RCC->CR |= 1<<28;                                                        //启动SAI时钟
  379.         TimeOut = 0;
  380.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功
  381.         {
  382.                 nop;
  383.                 TimeOut ++;
  384.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时
  385.         }
  386.         
  387.         return TRUE;
  388. }


  389. /*************************************************************************************************************************
  390. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        
  391. * 功能                        :        矩形填充(使用DMA2D)
  392. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
  393. * 返回                        :        无
  394. * 依赖                        :        底层宏定义
  395. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  396. * 时间                        :        2019-10-30
  397. * 最后修改时间         :         2019-10-30
  398. * 说明                        :        采用DMA2D实现
  399. *************************************************************************************************************************/
  400. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
  401. {
  402.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1),  DMA2D_COLOR_ARGB8888, color);                //DMA2D进行单色填充
  403.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
  404. }


  405. /*************************************************************************************************************************
  406. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)
  407. * 功能                        :        清屏(使用DMA2D)
  408. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色
  409. * 返回                        :        无
  410. * 依赖                        :        底层宏定义
  411. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  412. * 时间                        :        2019-10-30
  413. * 最后修改时间         :         2019-10-30
  414. * 说明                        :        采用DMA2D实现
  415. *************************************************************************************************************************/
  416. void LTDC_Clear(u8 LayerIndex,u32 color)
  417. {
  418.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充
  419.         SYS_DelayMS(5);
  420.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
  421. }


  422. /*************************************************************************************************************************
  423. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
  424. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
  425. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址
  426. * 返回                        :        无
  427. * 依赖                        :        底层宏定义
  428. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  429. * 时间                        :        2019-10-30
  430. * 最后修改时间         :         2019-10-30
  431. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致
  432. *************************************************************************************************************************/
  433. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
  434. {
  435.         DMA2D_FillImageToFGRAM(ImageAddr+sy*LTDC_WIDTH+sx, (u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1), LTDC_WIDTH-(ex-sx+1), DMA2D_COLOR_ARGB8888);//DMA2D进行矩形图形填充
  436.         DMA2D_WaitTransferComplete(500);
  437. }
复制代码
  1. /*************************************************************************************************************
  2. * 文件名                :        stm32f7_ltdc.h
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
  5. * 创建时间                :        2019-09-12
  6. * 最后修改时间        :        2019-09-12
  7. * 详细:        
  8. *************************************************************************************************************/               
  9. #ifndef __STM32F7_LTDC_H_
  10. #define        __STM32F7_LTDC_H_           
  11. #include "system.h"
  12. #include "DMA2D.h"

  13. #define LTDC_WIDTH                480
  14. #define LTDC_HEIGHT                272


  15. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];

  16. //像素格式定义
  17. typedef enum
  18. {
  19.         LTDC_ARGB8888         = 0,
  20.         LTDC_RGB888         = 1,
  21.         LTDC_RGB565         = 2,
  22.         /*LTDC_ARGB1555         = 3,
  23.         LTDC_ARGB4444         = 4,
  24.         LTDC_L8                 = 5,        //8 位 Luminance
  25.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance
  26.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/
  27. }LTDC_PixelFormat;
  28. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式




  29. //画点函数32bit ARGB8888格式
  30. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)
  31. {
  32.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;
  33. }

  34. //初始化DISP引脚
  35. __inline void LCD_DispIoInit(void)
  36. {
  37.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        
  38.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路
  39. }

  40. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置
  41. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化
  42. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置
  43. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
  44. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)

  45. //图形相关API
  46. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式
  47. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)
  48. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)

  49. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码


#endif //__STM32F7_LTDC_H_



收藏 评论0 发布时间:2021-12-14 10:49

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版