一。环境

  系统:ubuntu12.04

  开发板:jz2440

  编译器:gcc

二。说明

有空补上

三。代码

Makefile:

 CC      = arm-linux-gcc
LD = arm-linux-ld
AR = arm-linux-ar
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump CFLAGS := -Wall -O2 export CC LD AR OBJCOPY OBJDUMP CFLAGS objs := head.o init.o nand.o lcddrv.o framebuffer.o main.o lcd.bin: $(objs)
${LD} -Tlcd.lds -o lcd_elf $^
${OBJCOPY} -O binary -S lcd_elf $@
${OBJDUMP} -D -m arm lcd_elf > lcd.dis %.o:%.c
${CC} $(CFLAGS) -c -o $@ $< %.o:%.S
${CC} $(CFLAGS) -c -o $@ $< clean:
rm -f lcd.bin lcd_elf lcd.dis *.o

head.S:

 @******************************************************************************
@ File: head.S
@ 功能: 设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@****************************************************************************** .extern main
.text
.global _start
_start:
@******************************************************************************
@ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用
@******************************************************************************
b Reset @ 0x04: 未定义指令中止模式的向量地址
HandleUndef:
b HandleUndef @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
HandleSWI:
b HandleSWI @ 0x0c: 指令预取终止导致的异常的向量地址
HandlePrefetchAbort:
b HandlePrefetchAbort @ 0x10: 数据访问终止导致的异常的向量地址
HandleDataAbort:
b HandleDataAbort @ 0x14: 保留
HandleNotUsed:
b HandleNotUsed @ 0x18: 中断模式的向量地址
HandleIRQ:
b HandleIRQ @ 0x1c: 快中断模式的向量地址
HandleFIQ:
b HandleFIQ Reset:
ldr sp, = @ 设置栈指针,以下都是C函数,调用前需要设好栈
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK
bl memsetup @ 设置存储控制器以使用SDRAM
bl nand_init @ 初始化NAND Flash @ 复制代码到SDRAM中
ldr r0, =0x30000000 @ . 目标地址 = 0x30000000,这是SDRAM的起始地址
mov r1, # @ . 源地址 = ,运行地址在SDRAM中的代码保存在NAND Flash 4096地址开始处
mov r2, #* @ . 复制长度 = 16K,对于本实验,这是足够了
bl CopyCode2SDRAM @ 调用C函数CopyCode2SDRAM bl clean_bss @ 清除bss段,未初始化或初值为0的全局/静态变量保存在bss段 msr cpsr_c, #0xdf @ 进入系统模式
ldr sp, =0x34000000 @ 设置系统模式栈指针, ldr lr, =halt_loop @ 设置返回地址
ldr pc, =main @ 调用main函数
halt_loop:
b halt_loop

上面的sdram,时钟,nand flash等同前面的,不贴出来了

现在与lcd有关的函数:

main.c:

 #include "lcddrv.h"
#include "framebuffer.h"
#include "s3c24xx.h" void delay() { unsigned long cnt; for(cnt=;cnt<;cnt++); } int main()
{
Lcd_Port_Init(); // 设置LCD引脚
Tft_Lcd_Init(); // 初始化LCD控制器
Lcd_PowerEnable(, ); // 设置LCD_PWREN有效,它用于打开LCD的电源
Lcd_EnvidOnOff(); // 使能LCD控制器输出信号 ClearScr(0x0); // 清屏,黑色
while ()
{ Mire();
delay();
//Lcd_EnvidOnOff(0); } return ;
}

由main函数可以看出,本程序只是驱动lcd来画同心圆,参考代码是韦东山先生的,此处作了较大的删改:

framebuffer.c:

 /*
* FILE: framebuffer.c
* 实现在framebuffer上画点、画线、画同心圆、清屏的函数
*/ #include "framebuffer.h" extern unsigned int fb_base_addr;
extern unsigned int bpp;
extern unsigned int xsize;
extern unsigned int ysize; /*
* 画点
* 输入参数:
* x、y : 象素坐标
* color: 颜色值
* 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),
* 需要转换为5:6:5格式
* 对于8BPP: color为调色板中的索引值,
* 其颜色取决于调色板中的数值
*/
void PutPixel(unsigned int x, unsigned int y, unsigned int color)
{
unsigned char red,green,blue; switch (bpp){
case :
{
unsigned short *addr = (unsigned short *)fb_base_addr + (y * xsize + x);
red = (color >> ) & 0x1f;
green = (color >> ) & 0x3f;
blue = (color >> ) & 0x1f;
color = (red << ) | (green << ) | blue; // 格式5:6:5
*addr = (unsigned short) color;
break;
} default:
break;
}
} /*
* 绘制同心圆
*/
void Mire(void)
{
unsigned int x,y;
unsigned int color;
unsigned char red,green,blue,alpha; for (y = ; y < ysize; y++)
for (x = ; x < xsize; x++){
color = ((x-xsize/)*(x-xsize/) + (y-ysize/)*(y-ysize/))/;
red = (color/) % ;
green = (color/) % ;
blue = (color/) % ;
alpha = (color*) % ; color |= ((unsigned int)alpha << );
color |= ((unsigned int)red << );
color |= ((unsigned int)green << );
color |= ((unsigned int)blue ); PutPixel(x,y,color);
}
} /*
* 将屏幕清成单色
* 输入参数:
* color: 颜色值
* 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),
* 需要转换为5:6:5格式
* 对于8BPP: color为调色板中的索引值,
* 其颜色取决于调色板中的数值
*/
void ClearScr(unsigned int color)
{
unsigned int x,y; for (y = ; y < ysize; y++)
for (x = ; x < xsize; x++)
PutPixel(x, y, color);
}

lcddrv.c:

 /*
* FILE: lcddrv.c
* 提供操作LCD控制器、调色板等的底层函数
*/ #include "s3c24xx.h"
#include "lcddrv.h" #define GPB0_tout0 (2<<(0*2))
#define GPB0_out (1<<(0*2))
#define GPB1_out (1<<(1*2)) #define GPB0_MSK (3<<(0*2))
#define GPB1_MSK (3<<(1*2)) unsigned int fb_base_addr;
unsigned int bpp;
unsigned int xsize;
unsigned int ysize; /*
* 初始化用于LCD的引脚
*/
void Lcd_Port_Init(void)
{
GPCUP = 0xffffffff; // 禁止内部上拉
GPCCON = 0xaaaaaaaa; // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND
GPDUP = 0xffffffff; // 禁止内部上拉
GPDCON = 0xaaaaaaaa; // GPIO管脚用于VD[23:8]
GPBCON &= ~(GPB0_MSK); // Power enable pin
GPBCON |= GPB0_out;
GPBDAT &= ~(<<); // Power off } /*
* 初始化LCD控制器
* 输入参数:
* type: 显示模式
* MODE_TFT_8BIT_240320 : 240*320 8bpp的TFT LCD
* MODE_TFT_16BIT_240320 : 240*320 16bpp的TFT LCD
* MODE_TFT_8BIT_640480 : 640*480 8bpp的TFT LCD
* MODE_TFT_16BIT_640480 : 640*480 16bpp的TFT LCD
*/
void Tft_Lcd_Init()
{ /*
* 设置LCD控制器的控制寄存器LCDCON1~5
* 1. LCDCON1:
* 设置VCLK的频率:VCLK(Hz) = HCLK/[(CLKVAL+1)x2]
* 选择LCD类型: TFT LCD
* 设置显示模式: 16BPP
* 先禁止LCD信号输出
* 2. LCDCON2/3/4:
* 设置控制信号的时间参数
* 设置分辨率,即行数及列数
* 现在,可以根据公式计算出显示器的频率:
* 当HCLK=100MHz时,
* Frame Rate = 1/[{(VSPW+1)+(VBPD+1)+(LIINEVAL+1)+(VFPD+1)}x
* {(HSPW+1)+(HBPD+1)+(HFPD+1)+(HOZVAL+1)}x
* {2x(CLKVAL+1)/(HCLK)}]
* = 60Hz
* 3. LCDCON5:
* 设置显示模式为16BPP时的数据格式: 5:6:5
* 设置HSYNC、VSYNC脉冲的极性(这需要参考具体LCD的接口信号): 反转
* 半字(2字节)交换使能
*/
LCDCON1 = (<<) | (LCDTYPE_TFT<<) | \
(BPPMODE_16BPP<<) | (ENVID_DISABLE<<);
LCDCON2 = (<<) | (<<) | \
(<<) | ();
LCDCON3 = (<<) | (<<) | ();
LCDCON4 = ;
LCDCON5 = (FORMAT8BPP_565<<) | (HSYNC_INV<<) | (VSYNC_INV<<) | \
(HWSWP<<); /*
* 设置LCD控制器的地址寄存器LCDSADDR1~3
* 帧内存与视口(view point)完全吻合,
* 图像数据格式如下:
* |----PAGEWIDTH----|
* y/x 0 1 2 239
* 0 rgb rgb rgb ... rgb
* 1 rgb rgb rgb ... rgb
* 1. LCDSADDR1:
* 设置LCDBANK、LCDBASEU
* 2. LCDSADDR2:
* 设置LCDBASEL: 帧缓冲区的结束地址A[21:1]
* 3. LCDSADDR3:
* OFFSIZE等于0,PAGEWIDTH等于(240*2/2)
*/
LCDSADDR1 = ((LCDFRAMEBUFFER>>)<<) | LOWER21BITS(LCDFRAMEBUFFER>>);
LCDSADDR2 = LOWER21BITS((LCDFRAMEBUFFER+ \
()*()*)>>);
LCDSADDR3 = (<<) | (*/); /* 禁止临时调色板寄存器 */
TPAL = ; fb_base_addr = LCDFRAMEBUFFER;
bpp = ;
xsize = ;
ysize = ; } /*
* 设置是否输出LCD电源开关信号LCD_PWREN
* 输入参数:
* invpwren: 0 - LCD_PWREN有效时为正常极性
* 1 - LCD_PWREN有效时为反转极性
* pwren: 0 - LCD_PWREN输出有效
* 1 - LCD_PWREN输出无效
*/
void Lcd_PowerEnable(int invpwren, int pwren)
{
GPGCON = (GPGCON & (~(<<))) | (<<); // GPG4用作LCD_PWREN
GPGUP = (GPGUP & (~(<<))) | (<<); // 禁止内部上拉 LCDCON5 = (LCDCON5 & (~(<<))) | (invpwren<<); // 设置LCD_PWREN的极性: 正常/反转
LCDCON5 = (LCDCON5 & (~(<<))) | (pwren<<); // 设置是否输出LCD_PWREN
} /*
* 设置LCD控制器是否输出信号
* 输入参数:
* onoff:
* 0 : 关闭
* 1 : 打开
*/
void Lcd_EnvidOnOff(int onoff)
{
if (onoff == )
{
LCDCON1 |= ; // ENVID ON
GPBDAT |= (<<); // Power on
}
else
{
LCDCON1 &= 0x3fffe; // ENVID Off
GPBDAT &= ~(<<); // Power off
}
}

现在贴出重要的头文件做为理解用:

lcddrv.h:

 /*
* FILE: lcddrv.h
* 操作LCD控制器、调色板等的底层函数接口
*/ #ifndef __LCDDRV_H__
#define __LCDDRV_H__ #define LOWER21BITS(n) ((n) & 0x1fffff) #define BPPMODE_16BPP 0xC #define LCDTYPE_TFT 0x3 #define ENVID_DISABLE 0
#define ENVID_ENABLE 1 #define FORMAT8BPP_5551 0
#define FORMAT8BPP_565 1 #define HSYNC_NORM 0
#define HSYNC_INV 1 #define VSYNC_NORM 0
#define VSYNC_INV 1 #define VDEN_NORM 0
#define VDEN_INV 1 #define BSWP 1
#define HWSWP 1 #define LCDFRAMEBUFFER 0x30400000 /*
* 初始化用于LCD的引脚
*/
void Lcd_Port_Init(void); /*
* 初始化LCD控制器
* 输入参数:
* type: 显示模式
* MODE_TFT_8BIT_640480 : 640*640 8bpp的TFT LCD
* MODE_TFT_16BIT_640480 : 640*640 16bpp的TFT LCD
*/
void Tft_Lcd_Init(); void Lcd_EnvidOnOff(int onoff); /*
* 设置是否输出LCD电源开关信号LCD_PWREN
* 输入参数:
* invpwren: 0 - LCD_PWREN有效时为正常极性
* 1 - LCD_PWREN有效时为反转极性
* pwren: 0 - LCD_PWREN输出有效
* 1 - LCD_PWREN输出无效
*/
void Lcd_PowerEnable(int invpwren, int pwren); #endif /*__LCDDRV_H__*/

自然不难看出,仍然有不少冗余项,这里先不做深究。

上面代码经过烧写验证,没有问题。

代码删减了串口,中断,以及print函数的硬件重定向等内容,以便更直观理解lcd驱动。

关于代码中重要函数,有时间补上。

实验九--裸机LCD的更多相关文章

  1. Linux基础入门(新版)(实验九-实验十二)

    实验九 简单文本入门 一.常用的文本处理命令 二.文本处理命令 1.tr 命令 tr 命令可以用来删除一段文本信息中的某些文字.或者将其进行转换. 使用方式: tr [option]...SET1 [ ...

  2. 2017-2018-2 20155228 《网络对抗技术》 实验九:Web安全基础

    2017-2018-2 20155228 <网络对抗技术> 实验九:Web安全基础 1. 实践内容 1.1 标理解常用网络攻击技术的基本原理 1.2 在Webgoat实验环境下实践相关实验 ...

  3. 实验九 ZStack 广播通信实验

    实验九 ZStack 广播通信实验[实验目的]1. 了解 ZigBee 广播通信的原理2. 掌握在 ZigBee 网络中进行广播通信的方法[实验设备]1. 装有 IAR 开发工具的 PC 机一台2.  ...

  4. 2017-2018-2 20155225《网络对抗技术》实验九 Web安全基础

    2017-2018-2 20155225<网络对抗技术>实验九 Web安全基础 WebGoat 1.String SQL Injection 题目是想办法得到数据库所有人的信用卡号,用Sm ...

  5. 20155201 网络攻防技术 实验九 Web安全基础

    20155201 网络攻防技术 实验九 Web安全基础 一.实践内容 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 二.报告内容: 1. 基础问题回答 1)SQL注入攻击 ...

  6. 20155222卢梓杰 实验九 Web安全基础

    实验九 Web安全基础 今天不多bb,打开webgoat就是干好吧 1.简单字符串sql注入 可以看到这个实验说明是 "下表允许用户查看其信用卡号码.尝试插入一个SQL字符串,以显示所有信用 ...

  7. # 2017-2018-2 20155231《网络对抗技术》实验九: Web安全基础实践

    2017-2018-2 20155231<网络对抗技术>实验九: Web安全基础实践 实验要求: 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 实验内容: ( ...

  8. 20155235 《网络攻防》 实验九 Web安全基础

    20155235 <网络攻防> 实验九 Web安全基础 实验内容 SQL注入攻击 XSS攻击 CSRF攻击 WebGoat WebGoat是OWASP组织研制出的用于进行web漏洞实验的应 ...

  9. 20155313 杨瀚 《网络对抗技术》实验九 Web安全基础

    20155313 杨瀚 <网络对抗技术>实验九 Web安全基础 一.实验目的 本实践的目标理解常用网络攻击技术的基本原理.Webgoat实践下相关实验. 二.基础问题回答 1.SQL注入攻 ...

随机推荐

  1. 用户环境配置文件/etc/profile

    当用户在登录界面正确地输入用户名和密码后,系统就开始为用户构建一个可以使用的用户环境.用户环境包括用户使用的环境变量.快捷键设置及命令别名等.这些设置大多是通过运行全局用户配置文件/etc/profi ...

  2. iOS runtime 运行时( 三 )

    上一篇 聊的是: 在不知道一个对象有什么属性的情况下, 获取对象的所有属性,然后可以改变属性的值, 今天我们谈谈 怎么通过Category(类别)+runtime 给一个类 添加一个新的属性,一般情况 ...

  3. Android(java)学习笔记264:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  4. web前端开发(2)

    搜索引擎只能通过标签判断网页的语义. table布局代码量大.对搜素引擎不友好,应该使用div+css布局,使用css控制网页中元素的大小.颜色.位置,让html在样式.结构混杂的局面中挣脱出来,专注 ...

  5. XML Schema验证

    XML Schema验证 一.什么事Schema(XSD) XML Schema是微软定义的一套用来验证XML技术.是一套预先规定的XML元素和属性创建的,这些元素和属性定义了XML文档的结构和内容模 ...

  6. 如何让oracle的select强制走索

    大多数情况下,oracle数据库内置的查询优化策略还是很成功的,但偶尔也有糊涂的时候,即使有索引,也会做全表扫描,可以参考以下语句的写法,强制让select语句使用索引. (注意:走索引不一定是最优的 ...

  7. codeforces 675B B. Restoring Painting(暴力枚举)

    题目链接: B. Restoring Painting time limit per test 1 second memory limit per test 256 megabytes input s ...

  8. Linux配置防火墙8080端口

    1.查看防火墙状态,哪些端口开放了 /etc/init.d/iptables status 2.配置防火墙 vi /etc/sysconfig/iptables ################### ...

  9. python15-day1课堂随机

    print("Hello world") #变量定义:一个在内存储存数据的容器#意义:为什么有变量,因为它保存程序执行的中间结果或状态以供后面的低吗进行调用 day1 = 200+ ...

  10. photoSlider-原生js移动开发轮播图、相册滑动插件

    详细内容请点击 在线预览   立即下载 使用方法: 分别引用css文件和js文件 如: <link rel="stylesheet" type="text/css& ...