STM32 RTT LCD

本文详细介绍了SSD1963显示控制器的LCD驱动原理与实践过程,包括硬件连接、初始化配置以及如何利用RTGUI进行图形用户界面的基础绘制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载于http://blog.youkuaiyun.com/mostone/article/details/9318589


1、  补注

a)      硬件,打通通讯通道

若学习者购买了学习板,通常可以在学习板提供的示例代码中找到LCD的相关驱动代码,基本上,这里的驱动的所有代码都可以从里面找到。

从上面的示意图可见,MCU要在LCD上显示内容,需要经过:

1、  Core

2、  Dbus,SystemBus

3、  Bus Matrix

4、  FSMC

5、  SSD1963

6、  LCM

 

驱动LCD,就要相应地将这些通道开启,初始化,只要其中一个环节未打通,就不可能成功点亮LCD屏。

 

首先是到SSD1963的引脚,虽然说,MCU与SSD1963显示芯片的连接是通过FSMC方式,但由于FSMC与GPIO是共用引脚的,因此,需要先打开相应的GPIO。

代码:

[cpp]  view plain copy
  1. void GPIO_INIT(void)  
  2. {  
  3.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC  
  4.                         | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOF , ENABLE);  
  5. }  

作为新手,我就因为没打开GPIO,这么一句代码的问题,查了一个月才找到,杯具得不能再杯具了……

 

其次,就是FSMC了,这部分的代码,可以直接从学习板的示例代码中复制出来。

 

然后,是SSD1963显示芯片的初始化代码,也可以直接从学习板的示例代码中复制。

SSD1963,具体的信息可以查看学习板中带的PDF文件,以下是部分摘录:

1  GENERAL DESCRIPTION

 

SSD1963 is a display controller of 1215K byte frame buffer to support up to 864 x 480 x 24bit graphics

content.  It also equips parallel MCU interfaces in different bus width to receive graphics data and command

from MCU.  Its display interface supports common RA M-less LCD driver of color depth up to 24 bit-per-pixel.

 

2  FEATURES

 

•  Display feature

−  Built-in 1215K bytes frame buffer.  Support up to 864 x 480 at 24bpp display

−  Support TFT 18/24-bit generic RGB interface panel

−  Support 8-bit serial RGB interface

−  Hardware rotation of 0, 90, 180, 270 degree

−  Hardware display mirroring

−  Hardware windowing

−  Programmable brightness, contrast and saturation control

−  Dynamic Backlight Control (DBC) via PWM signal

•  MCU connectivity

−  8/9/16/18/24-bit MCU interface

−  Tearing effect signal

•  I/O Connectivity

−  4 GPIO pins

•  Built-in clock generator

•  Deep sleep mode for power saving

•  Core supply power (VDDPLL and VDDD): 1.2V±0.1V

•  I/O supply power(VDDIO): 1.65V to 3.6V

•  LCD interface supply power (VDDLCD): 1.65V to 3.6V 

可以看到,这款芯片内建1215K字节帧缓存,最大支持分辨率864x 480,真24位彩色的LCD屏

如果要提高显示效果,可考虑使用帧缓存(framebuffer)。RTGUI支持帧缓存,以后有时间,再更新驱动。

 

为了显示LCD屏上的每一个像素点,SSD1963提供了很多命令,如:

设置作图坐标,我们会使用 0x2A,0x2B来确定一个矩形区域。

然后开始写入数据之前,调用0x2C来通知SSD1963。同样,可以发送命令0x2E来通知SSD1963,将当前点的像素颜色值放到数据总线上,MCU随后就可以通过FSMC来读取。

 

其它更多内容,请查看PDF文件。

 

奋斗板V3的4.3” LCD屏,用的是翰彩4.3” ColorTFT-LCD Module,在相关资料文件夹中,也有相应的PDF文档。硬件连接只要按文档说明正确对应即可。

LCM型号(Model)是 HSD043I9W1-A**

 

完成以上,整个通讯通道就被打通,LCD屏才能成功点亮。

b)      GUI基础函数

RTGUI与UCGUI,其底层的绘图函数都只有很少的几个,复杂图形及文字等显示操作,都在这些功能简单的函数基础上进行的扩展。

RTGUI的五个基本绘图函数(未使用frame buffer的情况下):

[cpp]  view plain copy
  1. /** 
  2.  * graphic operations 
  3.  */  
  4. struct rt_device_graphic_ops  
  5. {  
  6.     void (*set_pixel) (const char *pixel, int x, int y);  
  7.     void (*get_pixel) (char *pixel, int x, int y);  
  8.    
  9.     void (*draw_hline)(const char *pixel, int x1, int x2, int y);  
  10.     void (*draw_vline)(const char *pixel, int x, int y1, int y2);  
  11.    
  12.     void (*blit_line) (const char *pixel, int x, int y, rt_size_t size);  
  13. };  

分别是:

  • l  画一个点
  • l  取一个点的色彩值
  • l  画一条水平线
  • l  画一条垂直线
  • l  画一条水平线,水平线上每个点的色彩值在“数组”中指定

 

在RTGUI中,把显示驱动作为一个设备来注册。以上五个函数则保存到通用设备的私有数据段。再将显示设备注册为“lcd”。

其中基类rt_devicer的control方法,我们返回了一些信息,如屏幕大小,色彩格式定义等。而其它几个方法其实都是空方法,因为LCD驱动不提供这些功能。

如下:

[cpp]  view plain copy
  1. void rt_hw_lcd_init(void)  
  2. {  
  3.    
  4.     /* register lcd device */  
  5.     _lcd_device.type  = RT_Device_Class_Graphic;  
  6.     _lcd_device.init  = lcd_init;  
  7.     _lcd_device.open  = lcd_open;  
  8.     _lcd_device.close = lcd_close;  
  9.     _lcd_device.control = lcd_control;  
  10.     _lcd_device.read  = RT_NULL;  
  11.     _lcd_device.write = RT_NULL;  
  12.    
  13.     _lcd_device.user_data = &ssd1963_ops;  
  14.     GPIO_INIT();  
  15.     FSMC_LCD_Init();  
  16.     LCD_INIT();  
  17.     lcd_clear();  
  18.    
  19.     /* register graphic device driver */  
  20.     rt_device_register(&_lcd_device, "lcd",  
  21.         RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);  
  22. }  

在application.c中,RTGUI取得设备“lcd”,并将它转化为rtgui_graphic_driver类,如下:

[cpp]  view plain copy
  1. …………  
  2. #ifdef RT_USING_RTGUI  
  3.     {  
  4.         extern void rtgui_system_server_init(void);  
  5.         extern void rt_hw_lcd_init();  
  6.         extern void rtgui_touch_hw_init(void);  
  7.    
  8.         rt_device_t lcd;  
  9.    
  10.         /* init lcd */  
  11.         rt_hw_lcd_init();  
  12.    
  13.         /* init touch panel */  
  14.         rtgui_touch_hw_init();  
  15.    
  16.         /* re-init device driver */  
  17.         rt_device_init_all();  
  18.    
  19.         /* find lcd device */  
  20.         lcd = rt_device_find("lcd");  
  21.    
  22.         /* set lcd device as rtgui graphic driver */  
  23.        <strong> rtgui_graphic_set_device(lcd);</strong>  
  24.    
  25.         /* init rtgui system server */  
  26.         rtgui_system_server_init();  
  27.     }  
  28. #endif /* #ifdef RT_USING_RTGUI */  
  29. }  
  30.    
  31. int rt_application_init()  
  32. {  
  33. …………  


 

[cpp]  view plain copy
  1. /* 
  2.  * File      : driver.h 
  3.  * This file is part of RTGUI in RT-Thread RTOS 
  4.  * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team 
  5.  * 
  6.  * The license and distribution terms for this file may be 
  7.  * found in the file LICENSE in this distribution or at 
  8.  * http://www.rt-thread.org/license/LICENSE 
  9.  * 
  10.  * Change Logs: 
  11.  * Date           Author       Notes 
  12.  * 2009-10-04     Bernard      first version 
  13.  */  
  14. #ifndef __RTGUI_DRIVER_H__  
  15. #define __RTGUI_DRIVER_H__  
  16.    
  17. #include <rtgui/list.h>  
  18. #include <rtgui/color.h>  
  19.    
  20. <strong>struct rtgui_graphic_driver_ops</strong>  
  21. {  
  22.     /* set and get pixel in (x, y) */  
  23.     void (*set_pixel)(rtgui_color_t *c, int x, int y);  
  24.     void (*get_pixel)(rtgui_color_t *c, int x, int y);  
  25.    
  26.     void (*draw_hline)(rtgui_color_t *c, int x1, int x2, int y);  
  27.     void (*draw_vline)(rtgui_color_t *c, int x , int y1, int y2);  
  28.    
  29.     /* draw raw hline */  
  30.     void (*<strong>draw_raw_hline</strong>)(rt_uint8_t *pixels, int x1, int x2, int y);  
  31. };  
  32.    
  33. <strong>struct rtgui_graphic_driver</strong>  
  34. {  
  35.     /* pixel format and byte per pixel */  
  36.     rt_uint8_t pixel_format;  
  37.     rt_uint8_t bits_per_pixel;  
  38.     rt_uint16_t pitch;  
  39.    
  40.     /* screen width and height */  
  41.     rt_uint16_t width;  
  42.     rt_uint16_t height;  
  43.    
  44.     /* framebuffer address and ops */  
  45.     volatile rt_uint8_t *framebuffer;  
  46.     rt_device_t device;  
  47.     <strong>const struct rtgui_graphic_driver_ops *ops;</strong>  
  48. };  
  49. ………………  
  50. ………………  
  51. ………………  


[cpp]  view plain copy
  1. /* 
  2.  * File      : driver.c 
  3.  * This file is part of RTGUI in RT-Thread RTOS 
  4.  * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team 
  5.  * 
  6.  * The license and distribution terms for this file may be 
  7.  * found in the file LICENSE in this distribution or at 
  8.  * http://www.rt-thread.org/license/LICENSE 
  9.  * 
  10.  * Change Logs: 
  11.  * Date           Author       Notes 
  12.  * 2009-10-04     Bernard      first version 
  13.  */  
  14. #include <rtthread.h>  
  15. #include <rtgui/driver.h>  
  16.    
  17. struct rtgui_graphic_driver _driver;  
  18.    
  19. ………………  
  20. ………………  
  21. ………………  
  22. rt_err_t rtgui_graphic_set_device(rt_device_t device)  
  23. {  
  24.     rt_err_t result;  
  25.     struct rt_device_graphic_info info;  
  26.    
  27.     /* get framebuffer address */  
  28.     result = rt_device_control(device, RTGRAPHIC_CTRL_GET_INFO, &info);  
  29.     if (result != RT_EOK)  
  30.     {  
  31.         /* get device information failed */  
  32.         return -RT_ERROR;  
  33.     }  
  34.    
  35.     /* initialize framebuffer driver */  
  36.     _driver.device = device;  
  37.     _driver.pixel_format = info.pixel_format;  
  38.     _driver.bits_per_pixel = info.bits_per_pixel;  
  39.     _driver.width = info.width;  
  40.     _driver.height = info.height;  
  41.     _driver.pitch = _driver.width * _driver.bits_per_pixel / 8;  
  42.     _driver.framebuffer = info.framebuffer;  
  43.    
  44.     if (info.framebuffer != RT_NULL)  
  45.     {  
  46.         /* is a frame buffer device */  
  47.         _driver.ops = rtgui_framebuffer_get_ops(_driver.pixel_format);  
  48.     }  
  49.     else  
  50.     {  
  51.         /* is a pixel device */  
  52.         <strong>_driver.ops = rtgui_pixel_device_get_ops(_driver.pixel_format);</strong>  
  53.     }  
  54.    
  55.     return RT_EOK;  
  56. }  
  57. ………………  
  58. ………………  
  59. ………………  

其它代码就不列出来了,最终实现的是GUI色彩定义与硬件的色彩定义分隔,在RTGUI中统一一种方式定义色彩,而不用关心具体LCD硬件对色彩的定义。不过,对于函数 draw_raw_hline() 来说,需要手工转换色彩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值