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。

代码:

void GPIO_INIT(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
| RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOF , ENABLE);
}

作为新手,我就因为没打开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的情况下):

/**
* graphic operations
*/
struct rt_device_graphic_ops
{
void (*set_pixel) (const char *pixel, int x, int y);
void (*get_pixel) (char *pixel, int x, int y); void (*draw_hline)(const char *pixel, int x1, int x2, int y);
void (*draw_vline)(const char *pixel, int x, int y1, int y2); void (*blit_line) (const char *pixel, int x, int y, rt_size_t size);
};

分别是:

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

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

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

如下:

void rt_hw_lcd_init(void)
{ /* register lcd device */
_lcd_device.type = RT_Device_Class_Graphic;
_lcd_device.init = lcd_init;
_lcd_device.open = lcd_open;
_lcd_device.close = lcd_close;
_lcd_device.control = lcd_control;
_lcd_device.read = RT_NULL;
_lcd_device.write = RT_NULL; _lcd_device.user_data = &ssd1963_ops;
GPIO_INIT();
FSMC_LCD_Init();
LCD_INIT();
lcd_clear(); /* register graphic device driver */
rt_device_register(&_lcd_device, "lcd",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
}

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

…………
#ifdef RT_USING_RTGUI
{
extern void rtgui_system_server_init(void);
extern void rt_hw_lcd_init();
extern void rtgui_touch_hw_init(void); rt_device_t lcd; /* init lcd */
rt_hw_lcd_init(); /* init touch panel */
rtgui_touch_hw_init(); /* re-init device driver */
rt_device_init_all(); /* find lcd device */
lcd = rt_device_find("lcd"); /* set lcd device as rtgui graphic driver */
rtgui_graphic_set_device(lcd); /* init rtgui system server */
rtgui_system_server_init();
}
#endif /* #ifdef RT_USING_RTGUI */
} int rt_application_init()
{
…………
/*
* File : driver.h
* This file is part of RTGUI in RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-04 Bernard first version
*/
#ifndef __RTGUI_DRIVER_H__
#define __RTGUI_DRIVER_H__ #include <rtgui/list.h>
#include <rtgui/color.h> struct rtgui_graphic_driver_ops
{
/* set and get pixel in (x, y) */
void (*set_pixel)(rtgui_color_t *c, int x, int y);
void (*get_pixel)(rtgui_color_t *c, int x, int y); void (*draw_hline)(rtgui_color_t *c, int x1, int x2, int y);
void (*draw_vline)(rtgui_color_t *c, int x , int y1, int y2); /* draw raw hline */
void (*draw_raw_hline)(rt_uint8_t *pixels, int x1, int x2, int y);
}; struct rtgui_graphic_driver
{
/* pixel format and byte per pixel */
rt_uint8_t pixel_format;
rt_uint8_t bits_per_pixel;
rt_uint16_t pitch; /* screen width and height */
rt_uint16_t width;
rt_uint16_t height; /* framebuffer address and ops */
volatile rt_uint8_t *framebuffer;
rt_device_t device;
const struct rtgui_graphic_driver_ops *ops;
};
………………
………………
………………
/*
* File : driver.c
* This file is part of RTGUI in RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-10-04 Bernard first version
*/
#include <rtthread.h>
#include <rtgui/driver.h> struct rtgui_graphic_driver _driver; ………………
………………
………………
rt_err_t rtgui_graphic_set_device(rt_device_t device)
{
rt_err_t result;
struct rt_device_graphic_info info; /* get framebuffer address */
result = rt_device_control(device, RTGRAPHIC_CTRL_GET_INFO, &info);
if (result != RT_EOK)
{
/* get device information failed */
return -RT_ERROR;
} /* initialize framebuffer driver */
_driver.device = device;
_driver.pixel_format = info.pixel_format;
_driver.bits_per_pixel = info.bits_per_pixel;
_driver.width = info.width;
_driver.height = info.height;
_driver.pitch = _driver.width * _driver.bits_per_pixel / 8;
_driver.framebuffer = info.framebuffer; if (info.framebuffer != RT_NULL)
{
/* is a frame buffer device */
_driver.ops = rtgui_framebuffer_get_ops(_driver.pixel_format);
}
else
{
/* is a pixel device */
_driver.ops = rtgui_pixel_device_get_ops(_driver.pixel_format);
} return RT_EOK;
}
………………
………………
………………

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

STM32 + RT Thread OS 学习笔记[四]的更多相关文章

  1. STM32 + RT Thread OS 学习笔记[二]

    串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1.   目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...

  2. STM32 + RT Thread OS 学习笔记[三]

    RTGUI 据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块.如果要移植到其它OS,估计难度较大.目前还处于Alpha状态,最终将会包含 ...

  3. STM32 + RT Thread OS 串口通讯

    1.   创建项目 a)   禁用Finsh和console b)   默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...

  4. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  5. muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制

    目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...

  6. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

  7. 零拷贝详解 Java NIO学习笔记四(零拷贝详解)

    转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...

  8. kvm虚拟化学习笔记(四)之kvm虚拟机日常管理与配置

    KVM虚拟化学习笔记系列文章列表----------------------------------------kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51 ...

  9. ZooKeeper学习笔记四:使用ZooKeeper实现一个简单的分布式锁

    作者:Grey 原文地址: ZooKeeper学习笔记四:使用ZooKeeper实现一个简单的分布式锁 前置知识 完成ZooKeeper集群搭建以及熟悉ZooKeeperAPI基本使用 需求 当多个进 ...

随机推荐

  1. 在Web Api中快速实现JSonp

    本文翻译自:http://www.codeproject.com/Tips/631685/JSONP-in-ASP-NET-Web-API-Quick-Get-Started Concept: 同源策 ...

  2. Java基础11 对象引用

    链接地址:http://www.cnblogs.com/vamei/archive/2013/04/01/2992484.html 作者:Vamei 出处:http://www.cnblogs.com ...

  3. SMTP命令 发送邮件 DOS命令

    1.实例:从qq邮箱 发送到其他地址的邮箱 >telnet smtp.qq.com 25 >helo qq.com >auth login >NzI3MTU0MTg3QHFxL ...

  4. perl 回调函数

    在计算机程序设计中,回调函数,或简称回调(Callback),是指通过函数参数传递到其它代码的,某一块可执行代码的引用.这一设计允许了底层代码调用在高层定义的子程序. 没啥不好理解的呀,就是向函数的参 ...

  5. perl 调用方法 子例程说明

    Perl does not provide any special syntax for class definitions Perl 不提供任何特殊的语法对于类的定义 A package is si ...

  6. Swift - 闭包的介绍及用法(以数组排序为例)

    闭包(即一些小的匿名代码块),可以像函数一样使用.可以很方便的将闭包传给其他函数,告诉它们应当如何执行某一个任务. 1,使用sort方法和闭包进行数组排序 sort方法返回一个数组的有序版本.(sor ...

  7. HDU 3966 Aragorn&#39;s Story(树链剖分)

    HDU Aragorn's Story 题目链接 树抛入门裸题,这题是区间改动单点查询,于是套树状数组就OK了 代码: #include <cstdio> #include <cst ...

  8. MSSQL、C# 、Winform、ASP.NET - 数据库备份与还原模块

    数据库备份还原类: using System; using System.Collections.Generic; using System.Linq; using System.Text; usin ...

  9. W英语: 紧急, 非紧急

    take your time 慢慢来 It is not urgent. Take it easy please. 不急,慢慢来.

  10. Qt之日志输出文件

    在Qt开发过程当中经常使用qDebug等一些输出来调试程序,但是到了正式发布的时候,都会被注释或者删除,采用日志输出来代替.     做过项目的童鞋可能都使用过日志功能,以便有异常错误能够快速跟踪.定 ...