查看: 2946|回复: 2

[原创] 【正点原子I.MX6U-ALPHA开发板】+⑤解读RGB液晶显示

[复制链接]
  • TA的每日心情
    奋斗
    9 小时前
  • 签到天数: 2088 天

    连续签到: 170 天

    [LV.Master]伴坛终老

    发表于 2020-2-23 19:28:43 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 yinwuqing 于 2020-2-24 00:56 编辑

       新冠肺炎疫情已有所好转,各地区已复工复产,今天是周末,来与大家分享一下使用RGB液晶显示模块的应用开发。LCD液晶屏是常用到的外设,通过LCD可以显示绚丽的图形、界面等,提高人机交互的友好性。I.MX6ULL开发板上集成了一个eLCDIF接口。LCD的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。接下来谈谈关于LCD的几个常理性知识点。
        ①.分辨率   
        LCD显示器都是由一个一个的像素点组成,像素点就类似一个灯(在OLED显示器中,像素点就是一个小灯),这个小灯是RGB灯,也就是由R(红色)、G(绿色)和B(蓝色)这三种颜色组成的,而RGB就是光的三基色。像我们下载高清电影,提示选择是720p还是1080p,720p代表的是一个比例尺寸:垂直方向720个点,水平方向1280个点,等效720*1280=921600=92万像素;1080p则是垂直方向1080个点,水平方向1920个点,等效1080*1920=2073600=207万像素。因此不难看出,在LCD尺寸不变的情况下,分辨率也高越清晰。同样的,分辨率不变的情况下,LCD尺寸越小越清晰。LCD显示器的分辨率是一个很重要的参数,但是并不是分辨率越高的LCD就越好。衡量一款LCD的好坏,分辨率只是其中的一个参数,还有色彩还原程度、色彩偏离、亮度、可视角度、屏幕刷新率等其他参数。
        ②.像素格式
        一个像素点就相当于一个RGB小灯,通过控制R、G、B这三种颜色的亮度就可以显示出各种各样的色彩。那该如何控制R、G、B这三种颜色的显示亮度呢?通常一个R、G、B这三部分分别使用8bit的数据,那么一个像素点所占数据就是8bit*3=24bit,也就是说一个像素点3个字节,这种像素格式称为RGB888。如果在加入8bit的Alpha(透明)通道的话一个像素点就是32bit,也就是4个字节,这种像素格式称为ARGB8888,一个像素占用4个字节的内存,这四个字节每个位的分配如下图所示:
    ARGB8888数据格式.png
        由上图可以清晰得知道,一个像素点是4个字节,其中bit31~bit24是Alpha通道,bit23~bit16是RED通道,bit15~bit14是GREEN通道,bit7~bit0是BLUE通道。所以红色对应的值就是0X00FF0000,蓝色对应的值就是0X0000FF00,绿色对应的值为0X000000FF。通过调节R、G、B的比例可以产生其它的颜色,比如0X00FFFF00就是黄色,0X00000000就是黑色,0X00FFFFFF就是白色。
        ③.LCD屏幕接口       
       在具有显示器功能的电子产品中,显示器做为显示模块,具有多种接口,如VGA、HDMI、DP等。I.MX6ULL-ALPHA支持RGB接口的LCD,其接口的信号线如下表所示:
    RGB数据线.png
    R[7:0]、G[7:0]和B[7:0]这24根是数据线,DE、VSYNC、HSYNC和PCLK这四根是控制信号线。RGB LCD一般有两种驱动模式:DE模式和HV模式,这两个模式的区别是DE模式需要用到DE信号线,而HV模式不需要用到DE信号线,在DE模式下是可以不需要HSYNC信号线的,即使不接HSYNC信号线LCD也可以正常工作。开发板支持三款RGB LCD屏幕,型号分别为:ATK-4342(4.3寸,480*272)、ATK-7084(7寸,800*480)和ATK-7016(7寸,1024*600),其中ATK-7016型的接口原理图如下图所示:
    ATK-7016的屏幕接口原理图.png
        ④.LCD时间参数
        如果我们在LCD屏上截下一张图,显示图片则需要扫描出整个屏幕的像素点,下面以一张1024*600像素的图片加载到以1024*600的分辨率大小的屏幕上举例,图片的扫描图如下所示:
    图片扫描图.png
        一帧图像是如何被显示在屏幕上的呢?一帧图像也是由一行一行组成的。HSYNC是水平同步信号,也叫做行同步信号,当产生此信号的话就表示开始显示新的一行了。当VSYNC信号是垂直同步信号,也叫做帧同步信号,当产生此信号的话就表示开始显示新的一帧图像了。如上图所示,我们可以看到有个黑边框,真正有效的显示区域是中间的白色部分。那这黑边框又起什么作用呢?那得跟之前使用的CRT显示器说起,CRT显示器后面有个电子枪,这个电子枪就如同“画笔”,电子枪打出的电子撞击到屏幕上的荧光物质使其发光。只要控制电子枪从左到右扫打万一行(也就是扫描一行),然后从上到下扫描完所有行,这样一帧图像就显示出来了。显示一帧图像电子枪是按照‘Z’形在运动,当扫描速度很快的时候看起来就是一幅完成的画面了。当显示完一行以后会发出HSYNC信号,此时电子枪就会关闭,然后迅速的移动到屏幕的左边,当HSYNC信号结束以后就可以显示新的一行数据了,电子枪就会重新打开。在HSYNC信号结束到电子枪重新打开之间会插入一段延时,即图中的HBP部分;当显示完一行以后就会关闭电子枪等待HSYNC信号产生,关闭电子枪到HSYNC信号产生之间会插入一段延时,即图中的HFP部分。同理,当显示完一帧图像以后电子枪也会关闭,然后等到VSYNC信号产生,期间也会加入一段延时,即图中的VFP部分;VSYNC信号产生,电子枪移动到左上角,当VSYNC信号结束以后电子枪重新打开,中间也会加入一段延时,即图中的VBP部分。
        HBP、HFP、VBP和VFP就是导致上图中黑边的原因,但是这是CRT显示器存在黑边的原因,现在LCD显示器不需要电子枪了,那么为何还会有黑边呢?这是因为RGB LCD屏幕内部是有一个IC的,发送一行或者一帧数据给IC,IC是需要反应时间的。通过这段反应时间可以让IC识别到一行数据扫描完,换行了或者一帧图像扫描完了,则要开始下一帧图像显示了。因此,在LCD屏幕中继续存在HBP、HFP、VPB和VFP这四个参数的主要目的是为了锁定有效的像素数据。这四个时间是LCD重要的时间参数,在编写LCD驱动时设置。
        ⑤.RGB LCD屏幕时序
        RGB LCD的行显示时序图如下所示:
    行显示时序.png
    HSYNC:行同步信号,当此信号有效的话就表示开始显示新的一行数据。
    HSPW:有些地方也叫做thp,是HSYNC信号宽度,也就是HSYNC信号持续时间。HSYNC信号不是一个脉冲,而是需要持续一段时间才是有效的,单位为CLK。
    HBP:有些地方叫做thb,前面已经讲过了,术语叫做行同步信号后肩,单位是CLK。
    HOZVAL:有些地方叫做thd,显示一行数据所需的时间,假如屏幕分辨率为1024*600,那么HOZVAL就是1024,单位为CLK。
    HFP:有些地方叫做thf,前面已经讲过了,术语叫做行同步信号前肩,单位是CLK。
        当HSYNC信号发出以后,需要等待HSPW+HBP个CLK时间才会接收到真正有效的像素数据。当显示完一行数据以后需要等待HFP个CLK时间才能发出下一个HSYNC信号,所以显示一行所需要的时间就是:HSPW + HBP + HOZVAL + HFP。一帧图像就是由很多个行组成的,帧显示时序如下图所示:
    帧显示时序图.png
    VSYNC:帧同步信号,当此信号有效的话就表示开始显示新的一帧数据。
    VSPW:有些地方也叫做tvp,是VSYNC信号宽度,也就是VSYNC信号持续时间,单位为1行的时间。
    VBP:有些地方叫做tvb,前面已经讲过了,术语叫做帧同步信号后肩,单位为1行的时间。


    LINE:有些地方叫做tvd,显示一帧有效数据所需的时间,假如分辨率为1024*600,LINE就是600行的时间。
    VFP:有些地方叫做tvf,前面已经讲过了,术语叫做帧同步信号前肩,单位为1行的时间。
         显示一帧所需要的时间就是:VSPW+VBP+LINE+VFP个行时间,最终的计算公式:
         T = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)
         由上得知配置一款RGB LCD需要知道这几个参数:HOZVAL(屏幕有效宽度)、LINE(屏幕有效高度)、HBP、HSPW、HFP、VSPW、VBP和VFP。该开发板支持的三款RGB LCD屏幕的参数如下图所示:
    RGB LCD屏幕时间参数.png
        ⑥.像素时钟
       像素时钟就是RGB LCD的时钟信号,以ATK7016这款屏幕为例,显示一帧图像所需要的时钟数就是:
       = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)
       = (3 + 20 + 600 + 12) * (20 + 140 + 1024 + 160)
       = 635 * 1344
       = 853440
       显示一帧图像需要853440个时钟数,那么显示60帧就是:853440 * 60 = 51206400≈51.2M,所以像素时钟就是51.2MHz。
        ⑦.显存
        如果采用ARGB8888格式的话一个像素需要4个字节的内存来存放像素数据那么1024*600分辨率就需要1024*600*4=2457600B≈2.4MB内存。但是RGB LCD内部是没有内存的,所以就需要在开发板上的DDR3中分出一段内存作为RGB LCD屏幕的显存,我们如果要在屏幕上显示什么图像的话直接操作这部分显存即可。
        本次体验用到的资源有指示灯LED0,RGB LCD接口,eLCDIF等。RGB LCD接口在I.MX6ULL-ALPHA开发板底板上,原理图如下图所示:
        RGB LCD接口原理图.png
       图中三个SGM3157的目的是在未使用RGBLCD的时候将LCD_DATA7、LCD_DATA15和LCD_DATA23这三个线隔离开来,因为ALIENTEK的屏幕的LCD_R7/G7/B7着几个线用来设置LCD的ID,所以这几根线上有上拉/下拉电阻。但是I.MX6ULL的BOOT设置也用到了LCD_DATA7、LCD_DATA15和LCD_DATA23这三个引脚,所以接上屏幕以后屏幕上的ID电阻就会影响到BOOT设置,会导致代码无法运行,所以先将其隔离开来,如要使用RGB LCD屏幕,需通过LCD_DE将其连接起来。这里我们采用40P的FPC线将ATK7016屏幕和I.MX6ULL-ALPHA开发板连接起来。





    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    9 小时前
  • 签到天数: 2088 天

    连续签到: 170 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-1 14:58:09 | 显示全部楼层
        时间过得真快,阳春三月已经来临,疫情有所好转,但出行依然受限,昨天是二月的最后一天,晚上参加了正点原子举办的Linux开发经验分享直播,阿尔法开发板的视频教程原创作者左忠凯对自己的成长经历进行了详细的叙述。的确,进阶Linux系统开发是一段充满艰辛而又漫长的道路。 听讲座.png

    趋势.png
    评论.png
        虽然没能幸运中奖,但受益匪浅,正点原子视频教程更新准时,给力。脚踏实地才能走出荆棘。
        今天接着上次的RGB LCD理论知识分享讲起,结合视频讲解的示例,编写驱动LCD的部分代码如下:
    1. #ifndef _BSP_LCD_H
    2. #define _BSP_LCD_H

    3. #include "imx6ul.h"

    4. /* 颜色 */
    5. #define LCD_BLUE                  0x000000FF
    6. #define LCD_GREEN                  0x0000FF00
    7. #define LCD_RED                   0x00FF0000
    8. #define LCD_CYAN                  0x0000FFFF
    9. #define LCD_MAGENTA           0x00FF00FF
    10. #define LCD_YELLOW                  0x00FFFF00
    11. #define LCD_LIGHTBLUE          0x008080FF
    12. #define LCD_LIGHTGREEN          0x0080FF80
    13. #define LCD_LIGHTRED          0x00FF8080
    14. #define LCD_LIGHTCYAN          0x0080FFFF
    15. #define LCD_LIGHTMAGENTA  0x00FF80FF
    16. #define LCD_LIGHTYELLOW   0x00FFFF80
    17. #define LCD_DARKBLUE          0x00000080
    18. #define LCD_DARKGREEN          0x00008000
    19. #define LCD_DARKRED           0x00800000
    20. #define LCD_DARKCYAN          0x00008080
    21. #define LCD_DARKMAGENTA   0x00800080
    22. #define LCD_DARKYELLOW          0x00808000
    23. #define LCD_WHITE                  0x00FFFFFF
    24. #define LCD_LIGHTGRAY          0x00D3D3D3
    25. #define LCD_GRAY                  0x00808080
    26. #define LCD_DARKGRAY          0x00404040
    27. #define LCD_BLACK                  0x00000000
    28. #define LCD_BROWN                  0x00A52A2A
    29. #define LCD_ORANGE                  0x00FFA500
    30. #define LCD_TRANSPARENT   0x00000000

    31. /* LCD显存地址 */
    32. #define LCD_FRAMEBUF_ADDR        (0x89000000)

    33. /* LCD控制参数结构体 */
    34. struct tftlcd_typedef{
    35.         unsigned short height;                /* LCD屏幕高度 */
    36.         unsigned short width;                /* LCD屏幕宽度 */
    37.         unsigned char pixsize;                /* LCD每个像素所占字节大小 */
    38.         unsigned short vspw;
    39.         unsigned short vbpd;
    40.         unsigned short vfpd;
    41.         unsigned short hspw;
    42.         unsigned short hbpd;
    43.         unsigned short hfpd;
    44.         unsigned int framebuffer;         /* LCD显存首地址             */
    45.         unsigned int forecolor;                /* 前景色 */
    46.         unsigned int backcolor;                /* 背景色 */
    47. };
    48. extern struct tftlcd_typedef tftlcd_dev;
    49. /* 函数声明 */
    50. void lcd_init(void);
    51. void lcdgpio_init(void);
    52. void lcdclk_init(unsigned char loopDiv, unsigned char prediv, unsigned char div);
    53. void lcd_reset(void);
    54. void lcd_noreset(void);
    55. void lcd_enable(void);
    56. void video_pllinit(unsigned char loopdivi, unsigned char postdivi);

    57. inline void lcd_drawpoint(unsigned short x,unsigned short y,unsigned int color);
    58. inline unsigned int lcd_readpoint(unsigned short x,unsigned short y);
    59. void lcd_clear(unsigned int color);
    60. void lcd_fill(unsigned    short x0, unsigned short y0, unsigned short x1, unsigned short y1, unsigned int color);
    61. #endif
    复制代码
    1. #include "bsp_lcd.h"
    2. #include "bsp_gpio.h"
    3. #include "bsp_delay.h"
    4. #include "stdio.h"

    5. /* 液晶屏参数结构体 */
    6. struct tftlcd_typedef tftlcd_dev;

    7. /*
    8. * @description        : 始化LCD
    9. * @param                 : 无
    10. * @return                 : 无
    11. */
    12. void lcd_init(void)
    13. {
    14.         lcdgpio_init();                        /* 初始化IO                         */
    15.         lcdclk_init(32, 3, 5);        /* 初始化LCD时钟                 */
    16.        
    17.         lcd_reset();                        /* 复位LCD                          */
    18.         delayms(10);                        /* 延时10ms                         */
    19.         lcd_noreset();                        /* 结束复位                         */

    20.         /* TFTLCD参数结构体初始化 */
    21.         tftlcd_dev.height = 600;       
    22.         tftlcd_dev.width = 1024;
    23.         tftlcd_dev.pixsize = 4;                                /* ARGB8888模式,每个像素4字节 */
    24.         tftlcd_dev.vspw = 3;
    25.         tftlcd_dev.vbpd = 20;
    26.         tftlcd_dev.vfpd = 12;
    27.         tftlcd_dev.hspw = 20;
    28.         tftlcd_dev.hbpd = 140;
    29.         tftlcd_dev.hfpd = 160;
    30.         tftlcd_dev.framebuffer = LCD_FRAMEBUF_ADDR;       
    31.         tftlcd_dev.backcolor = LCD_WHITE;        /* 背景色为白色 */
    32.         tftlcd_dev.forecolor = LCD_BLACK;        /* 前景色为黑色 */
    33.      
    34.         /* 初始化ELCDIF的CTRL寄存器
    35.      * bit [31] 0 : 停止复位
    36.      * bit [19] 1 : 旁路计数器模式
    37.      * bit [17] 1 : LCD工作在dotclk模式
    38.      * bit [15:14] 00 : 输入数据不交换
    39.      * bit [13:12] 00 : CSC不交换
    40.      * bit [11:10] 11 : 24位总线宽度
    41.      * bit [9:8]   11 : 24位数据宽度,也就是RGB888
    42.      * bit [5]     1  : elcdif工作在主模式
    43.      * bit [1]     0  : 所有的24位均有效
    44.          */
    45.          LCDIF->CTRL |= (1 << 19) | (1 << 17) | (0 << 14) | (0 << 12) |
    46.                                          (3 << 10) | (3 << 8) | (1 << 5) | (0 << 1);
    47.         /*
    48.      * 初始化ELCDIF的寄存器CTRL1
    49.      * bit [19:16]  : 0X7 ARGB模式下,传输24位数据,A通道不用传输
    50.          */       
    51.          LCDIF->CTRL1 = 0X7 << 16;
    52.          /*
    53.       * 初始化ELCDIF的寄存器TRANSFER_COUNT寄存器
    54.       * bit [31:16]  : 高度
    55.       * bit [15:0]   : 宽度
    56.           */
    57.         LCDIF->TRANSFER_COUNT  = (tftlcd_dev.height << 16) | (tftlcd_dev.width << 0);
    58.         /*
    59.      * 初始化ELCDIF的VDCTRL0寄存器
    60.      * bit [29] 0 : VSYNC输出
    61.      * bit [28] 1 : 使能ENABLE输出
    62.      * bit [27] 0 : VSYNC低电平有效
    63.      * bit [26] 0 : HSYNC低电平有效
    64.      * bit [25] 0 : DOTCLK上升沿有效
    65.      * bit [24] 1 : ENABLE信号高电平有效
    66.      * bit [21] 1 : DOTCLK模式下设置为1
    67.      * bit [20] 1 : DOTCLK模式下设置为1
    68.      * bit [17:0] : vsw参数
    69.          */
    70.         LCDIF->VDCTRL0 = 0;        //先清零
    71.         LCDIF->VDCTRL0 = (0 << 29) | (1 << 28) | (0 << 27) |
    72.                                          (0 << 26) | (0 << 25) | (1 << 24) |
    73.                                          (1 << 21) | (1 << 20) | (tftlcd_dev.vspw << 0);
    74.         /*
    75.          * 初始化ELCDIF的VDCTRL1寄存器
    76.          * 设置VSYNC总周期
    77.          */  
    78.         LCDIF->VDCTRL1 = tftlcd_dev.height + tftlcd_dev.vspw + tftlcd_dev.vfpd + tftlcd_dev.vbpd;  //VSYNC周期
    79.          
    80.          /*
    81.           * 初始化ELCDIF的VDCTRL2寄存器
    82.           * 设置HSYNC周期
    83.           * bit[31:18] :hsw
    84.           * bit[17:0]  : HSYNC总周期
    85.           */
    86.         LCDIF->VDCTRL2 = (tftlcd_dev.hspw << 18) | (tftlcd_dev.width + tftlcd_dev.hspw + tftlcd_dev.hfpd + tftlcd_dev.hbpd);

    87.         /*
    88.          * 初始化ELCDIF的VDCTRL3寄存器
    89.          * 设置HSYNC周期
    90.          * bit[27:16] :水平等待时钟数
    91.          * bit[15:0]  : 垂直等待时钟数
    92.          */
    93.         LCDIF->VDCTRL3 = ((tftlcd_dev.hbpd + tftlcd_dev.hspw) << 16) | (tftlcd_dev.vbpd + tftlcd_dev.vspw);

    94.         /*
    95.          * 初始化ELCDIF的VDCTRL4寄存器
    96.          * 设置HSYNC周期
    97.          * bit[18] 1 : 当使用VSHYNC、HSYNC、DOTCLK的话此为置1
    98.          * bit[17:0]  : 宽度
    99.          */
    100.        
    101.         LCDIF->VDCTRL4 = (1<<18) | (tftlcd_dev.width);

    102.         /*
    103.      * 初始化ELCDIF的CUR_BUF和NEXT_BUF寄存器
    104.      * 设置当前显存地址和下一帧的显存地址
    105.          */
    106.         LCDIF->CUR_BUF = (unsigned int)tftlcd_dev.framebuffer;
    107.         LCDIF->NEXT_BUF = (unsigned int)tftlcd_dev.framebuffer;

    108.         lcd_enable();                        /* 使能LCD         */
    109.         delayms(10);
    110.         lcd_clear(LCD_WHITE);        /* 清屏                 */
    111. }

    112. /*
    113. * IO引脚:         LCD_DATA00 -> LCD_B0
    114. *                        LCD_DATA01 -> LCD_B1
    115. *                        LCD_DATA02 -> LCD_B2
    116. *                        LCD_DATA03 -> LCD_B3
    117. *                        LCD_DATA04 -> LCD_B4
    118. *                        LCD_DATA05 -> LCD_B5
    119. *                        LCD_DATA06 -> LCD_B6
    120. *                        LCD_DATA07 -> LCD_B7
    121. *
    122. *                        LCD_DATA08 -> LCD_G0
    123. *                        LCD_DATA09 -> LCD_G1
    124. *                        LCD_DATA010 -> LCD_G2
    125. *                        LCD_DATA011 -> LCD_G3
    126. *                        LCD_DATA012 -> LCD_G4
    127. *                        LCD_DATA012 -> LCD_G4
    128. *                        LCD_DATA013 -> LCD_G5
    129. *                        LCD_DATA014 -> LCD_G6
    130. *                        LCD_DATA015 -> LCD_G7
    131. *
    132. *                        LCD_DATA016 -> LCD_R0
    133. *                        LCD_DATA017 -> LCD_R1
    134. *                        LCD_DATA018 -> LCD_R2
    135. *                        LCD_DATA019 -> LCD_R3
    136. *                        LCD_DATA020 -> LCD_R4
    137. *                        LCD_DATA021 -> LCD_R5
    138. *                        LCD_DATA022 -> LCD_R6
    139. *                        LCD_DATA023 -> LCD_R7
    140. *
    141. *                        LCD_CLK -> LCD_CLK
    142. *                        LCD_VSYNC -> LCD_VSYNC
    143. *                        LCD_HSYNC -> LCD_HSYNC
    144. *                        LCD_DE -> LCD_DE
    145. *                        LCD_BL -> GPIO1_IO08
    146. */

    147. /*
    148. * @description        : LCD GPIO初始化
    149. * @param                 : 无
    150. * @return                 : 无
    151. */
    152. void lcdgpio_init(void)
    153. {
    154.         gpio_pin_config_t gpio_config;
    155.        
    156.         /* 1、IO初始化复用功能 */
    157.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA00_LCDIF_DATA00,0);
    158.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA01_LCDIF_DATA01,0);
    159.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA02_LCDIF_DATA02,0);
    160.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA03_LCDIF_DATA03,0);
    161.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA04_LCDIF_DATA04,0);
    162.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA05_LCDIF_DATA05,0);
    163.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA06_LCDIF_DATA06,0);
    164.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA07_LCDIF_DATA07,0);
    165.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA08_LCDIF_DATA08,0);
    166.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA09_LCDIF_DATA09,0);
    167.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA10_LCDIF_DATA10,0);
    168.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA11_LCDIF_DATA11,0);
    169.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA12_LCDIF_DATA12,0);
    170.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA13_LCDIF_DATA13,0);
    171.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA14_LCDIF_DATA14,0);
    172.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA15_LCDIF_DATA15,0);
    173.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA16_LCDIF_DATA16,0);
    174.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA17_LCDIF_DATA17,0);
    175.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA18_LCDIF_DATA18,0);
    176.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA19_LCDIF_DATA19,0);
    177.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA20_LCDIF_DATA20,0);
    178.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA21_LCDIF_DATA21,0);
    179.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA22_LCDIF_DATA22,0);
    180.         IOMUXC_SetPinMux(IOMUXC_LCD_DATA23_LCDIF_DATA23,0);

    181.         IOMUXC_SetPinMux(IOMUXC_LCD_CLK_LCDIF_CLK,0);       
    182.         IOMUXC_SetPinMux(IOMUXC_LCD_ENABLE_LCDIF_ENABLE,0);       
    183.         IOMUXC_SetPinMux(IOMUXC_LCD_HSYNC_LCDIF_HSYNC,0);
    184.         IOMUXC_SetPinMux(IOMUXC_LCD_VSYNC_LCDIF_VSYNC,0);

    185.         IOMUXC_SetPinMux(IOMUXC_GPIO1_IO08_GPIO1_IO08,0);                        /* 背光BL引脚      */

    186.         /* 2、配置LCD IO属性       
    187.          *bit 16:0 HYS关闭
    188.          *bit [15:14]: 0 默认22K上拉
    189.          *bit [13]: 0 pull功能
    190.          *bit [12]: 0 pull/keeper使能
    191.          *bit [11]: 0 关闭开路输出
    192.          *bit [7:6]: 10 速度100Mhz
    193.          *bit [5:3]: 111 驱动能力为R0/7
    194.          *bit [0]: 1 高转换率
    195.          */
    196.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA00_LCDIF_DATA00,0xB9);
    197.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA01_LCDIF_DATA01,0xB9);
    198.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA02_LCDIF_DATA02,0xB9);
    199.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA03_LCDIF_DATA03,0xB9);
    200.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA04_LCDIF_DATA04,0xB9);
    201.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA05_LCDIF_DATA05,0xB9);
    202.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA06_LCDIF_DATA06,0xB9);
    203.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA07_LCDIF_DATA07,0xB9);
    204.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA08_LCDIF_DATA08,0xB9);
    205.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA09_LCDIF_DATA09,0xB9);
    206.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA10_LCDIF_DATA10,0xB9);
    207.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA11_LCDIF_DATA11,0xB9);
    208.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA12_LCDIF_DATA12,0xB9);
    209.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA13_LCDIF_DATA13,0xB9);
    210.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA14_LCDIF_DATA14,0xB9);
    211.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA15_LCDIF_DATA15,0xB9);
    212.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA16_LCDIF_DATA16,0xB9);
    213.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA17_LCDIF_DATA17,0xB9);
    214.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA18_LCDIF_DATA18,0xB9);
    215.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA19_LCDIF_DATA19,0xB9);
    216.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA20_LCDIF_DATA20,0xB9);
    217.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA21_LCDIF_DATA21,0xB9);
    218.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA22_LCDIF_DATA22,0xB9);
    219.         IOMUXC_SetPinConfig(IOMUXC_LCD_DATA23_LCDIF_DATA23,0xB9);

    220.         IOMUXC_SetPinConfig(IOMUXC_LCD_CLK_LCDIF_CLK,0xB9);
    221.         IOMUXC_SetPinConfig(IOMUXC_LCD_ENABLE_LCDIF_ENABLE,0xB9);
    222.         IOMUXC_SetPinConfig(IOMUXC_LCD_HSYNC_LCDIF_HSYNC,0xB9);
    223.         IOMUXC_SetPinConfig(IOMUXC_LCD_VSYNC_LCDIF_VSYNC,0xB9);

    224.         IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO08_GPIO1_IO08,0xB9);        /* 背光BL引脚                 */

    225.         /* GPIO初始化 */
    226.         gpio_config.direction = kGPIO_DigitalOutput;                        /* 输出                         */
    227.         gpio_config.outputLogic = 1;                                                         /* 默认关闭背光 */
    228.         gpio_init(GPIO1, 8, &gpio_config);                                                /* 背光默认打开 */
    229.         gpio_pinwrite(GPIO1, 8, 1);                                                                /* 打开背光     */
    230. }

    231. /*
    232. * @description                : LCD时钟初始化, LCD时钟计算公式如下:
    233. *                          LCD CLK = 24 * loopDiv / prediv / div
    234. * @param -        loopDiv        : loopDivider值
    235. * @param -        loopDiv : lcdifprediv值
    236. * @param -        div                : lcdifdiv值
    237. * @return                         : 无
    238. */
    239. void lcdclk_init(unsigned char loopDiv, unsigned char prediv, unsigned char div)
    240. {
    241.         /* 先初始化video pll
    242.      * VIDEO PLL = OSC24M * (loopDivider + (denominator / numerator)) / postDivider
    243.          *不使用小数分频器,因此denominator和numerator设置为0
    244.          */
    245.         CCM_ANALOG->PLL_VIDEO_NUM = 0;                /* 不使用小数分频器 */
    246.         CCM_ANALOG->PLL_VIDEO_DENOM = 0;       

    247.         /*
    248.      * PLL_VIDEO寄存器设置
    249.      * bit[13]:    1   使能VIDEO PLL时钟
    250.      * bit[20:19]  2  设置postDivider为1分频
    251.      * bit[6:0] : 32  设置loopDivider寄存器
    252.          */
    253.         CCM_ANALOG->PLL_VIDEO =  (2 << 19) | (1 << 13) | (loopDiv << 0);

    254.         /*
    255.      * MISC2寄存器设置
    256.      * bit[31:30]: 0  VIDEO的post-div设置,时钟源来源于postDivider,1分频
    257.          */
    258.         CCM_ANALOG->MISC2 &= ~(3 << 30);
    259.         CCM_ANALOG->MISC2 = 0 << 30;

    260.         /* LCD时钟源来源与PLL5,也就是VIDEO           PLL  */
    261.         CCM->CSCDR2 &= ~(7 << 15);         
    262.         CCM->CSCDR2 |= (2 << 15);           /* 设置LCDIF_PRE_CLK使用PLL5 */

    263.         /* 设置LCDIF_PRE分频 */
    264.         CCM->CSCDR2 &= ~(7 << 12);               
    265.         CCM->CSCDR2 |= (prediv - 1) << 12;  /* 设置分频  */

    266.         /* 设置LCDIF分频 */
    267.         CCM->CBCMR &= ~(7 << 23);                                       
    268.         CCM->CBCMR |= (div - 1) << 23;                               

    269.         /* 设置LCD时钟源为LCDIF_PRE时钟 */
    270.         CCM->CSCDR2 &= ~(7 << 9);       /* 清除原来的设置                         */
    271.         CCM->CSCDR2 |= (0 << 9);        /* LCDIF_PRE时钟源选择LCDIF_PRE时钟 */
    272. }

    273. /*
    274. * @description        : 复位ELCDIF接口
    275. * @param                 : 无
    276. * @return                 : 无
    277. */
    278. void lcd_reset(void)
    279. {
    280.         LCDIF->CTRL  = 1<<31; /* 强制复位 */
    281. }

    282. /*
    283. * @description        : 结束复位ELCDIF接口
    284. * @param                 : 无
    285. * @return                 : 无
    286. */
    287. void lcd_noreset(void)
    288. {
    289.         LCDIF->CTRL  = 0<<31; /* 取消强制复位 */
    290. }

    291. /*
    292. * @description        : 使能ELCDIF接口
    293. * @param                 : 无
    294. * @return                 : 无
    295. */
    296. void lcd_enable(void)
    297. {
    298.         LCDIF->CTRL |= 1<<0; /* 使能ELCDIF */
    299. }

    300. /*
    301. * @description                : 画点函数
    302. * @param - x                : x轴坐标
    303. * @param - y                : y轴坐标
    304. * @param - color        : 颜色值
    305. * @return                         : 无
    306. */
    307. inline void lcd_drawpoint(unsigned short x,unsigned short y,unsigned int color)
    308. {
    309.           *(unsigned int*)((unsigned int)tftlcd_dev.framebuffer +
    310.                              tftlcd_dev.pixsize * (tftlcd_dev.width * y+x))=color;
    311. }
    312. /*
    313. * @description                : 读取指定点的颜色值
    314. * @param - x                : x轴坐标
    315. * @param - y                : y轴坐标
    316. * @return                         : 读取到的指定点的颜色值
    317. */
    318. inline unsigned int lcd_readpoint(unsigned short x,unsigned short y)
    319. {
    320.         return *(unsigned int*)((unsigned int)tftlcd_dev.framebuffer +
    321.                    tftlcd_dev.pixsize * (tftlcd_dev.width * y + x));
    322. }

    323. /*
    324. * @description                : 清屏
    325. * @param - color        : 颜色值
    326. * @return                         : 读取到的指定点的颜色值
    327. */
    328. void lcd_clear(unsigned int color)
    329. {
    330.         unsigned int num;
    331.         unsigned int i = 0;
    332.         unsigned int *startaddr=(unsigned int*)tftlcd_dev.framebuffer;        //指向帧缓存首地址
    333.         num=(unsigned int)tftlcd_dev.width * tftlcd_dev.height;                        //缓冲区总长度
    334.         for(i = 0; i < num; i++)
    335.         {
    336.                 startaddr[i] = color;
    337.         }               
    338. }

    339. /*
    340. * @description                : 以指定的颜色填充一块矩形
    341. * @param - x0                : 矩形起始点坐标X轴
    342. * @param - y0                : 矩形起始点坐标Y轴
    343. * @param - x1                : 矩形终止点坐标X轴
    344. * @param - y1                : 矩形终止点坐标Y轴
    345. * @param - color        : 要填充的颜色
    346. * @return                         : 读取到的指定点的颜色值
    347. */
    348. void lcd_fill(unsigned    short x0, unsigned short y0,
    349.                  unsigned short x1, unsigned short y1, unsigned int color)
    350. {
    351.     unsigned short x, y;

    352.         if(x0 < 0) x0 = 0;
    353.         if(y0 < 0) y0 = 0;
    354.         if(x1 >= tftlcd_dev.width) x1 = tftlcd_dev.width - 1;
    355.         if(y1 >= tftlcd_dev.height) y1 = tftlcd_dev.height - 1;
    356.        
    357.     for(y = y0; y <= y1; y++)
    358.     {
    359.         for(x = x0; x <= x1; x++)
    360.                         lcd_drawpoint(x, y, color);
    361.     }
    362. }
    复制代码
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    9 小时前
  • 签到天数: 2088 天

    连续签到: 170 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-3-1 16:16:34 | 显示全部楼层
    接上LCD底层驱动API函数如下:
    1. #include "bsp_lcdapi.h"
    2. #include "font.h"

    3. /*
    4. * @description                : 画线函数
    5. * @param - x1                : 线起始点坐标X轴
    6. * @param - y1                : 线起始点坐标Y轴
    7. * @param - x2                : 线终止点坐标X轴
    8. * @param - y2                : 线终止点坐标Y轴
    9. * @return                         : 无
    10. */
    11. void lcd_drawline(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2)
    12. {
    13.         u16 t;
    14.         int xerr = 0, yerr = 0, delta_x, delta_y, distance;
    15.         int incx, incy, uRow, uCol;
    16.         delta_x = x2 - x1;                                         /* 计算坐标增量 */
    17.         delta_y = y2 - y1;
    18.         uRow = x1;
    19.         uCol = y1;
    20.         if(delta_x > 0)                                         /* 设置单步方向 */
    21.                 incx = 1;
    22.         else if(delta_x==0)                                        /* 垂直线 */
    23.                 incx = 0;               
    24.         else
    25.         {
    26.                 incx = -1;
    27.                 delta_x = -delta_x;
    28.         }
    29.         if(delta_y>0)
    30.                 incy=1;
    31.         else if(delta_y == 0)    /* 水平线 */
    32.                 incy=0;
    33.         else
    34.         {
    35.                 incy = -1;
    36.                 delta_y = -delta_y;
    37.         }
    38.         if( delta_x > delta_y)   /*选取基本增量坐标轴  */
    39.                 distance = delta_x;
    40.         else
    41.                 distance = delta_y;
    42.         for(t = 0; t <= distance+1; t++ )        /* 画线输出 */
    43.         {
    44.                 lcd_drawpoint(uRow, uCol, tftlcd_dev.forecolor);  /* 画点 */
    45.                 xerr += delta_x ;
    46.                 yerr += delta_y ;
    47.                 if(xerr > distance)
    48.                 {
    49.                         xerr -= distance;
    50.                         uRow += incx;
    51.                 }
    52.                 if(yerr > distance)
    53.                 {
    54.                         yerr -= distance;
    55.                         uCol += incy;
    56.                 }
    57.         }  
    58. }   

    59. /*
    60. * @description        : 画矩形函数
    61. * @param - x1        : 矩形左上角坐标X轴
    62. * @param - y1        : 矩形左上角坐标Y轴
    63. * @param - x2        : 矩形右下角坐标X轴
    64. * @param - y2        : 矩形右下角坐标Y轴
    65. * @return                 : 无
    66. */
    67. void lcd_draw_rectangle(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2)
    68. {
    69.         lcd_drawline(x1, y1, x2, y1);
    70.         lcd_drawline(x1, y1, x1, y2);
    71.         lcd_drawline(x1, y2, x2, y2);
    72.         lcd_drawline(x2, y1, x2, y2);
    73. }

    74. /*
    75. * @description        : 在指定位置画一个指定大小的圆
    76. * @param - x0        : 圆心坐标X轴
    77. * @param - y0        : 圆心坐标Y轴
    78. * @param - y2        : 圆形半径
    79. * @return                 : 无
    80. */
    81. void lcd_draw_Circle(unsigned short x0,unsigned short y0,unsigned char r)
    82. {
    83.     int mx = x0, my = y0;
    84.     int x = 0, y = r;

    85.     int d = 1 - r;   
    86.     while(y > x)            /* y>x即第一象限的第1区八分圆 */
    87.     {
    88.         lcd_drawpoint(x  + mx, y  + my, tftlcd_dev.forecolor);
    89.         lcd_drawpoint(y  + mx, x  + my, tftlcd_dev.forecolor);
    90.         lcd_drawpoint(-x + mx, y  + my, tftlcd_dev.forecolor);
    91.         lcd_drawpoint(-y + mx, x  + my, tftlcd_dev.forecolor);

    92.         lcd_drawpoint(-x + mx, -y + my, tftlcd_dev.forecolor);
    93.         lcd_drawpoint(-y + mx, -x + my, tftlcd_dev.forecolor);
    94.         lcd_drawpoint(x  + mx, -y + my, tftlcd_dev.forecolor);
    95.         lcd_drawpoint(y  + mx, -x + my, tftlcd_dev.forecolor);
    96.         if( d < 0)
    97.         {
    98.             d = d + 2 * x + 3;
    99.         }
    100.         else
    101.         {
    102.             d= d + 2 * (x - y) + 5;
    103.             y--;
    104.         }
    105.         x++;
    106.     }
    107. }

    108. /*
    109. * @description        : 在指定位置显示一个字符
    110. * @param - x        : 起始坐标X轴
    111. * @param - y        : 起始坐标Y轴
    112. * @param - num        : 显示字符
    113. * @param - size: 字体大小, 可选12/16/24/32
    114. * @param - mode: 叠加方式(1)还是非叠加方式(0)
    115. * @return                 : 无
    116. */
    117. void lcd_showchar(unsigned     short x, unsigned short y,
    118.                                       unsigned char num, unsigned char size,
    119.                                       unsigned char mode)
    120. {                                                            
    121.     unsigned char  temp, t1, t;
    122.         unsigned short y0 = y;
    123.         unsigned char csize = (size / 8+ ((size % 8) ? 1 : 0)) * (size / 2);        /* 得到字体一个字符对应点阵集所占的字节数         */       
    124.         num = num - ' ';          /*得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)  */
    125.         for(t = 0; t < csize; t++)
    126.         {   
    127.                 if(size == 12) temp = asc2_1206[num][t];                 /* 调用1206字体 */
    128.                 else if(size == 16)temp = asc2_1608[num][t];        /* 调用1608字体 */
    129.                 else if(size == 24)temp = asc2_2412[num][t];        /* 调用2412字体 */
    130.                 else if(size == 32)temp = asc2_3216[num][t];        /* 调用3216字体 */
    131.                 else return;                                                                        /* 没有的字库                 */
    132.                 for(t1 = 0; t1 < 8; t1++)
    133.                 {                            
    134.                         if(temp & 0x80)lcd_drawpoint(x, y, tftlcd_dev.forecolor);
    135.                         else if(mode==0)lcd_drawpoint(x, y, tftlcd_dev.backcolor);
    136.                         temp <<= 1;
    137.                         y++;
    138.                         if(y >= tftlcd_dev.height) return;                        /* 超区域了 */       
    139.                         if((y - y0) == size)
    140.                         {
    141.                                 y = y0;
    142.                                 x++;
    143.                                 if(x >= tftlcd_dev.width) return;                /* 超区域了 */
    144.                                 break;
    145.                         }
    146.                 }           
    147.         }                                                    
    148. }

    149. /*
    150. * @description        : 计算m的n次方
    151. * @param - m        : 要计算的值
    152. * @param - n        : n次方
    153. * @return                 : m^n次方.
    154. */
    155. unsigned int lcd_pow(unsigned char m,unsigned char n)
    156. {
    157.         unsigned int result = 1;         
    158.         while(n--) result *= m;   
    159.         return result;
    160. }

    161. /*
    162. * @description        : 显示指定的数字,高位为0则不显示
    163. * @param - x        : 起始坐标点X轴。
    164. * @param - y        : 起始坐标点Y轴。
    165. * @param - num        : 数值(0~999999999)。
    166. * @param - len : 数字位数。
    167. * @param - size: 字体大小
    168. * @return                 : 无
    169. */
    170. void lcd_shownum(unsigned     short x,
    171.                                          unsigned short y,
    172.                                          unsigned int num,
    173.                                          unsigned char len,
    174.                                          unsigned char size)
    175. {                
    176.         unsigned char  t, temp;
    177.         unsigned char  enshow = 0;                                                  
    178.         for(t = 0; t < len; t++)
    179.         {
    180.                 temp = (num / lcd_pow(10, len - t - 1)) % 10;
    181.                 if(enshow == 0 && t < (len - 1))
    182.                 {
    183.                         if(temp == 0)
    184.                         {
    185.                                 lcd_showchar(x + (size / 2) * t, y, ' ', size, 0);
    186.                                 continue;
    187.                         }else enshow = 1;          
    188.                 }
    189.                  lcd_showchar(x + (size / 2) * t, y, temp + '0', size, 0);
    190.         }
    191. }

    192. /*
    193. * @description                : 显示指定的数字,高位为0,还是显示
    194. * @param - x                 : 起始坐标点X轴。
    195. * @param - y                 : 起始坐标点Y轴。
    196. * @param - num                : 数值(0~999999999)。
    197. * @param - len         : 数字位数。
    198. * @param - size        : 字体大小
    199. * @param - mode        : [7]:0,不填充;1,填充0.
    200. *                                           [6:1]:保留
    201. *                                          [0]:0,非叠加显示;1,叠加显示.
    202. * @return                          : 无
    203. */
    204. void lcd_showxnum(unsigned     short x, unsigned short y,
    205.                                           unsigned int num, unsigned char len,
    206.                                           unsigned char size, unsigned char mode)
    207. {  
    208.         unsigned char t, temp;
    209.         unsigned char enshow = 0;                                                  
    210.         for(t = 0; t < len; t++)
    211.         {
    212.                 temp = (num / lcd_pow(10, len - t- 1)) % 10;
    213.                 if(enshow == 0 && t < (len - 1))
    214.                 {
    215.                         if(temp == 0)
    216.                         {
    217.                                 if(mode & 0X80) lcd_showchar(x + (size / 2) * t, y, '0', size, mode & 0X01);  
    218.                                 else  lcd_showchar(x + (size / 2) * t, y , ' ', size, mode & 0X01);  
    219.                                 continue;
    220.                         }else enshow=1;
    221.                 }
    222.                  lcd_showchar( x + (size / 2) * t, y, temp + '0' , size , mode & 0X01);
    223.         }
    224. }

    225. /*
    226. * @description                : 显示一串字符串
    227. * @param - x                : 起始坐标点X轴。
    228. * @param - y                : 起始坐标点Y轴。
    229. * @param - width         : 字符串显示区域长度
    230. * @param - height        : 字符串显示区域高度
    231. * @param - size        : 字体大小
    232. * @param - p                : 要显示的字符串首地址
    233. * @return                         : 无
    234. */
    235. void lcd_show_string(unsigned short x,unsigned short y,
    236.                                                   unsigned short width,unsigned short height,
    237.                                                   unsigned char size,char *p)
    238. {         
    239.         unsigned char x0 = x;
    240.         width += x;
    241.         height += y;
    242.     while((*p <= '~') &&(*p >= ' '))                /* 判断是不是非法字符! */
    243.     {      
    244.         if(x >= width) {x = x0; y += size;}
    245.         if(y >= height) break;                                /* 退出 */
    246.         lcd_showchar(x, y, *p , size, 0);
    247.         x += size / 2;
    248.         p++;
    249.     }  
    250. }
    复制代码
    1. #ifndef BSP_LCDAPI_H
    2. #define BSP_LCDAPI_H

    3. #include "imx6ul.h"
    4. #include "bsp_lcd.h"

    5. /* 函数声明 */
    6. void lcd_drawline(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2);
    7. void lcd_draw_rectangle(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2);
    8. void lcd_draw_Circle(unsigned short x0,unsigned short y0,unsigned char r);
    9. void lcd_showchar(unsigned     short x,unsigned short y,unsigned char num,unsigned char size, unsigned char mode);
    10. unsigned int lcd_pow(unsigned char m,unsigned char n);
    11. void lcd_shownum(unsigned short x, unsigned short y, unsigned int num, unsigned char len,unsigned char size);
    12. void lcd_showxnum(unsigned short x, unsigned short y, unsigned int num, unsigned char len, unsigned char size, unsigned char mode);
    13. void lcd_show_string(unsigned short x,unsigned short y,
    14. unsigned short width, unsigned short height, unsigned char size,char *p);
    15. #endif
    复制代码
    1. #include "bsp_clk.h"
    2. #include "bsp_delay.h"
    3. #include "bsp_led.h"
    4. #include "bsp_beep.h"
    5. #include "bsp_key.h"
    6. #include "bsp_int.h"
    7. #include "bsp_uart.h"
    8. #include "stdio.h"
    9. #include "bsp_lcd.h"
    10. #include "bsp_lcdapi.h"

    11. /* 背景颜色索引 */
    12. unsigned int backcolor[10] = {
    13.         LCD_BLUE,                 LCD_GREEN,                 LCD_RED,         LCD_CYAN,         LCD_YELLOW,
    14.         LCD_LIGHTBLUE,         LCD_DARKBLUE,         LCD_WHITE,         LCD_BLACK,         LCD_ORANGE
    15. };

    16. /*
    17. * @description        : main函数
    18. * @param                 : 无
    19. * @return                 : 无
    20. */
    21. int main(void)
    22. {
    23.         unsigned char index = 0;
    24.         unsigned char state = OFF;
    25.         int_init();                                 /* 初始化中断(一定要最先调用!) */
    26.         imx6u_clkinit();                        /* 初始化系统时钟                         */
    27.         delay_init();                                /* 初始化延时                         */
    28.         clk_enable();                                /* 使能所有的时钟                         */
    29.         led_init();                                        /* 初始化led                         */
    30.         beep_init();                                /* 初始化beep                         */
    31.         uart_init();                                /* 初始化串口,波特率115200 */
    32.         lcd_init();                                        /* 初始化LCD                         */

    33.         tftlcd_dev.forecolor = LCD_RED;          
    34.         lcd_show_string(10,10,400,32,32,(char*)"WELCOME TEST IMX6ULL LCD");  /* 显示字符串 */
    35.         lcd_draw_rectangle(10, 52, 790, 290);        /* 绘制矩形框                  */
    36.         lcd_drawline(10, 52,790, 290);                        /* 绘制线条                          */
    37.         lcd_drawline(10, 290,790, 52);                        /* 绘制线条                 */
    38.         lcd_draw_Circle(400, 171, 119);                        /* 绘制圆形                 */
    39.         lcd_draw_Circle(400, 171, 99);                        /* 绘制圆形                 */
    40.         lcd_draw_Circle(400, 171, 79);                        /* 绘制圆形                 */
    41.         lcd_draw_Circle(400, 171, 59);                        /* 绘制圆形                 */
    42.         lcd_draw_Circle(400, 171, 39);                        /* 绘制圆形                 */

    43.         while(1)                               
    44.         {       
    45.                 index++;
    46.                 if(index == 10)
    47.                         index = 0;

    48.                 lcd_fill(10, 300, 790, 470, backcolor[index]);
    49.                 lcd_show_string(610,10,240,32,32,(char*)"INDEX=");  /*显示字符串                    */
    50.                 lcd_shownum(700,10, index, 2, 32);                                         /* 显示数字,叠加显示        */

    51.                 state = !state;
    52.                 led_switch(LED0,state);
    53.                 delayms(1000);        /* 延时一秒        */
    54.         }
    55.         return 0;
    56. }
    复制代码
         根据上面的编写代码,编译链接ok,完成下载。
    编译ok.png
         最后奉上此次实现驱动LCD的现象结果:
          驱动LCD结果演示.gif
         屏驱动视频演示
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2024-4-25 18:41 , Processed in 0.131316 second(s), 19 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.