其实我一直就只想学一点东西,当时心太大了,就直接买了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-12 20:27
推荐帖子
- 基于瑞萨单片机的空中鼠标-原理图
- 瑞萨这个板子收到已经很久了,但是那是刚到公司报道,很多东西都没有比如没有网络,自己的电脑也带回去了。这个项目我一拖再拖,实在抱歉。希望论坛能理解刚入职的新人的处境。在那个公司干了不久,由于各种原因在决定重新找过工作,现在也是刚到新公司两周,算基本稳定下来。当初我申请这个板子的题目是空中鼠标,周末不用加班,先把原理图画了,请各位看看:其实要做一个空中鼠标的MCU外围电路就是这么简单!!基于瑞萨单片机的空中鼠标-原理图看起来确实简单。
- IC爬虫 瑞萨电子MCU
- 480伏高压直流无刷电机驱动问题
- 请问,480伏高压直流无刷电机驱动时,高压输入端需要用怎样型号的电容器(容值、耐压值等),非常感谢!480伏高压直流无刷电机驱动问题这个与你的驱动电路以及电容所处的位置有关,必须说清楚。该驱动板用于新能源汽车空调压缩机的电机驱动,直流480伏直接由车身提供,电容位于驱动板的直流480伏输入端。 直接并联在电源输入处,因车载电源本身应有足够滤波电容容值,此处仅做高频去耦即可。可用金属化高压电容,取630V或以上规格,0.1uF的即可。在高压直流无刷电机驱动中,输
- panyuxi77 电机驱动控制(Motor Control)
- R7F0C802x Easy Start ----计步器的原理
- 拿到板子也不少时间了,一直琢磨做什么的问题。R7F0C802x体积小,引脚少,内存小,功耗低,完成诸如示波器等大型的东西显然不合适。看到论坛里很多朋友都出了不少成果,心里急啊。。。。刚好手边有个加速度传感器,于是乎干脆做个基于加速度计的计步器吧。主要功能:1.使用干电池供电2.3轴加速度计来确定是否在步行3.通过蓝牙与手机连接4.手机客户端显示当前步数期待结果吧R7F0C802xEasyStart----计步器的原理
- youki12345 瑞萨电子MCU
- EMI 工程师完整指南(40000字,建议收藏)——目录及第一部分
- 目录 规范和测量 噪声传播和滤波 了解功率级寄生效应 辐射发射 采用集成FET设计的EMI抑制技术 采用离散FET设计的EMI抑制技术 反激式转换器的共模噪声 隔离式DC/DC电路的共模噪声抑制方法 扩频调制 第1部分规范与测量简介多数电源应用必须减少电磁干扰(EMI)以满足相关要求,系
- 木犯001号 电源技术
- 试出售一些闲置东西
- 整理了下自己的东西,试出售。感兴趣的同学可以交流下,谢谢1、vincotechigbt模块(FZ06NIA075SA-P926F33)3pcs2、TMS320F67201pcs3、电流霍尔_4646X4125pcs4、1ED020I12-FT20pcs5、2ED020I12-
- elvike 淘e淘
- 一起读《动手学深度学习(PyTorch版)》- 权重衰减(weight decay)
- weight-decay,用于解决过拟合问题,其中用到范数,将权重进行欧几里得范数,得到惩罚函数为Sum(w^2)/2,要保证权重向量比较小,最常用方法是将其范数作为惩罚项加到最小化损失的问题中,将原来的训练目标最小化训练标签上的预测损失,调整为最小化预测损失和惩罚项之和。现在,如果权重向量增长的太大,优化算法会更集中于最小化权重范数损失函数预测损失和惩罚项之和importtorchimporttorchvisionfromtorch.util
- LitchiCheng 测评中心专版
设计资源 培训 开发板 精华推荐
- EVAL-AD5141DB,用于 AD5141 四通道、256 位、非易失性存储器、数字电位计的评估板
- LTM8064IY 46Vin、-12Vout 负转换器的典型应用电路
- 使用2x SD2933的400 W / 1.6-54 MHz 参考设计
- 新的低电阻模拟开关允许在手机中切换扬声器
- 使用 ROHM Semiconductor 的 BU4809 的参考设计
- LTC3722-1 演示板,36-72V 输入和 12V,35A 输出
- 使用 Infineon Technologies AG 的 IRU3033 的参考设计
- 用于简单时钟振荡器的 NCP301LSN31T1 3.1V 电压检测器的典型应用
- MPC5606E车联网评估板
- OLED 2.45寸 305x96 SH1126G 高清屏幕 显示模块