其实我一直就只想学一点东西,当时心太大了,就直接买了Tiny4412,才发现这是一块硬骨头,网上资料少的可怜,FriendlyARM给的资料基本就是代码,说明性、讲原理的东西也没有。看了好久才发现其给的U-BOOT是不带LCD显示功能的,我就想给这个U-BOOT增加LCD显示功能,我所有的学习过程,都是为了增加LCD功能而开展的。这一篇虽然也有参考别人成份,但绝大多数内容都是我最近这段时间分析U-BOOT后,也进行相关裸机程序后(裸机代码的实现我有一篇相关的说明文档),有了一定的感觉,才顺利完成的。
下面依据《s5pv-u -boot-2011.06之增加LCD显示功能》的实现过程,来说明一下:我增加LCD功能的过程。
《s5pv-u-boot-2011.06之增加LCD显示功能》上说,其主要完成 U-Boot 层可以在 LCD 上显示字符,而且对于软件分层的 U-Boot 来说,只要将底层驱动移植过来并调整好初始化参数就可以在LCD上显示console。下图17-1是LCD 驱动软件分层执行流程示意。可以看到 LCD 在执行时最终调用的是底层的 board_video_init() 函数,其主要作用是对 LCD控制寄存器进行初始化。可由用户根据实际 LCD 硬件编写。
这个功能的移植修改了5 个文件。
图19-1、LCD 驱动软件分层执行流程示意
废话不多说,开始按步骤说明吧:
我用的U-Boot代码就是光盘中FriendlyARM提供的uboot_tiny4412-20130729.tgz。我的所有编辑操作都是在windows环境下,应用sourcein sight等工具进行的,最后才到linux环境下面进行编译。
第一步:增加底层头文件
复制LCD裸机程序下的字库文件,font_8x16.h,font_10x18.h,font_sun12x22.h到uboot_tiny4412-lcdinclude下,这三个字库文件是从Linux源码下提取出来的。具体说明可参看我裸机LCD程序说明文档。
接着,在uboot_tiny4412-lcdinclude目录下添加一个驱动程序所需的头文件,文件名为zth_tiny4412_lcd.h,此文件是从我的LCD裸机程序里复制过来的。zth_tiny4412_lcd.h内容如下,大家可以将其粘贴过去。
/****************************************
NAME:LCD.h
TRAD:
PROJECT:
CREATER:Zhang Taohua
DATA:2014-06-07
MAIL :zthvivid@163.com
DESCRIPTION:
*****************************************/
#ifndef __LCD_H
#define __LCD_H
extern void lcd_init(void);
extern void lcd_draw_pixel(introw, int col, int color);
extern void lcd_clear_screen(intcolor);
extern void lcd_draw_hline(introw, int col1, int col2, int color);
extern void lcd_draw_vline(intcol, int row1, int row2, int color);
extern void lcd_draw_cross(introw, int col, int halflen, int color);
extern void led_blink(intlink_times);
extern void delay(unsigned longcount);
extern void draw_point(int x, inty, int r, int g, int b);
//extern void memset_int(unsignedint * s, int c,unsigned int count);
extern void lcd_draw_bmp(constunsigned char gImage_bmp[]);
extern voidlcd_draw_char(unsigned char c);
#define readb(a) (*(volatile unsigned char*)(a))
#define readw(a) (*(volatile unsigned short*)(a))
#define readl(a) (*(volatile unsigned int*)(a))
#define writeb(v,a) (*(volatile unsigned char *)(a) = (v))
#define writew(v,a) (*(volatile unsigned short *)(a) =(v))
#define writel(v,a) (*(volatile unsigned int *)(a) = (v))
//FONT
//#define FONT8_16 1
//#define FONT10_18 1
#define FONT12_22 1
#define FONT_STATIC_ROW 8
#if FONT8_16
#define FONT_ROW 8
#define FONT_COL 16
#endif
#if FONT10_18
#define FONT_ROW 10
#define FONT_COL 18
#endif
#if FONT12_22
#define FONT_ROW 12
#define FONT_COL 22
#endif
//PICTURE
#define PICTURE_WIDTH
#define PICTURE_HEIGHT
//LCD Clock Relate Register
#define CLK_DIV_LCD (*(volatileunsigned int *)0x1003c534)
#define CLK_SRC_MASK_LCD(*(volatile unsigned int *)0x1003c334)
#define CLK_GATE_IP_LCD(*(volatile unsigned int *)0x1003c934)
#define CLK_SRC_LCD0 (*(volatileunsigned int *)0x1003c234)
//Framer Buffer Address And Size
//#define LCD_VIDEO_ADDR (0x54000000)
//#define VIDEO_MEM_SIZE 0x200000 /* 800x480x24bit =0X119400 bytes */
//LED IO Control Regiester
#define GPM4CON (*(volatile unsigned long *) 0x110002E0)
#define GPM4DAT (*(volatile unsigned long *) 0x110002E4)
//LCD OP Control Regiester
#define GPF0CON (*(volatile unsigned int *)0x11400180)
#define GPF0DAT (*(volatile unsigned int *)0x11400184)
#define GPF0PUD (*(volatile unsigned int *)0x11400188)
#define GPF0DRV (*(volatile unsigned int *)0x1140018C)
#define GPF1CON (*(volatile unsigned int *)0x114001a0)
#define GPF1DAT (*(volatileunsigned int *)0x114001a4)
#define GPF1PUD (*(volatile unsigned int *)0x114001a8)
#define GPF1DRV (*(volatile unsigned int *)0x114001ac)
#define GPF2CON (*(volatile unsigned int *)0x114001c0)
#define GPF2DAT (*(volatileunsigned int *)0x114001c4)
#define GPF2PUD (*(volatile unsigned int *)0x114001c8)
#define GPF2DRV (*(volatile unsigned int *)0x114001cc)
#define GPF3CON (*(volatile unsigned int *)0x114001e0)
#define GPF3DAT (*(volatileunsigned int *)0x114001e4)
#define GPF3PUD (*(volatile unsigned int *)0x114001e8)
#define GPF3DRV (*(volatile unsigned int *)0x114001ec)
#define LCDBLK_CFG (*(volatileunsigned int *)0x10010210)
#define LCDBLK_CFG2 (*(volatileunsigned int *)0x10010214)
//LCD Control Register
#define LCD_BASE 0x11C00000
#define VIDCON0 (*(volatile unsigned int *)(LCD_BASE +0x0000))
#define VIDCON1 (*(volatile unsigned int *)(LCD_BASE +0x0004))
#define VIDCON2 (*(volatile unsigned int *)(LCD_BASE +0x0008))
#define VIDCON3 (*(volatile unsigned int *)(LCD_BASE +0x000C))
#define VIDTCON0 (*(volatile unsigned int *)(LCD_BASE +0x0010))
#define VIDTCON1 (*(volatile unsigned int *)(LCD_BASE +0x0014))
#define VIDTCON2 (*(volatile unsigned int *)(LCD_BASE +0x0018))
#define VIDTCON3 (*(volatile unsigned int *)(LCD_BASE +0x001C))
#define WINCON0 (*(volatile unsigned int *)(LCD_BASE +0x0020))
#define WINCON1 (*(volatile unsigned int *)(LCD_BASE +0x0024))
#define WINCON2 (*(volatile unsigned int *)(LCD_BASE +0x0028))
#define WINCON3 (*(volatile unsigned int *)(LCD_BASE + 0x002C))
#define WINCON4 (*(volatile unsigned int *)(LCD_BASE +0x0030))
#define SHADOWCON (*(volatile unsigned int *)(LCD_BASE +0x0034))
#define WINCHMAP2 (*(volatile unsigned int *)(LCD_BASE + 0x003C))
#define VIDOSD0A (*(volatile unsigned int *)(LCD_BASE +0x0040))
#define VIDOSD0B (*(volatile unsigned int *)(LCD_BASE +0x0044))
#define VIDOSD0C (*(volatile unsigned int *)(LCD_BASE +0x0048))
#define VIDOSD1A (*(volatile unsigned int *)(LCD_BASE +0x0050))
#define VIDOSD1B (*(volatile unsigned int *)(LCD_BASE +0x0054))
#define VIDOSD1C (*(volatile unsigned int *)(LCD_BASE +0x0058))
#define VIDOSD1D (*(volatile unsigned int *)(LCD_BASE +0x005C))
#define VIDOSD2A (*(volatile unsigned int *)(LCD_BASE +0x0060))
#define VIDOSD2B (*(volatile unsigned int *)(LCD_BASE +0x0064))
#define VIDOSD2C (*(volatile unsigned int *)(LCD_BASE +0x0068))
#define VIDOSD2D (*(volatile unsigned int *)(LCD_BASE +0x006C))
#define VIDOSD3A (*(volatile unsigned int *)(LCD_BASE +0x0070))
#define VIDOSD3B (*(volatile unsigned int *)(LCD_BASE +0x0074))
#define VIDOSD3C (*(volatile unsigned int *)(LCD_BASE +0x0078))
#define VIDOSD4A (*(volatile unsigned int *)(LCD_BASE +0x0080))
#define VIDOSD4B (*(volatile unsigned int *)(LCD_BASE +0x0084))
#define VIDOSD4C (*(volatile unsigned int *)(LCD_BASE +0x0088))
#define VIDW00ADD0B0 (*(volatile unsigned int *)(LCD_BASE +0x00A0))
#define VIDW00ADD0B1 (*(volatile unsigned int *)(LCD_BASE +0x00A4))
#define VIDW00ADD0B2 (*(volatile unsigned int *)(LCD_BASE +0x20A0))
#define VIDW01ADD0B0 (*(volatile unsigned int *)(LCD_BASE +0x00A8))
#define VIDW01ADD0B1 (*(volatile unsigned int *)(LCD_BASE +0x00AC))
#define VIDW01ADD0B2 (*(volatile unsigned int *)(LCD_BASE +0x20A8))
#define VIDW02ADD0B0 (*(volatile unsigned int *)(LCD_BASE +0x00B0))
#define VIDW02ADD0B1 (*(volatile unsigned int *)(LCD_BASE +0x00B4))
#define VIDW02ADD0B2 (*(volatile unsigned int *)(LCD_BASE +0x20B0))
#define VIDW03ADD0B0 (*(volatile unsigned int *)(LCD_BASE + 0x00B8))
#define VIDW03ADD0B1 (*(volatile unsigned int *)(LCD_BASE +0x00BC))
#define VIDW03ADD0B2 (*(volatile unsigned int *)(LCD_BASE +0x20B8))
#define VIDW04ADD0B0 (*(volatile unsigned int *)(LCD_BASE +0x00C0))
#define VIDW04ADD0B1 (*(volatile unsigned int *)(LCD_BASE +0x00C4))
#define VIDW04ADD0B2 (*(volatile unsigned int *)(LCD_BASE +0x20C0))
#define VIDW00ADD1B0 (*(volatile unsigned int *)(LCD_BASE +0x00D0))
#define VIDW00ADD1B1 (*(volatile unsigned int *)(LCD_BASE +0x00D4))
#define VIDW00ADD1B2 (*(volatile unsigned int *)(LCD_BASE +0x20D0))
#define VIDW01ADD1B0 (*(volatile unsigned int *)(LCD_BASE +0x00D8))
#define VIDW01ADD1B1 (*(volatile unsigned int *)(LCD_BASE +0x00DC))
#define VIDW01ADD1B2 (*(volatile unsigned int *)(LCD_BASE +0x20D8))
上一篇:第十八章:Android LCD(四):LCD驱动调试篇
下一篇:第十一章、Tiny4412 U-BOOT移植十一 DDR3简单介绍
推荐阅读最新更新时间:2024-11-19 05:16
推荐帖子
- 急问!多谢了
- 我的毕业设计是给个基于ISA的CAN模块做个驱动环境:WindowsXP工具:driverworks可是CAN是基于内存访问的,我不知道用在driverworks开发的驱动程序中如何访问物理内存,查了很多资料,都没有解决,有知道的麻烦告诉我一声,多谢!现在离验收没有几天了,很着急!期待好心人的帮助!急问!多谢了
- huhuashen 嵌入式系统
- [新手学习一点心得]几个常用外设模块的库函数操作流程
- 呵呵,大虾就不用看了,像我一样的新手可以看看GPIO操作流程中的库函数1.内核时钟设置SysCtlClockSet2.片上设备时钟使能SysCtlPeripheralEnable3.GPIO设置//输入(数字、模拟)、输出(数字)、由硬件决定GPIODirModeSet/Get//驱动强度、推挽/开漏、模拟功能设置GPIOPadConfigSet/Get注:上述
- fishplj2000 微控制器 MCU
- 常见阻抗匹配的方式
- 1、串联终端匹配在信号源端阻抗低于传输线特征阻抗的条件下,在信号的源端和传输线之间串接一个电阻R,使源端的输出阻抗与传输线的特征阻抗相匹配,抑制从负载端反射回来的信号发生再次反射。匹配电阻选择原则:匹配电阻值与驱动器的输出阻抗之和等于传输线的特征阻抗。常见的CMOS和TTL驱动器,其输出阻抗会随信号的电平大小变化而变化。因此,对TTL或CMOS电路来说,不可能有十分正确的匹配电阻,只能折中考虑。链状拓扑结构的信号网路不适合使用串联终端匹配,所有的负载必须接
- fish001 模拟与混合信号
- 新版GB 31241-2022《便携式电子产品用锂离子电池和电池组 安全技术规范》新-旧版本...
- 新版GB31241-2022《便携式电子产品用锂离子电池和电池组安全技术规范》(以下简称新版标准)已于2022年12月29日发布,将于2024年1月1日起实施并替代GB31241-2014(以下简称旧版标准)。相比于旧版标准,新版标准主要包含了如下重要更新: 1.术语和定义 修改、增加内容 章节 修改了部分术语和定义 3.1锂离子电池 3.2银离子电池组 3.11充电上限电压 3.23上限充电
- 木犯001号 电源技术
- 寻找在WINCE下面做过16C554驱动的技术人员
- 由于时间很紧,项目需要7月10号之前结题,目前我们选择的平台是S3C2440,操作系统是WINCE,由于三星2440的串口数量不满足项目要求,因此我们外扩了st16c554芯片来扩展4个串口。由于时间关系,我们自己来不及进行串口芯片调试了,想寻找做过此类项目的人员合作。时间是:20天,经费在1000~2500之间。有意的朋友可以直接和我联系,联系方式:zhaozw1975@hotmail.comQQ:525074092(注明:串口驱动项目)邮箱:zhaozzw@mail.hzic.edu
- nebulabhm WindowsCE
- EVCC
- 有没有做电动汽车充电通信模块EVCC的厂家,可以做一下交流,也可以告诉我EVCC做的好一些的厂家,有这方面的需求。EVCC瑞凯诺科技江苏羿邦新能源凯迈(洛阳)测控
- 爱干饭 汽车电子
设计资源 培训 开发板 精华推荐
- 适用于汽车信息娱乐处理器电源的 17W 系统级电源参考设计
- 使用 ON Semiconductor 的 SR10210 的参考设计
- LTC1148、具有故障保护功能的 5V 至 3.3V 稳压器
- 用于音频的 4 通道 D 类音频功率放大器
- 用于街道和室内 LED 照明的 25W、21 个 LED 室内和室外 LED 驱动器
- XPC563MADPT176S、XPC563MKIT 评估系统支持Freescale MPC563xM MCU
- #第四届立创大赛#汽车高强度气体放电灯HID安定器
- 使用 Analog Devices 的 LTC3130EUDC-1 的参考设计
- 使用 Analog Devices 的 LTC1261LCS8-4.5 的参考设计
- 使用 ROHM Semiconductor 的 BU4832 的参考设计
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸
- 千丘智能侍淳博:用数字疗法,点亮“孤独症”儿童的光
- 数药智能冯尚:ADHD数字疗法正为儿童“多动症”提供更有效便捷服务
- Vicor高性能电源模块助力低空航空电子设备和 EVTOL的发展
- 创实技术electronica 2024首秀:加速国内分销商海外拓展之路
- 硬核拆解|看看千元智能电表内部如何连接
- 罗姆有奖直播|可应用于LiDAR的激光二极管及周边电源推荐
- 【EE征集令】LaunchPad学习全体验
- 打卡英飞凌碳化硅MOSFET新品快闪店
- 将想法变成现实,Maxim MAX32630FTHR创意设计大赛,重磅开启!
- 【答题有奖】赛灵思工业与医疗专题有奖问答
- 【有奖下载】英飞凌《时尚小家电功率器选型指南》,详解兼具强大功能与潮流款式的小家电设计!
- 罗姆有奖直播|从0到1,带你了解电机及其驱动 开始报名啦~
- 泰克MDO3000系列示波器结合MDO3PWR功率分析模块 立即询价享春季好礼!
- PSoC4 Cortex-M0开发板免费申请,分享心得赢惊喜大礼!