一。环境
系统:ubuntu12.04
开发板:jz2440
编译器:gcc
二。说明
有空补上
三。代码
Makefile:
1 CC = arm-linux-gcc
2 LD = arm-linux-ld
3 AR = arm-linux-ar
4 OBJCOPY = arm-linux-objcopy
5 OBJDUMP = arm-linux-objdump
6
7 CFLAGS := -Wall -O2
8
9
10 export CC LD AR OBJCOPY OBJDUMP CFLAGS
11
12 objs := head.o init.o nand.o lcddrv.o framebuffer.o main.o
13
14 lcd.bin: $(objs)
15 ${LD} -Tlcd.lds -o lcd_elf $^
16 ${OBJCOPY} -O binary -S lcd_elf $@
17 ${OBJDUMP} -D -m arm lcd_elf > lcd.dis
18
19
20 %.o:%.c
21 ${CC} $(CFLAGS) -c -o $@ $<
22
23 %.o:%.S
24 ${CC} $(CFLAGS) -c -o $@ $<
25
26 clean:
27 rm -f lcd.bin lcd_elf lcd.dis *.o
28
head.S:
1 @******************************************************************************
2 @ File: head.S
3 @ 功能: 设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
4 @******************************************************************************
5
6 .extern main
7 .text
8 .global _start
9 _start:
10 @******************************************************************************
11 @ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用
12 @******************************************************************************
13 b Reset
14
15 @ 0x04: 未定义指令中止模式的向量地址
16 HandleUndef:
17 b HandleUndef
18
19 @ 0x08: 管理模式的向量地址,通过SWI指令进入此模式
20 HandleSWI:
21 b HandleSWI
22
23 @ 0x0c: 指令预取终止导致的异常的向量地址
24 HandlePrefetchAbort:
25 b HandlePrefetchAbort
26
27 @ 0x10: 数据访问终止导致的异常的向量地址
28 HandleDataAbort:
29 b HandleDataAbort
30
31 @ 0x14: 保留
32 HandleNotUsed:
33 b HandleNotUsed
34
35 @ 0x18: 中断模式的向量地址
36 HandleIRQ:
37 b HandleIRQ
38
39 @ 0x1c: 快中断模式的向量地址
40 HandleFIQ:
41 b HandleFIQ
42
43 Reset:
44 ldr sp, =4096 @ 设置栈指针,以下都是C函数,调用前需要设好栈
45 bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
46 bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK
47 bl memsetup @ 设置存储控制器以使用SDRAM
48 bl nand_init @ 初始化NAND Flash
49
50 @ 复制代码到SDRAM中
51 ldr r0, =0x30000000 @ 1. 目标地址 = 0x30000000,这是SDRAM的起始地址
52 mov r1, #4096 @ 2. 源地址 = 4096,运行地址在SDRAM中的代码保存在NAND Flash 4096地址开始处
53 mov r2, #16*1024 @ 3. 复制长度 = 16K,对于本实验,这是足够了
54 bl CopyCode2SDRAM @ 调用C函数CopyCode2SDRAM
55
56 bl clean_bss @ 清除bss段,未初始化或初值为0的全局/静态变量保存在bss段
57
58
59
60 msr cpsr_c, #0xdf @ 进入系统模式
61 ldr sp, =0x34000000 @ 设置系统模式栈指针,
62
63
64
65 ldr lr, =halt_loop @ 设置返回地址
66 ldr pc, =main @ 调用main函数
67 halt_loop:
68 b halt_loop
上面的sdram,时钟,nand flash等同前面的,不贴出来了
现在与lcd有关的函数:
main.c:
1 #include "lcddrv.h"
2 #include "framebuffer.h"
3 #include "s3c24xx.h"
4
5 void delay()
6
7 {
8
9 unsigned long cnt;
10
11 for(cnt=0;cnt<100000;cnt++);
12
13 }
14
15 int main()
16 {
17 Lcd_Port_Init(); // 设置LCD引脚
18 Tft_Lcd_Init(); // 初始化LCD控制器
19 Lcd_PowerEnable(0, 1); // 设置LCD_PWREN有效,它用于打开LCD的电源
20 Lcd_EnvidOnOff(1); // 使能LCD控制器输出信号
21
22 ClearScr(0x0); // 清屏,黑色
23 while (1)
24 {
25
26 Mire();
27 delay();
28 //Lcd_EnvidOnOff(0);
29
30 }
31
32 return 0;
33 }
由main函数可以看出,本程序只是驱动lcd来画同心圆,参考代码是韦东山先生的,此处作了较大的删改:
framebuffer.c:
1 /*
2 * FILE: framebuffer.c
3 * 实现在framebuffer上画点、画线、画同心圆、清屏的函数
4 */
5
6 #include "framebuffer.h"
7
8 extern unsigned int fb_base_addr;
9 extern unsigned int bpp;
10 extern unsigned int xsize;
11 extern unsigned int ysize;
12
13 /*
14 * 画点
15 * 输入参数:
16 * x、y : 象素坐标
17 * color: 颜色值
18 * 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),
19 * 需要转换为5:6:5格式
20 * 对于8BPP: color为调色板中的索引值,
21 * 其颜色取决于调色板中的数值
22 */
23 void PutPixel(unsigned int x, unsigned int y, unsigned int color)
24 {
25 unsigned char red,green,blue;
26
27 switch (bpp){
28 case 16:
29 {
30 unsigned short *addr = (unsigned short *)fb_base_addr + (y * xsize + x);
31 red = (color >> 19) & 0x1f;
32 green = (color >> 10) & 0x3f;
33 blue = (color >> 3) & 0x1f;
34 color = (red << 11) | (green << 5) | blue; // 格式5:6:5
35 *addr = (unsigned short) color;
36 break;
37 }
38
39
40 default:
41 break;
42 }
43 }
44
45 /*
46 * 绘制同心圆
47 */
48 void Mire(void)
49 {
50 unsigned int x,y;
51 unsigned int color;
52 unsigned char red,green,blue,alpha;
53
54 for (y = 0; y < ysize; y++)
55 for (x = 0; x < xsize; x++){
56 color = ((x-xsize/2)*(x-xsize/2) + (y-ysize/2)*(y-ysize/2))/64;
57 red = (color/8) % 256;
58 green = (color/4) % 256;
59 blue = (color/2) % 256;
60 alpha = (color*2) % 256;
61
62 color |= ((unsigned int)alpha << 24);
63 color |= ((unsigned int)red << 16);
64 color |= ((unsigned int)green << 8 );
65 color |= ((unsigned int)blue );
66
67 PutPixel(x,y,color);
68 }
69 }
70
71 /*
72 * 将屏幕清成单色
73 * 输入参数:
74 * color: 颜色值
75 * 对于16BPP: color的格式为0xAARRGGBB (AA = 透明度),
76 * 需要转换为5:6:5格式
77 * 对于8BPP: color为调色板中的索引值,
78 * 其颜色取决于调色板中的数值
79 */
80 void ClearScr(unsigned int color)
81 {
82 unsigned int x,y;
83
84 for (y = 0; y < ysize; y++)
85 for (x = 0; x < xsize; x++)
86 PutPixel(x, y, color);
87 }
lcddrv.c:
1 /*
2 * FILE: lcddrv.c
3 * 提供操作LCD控制器、调色板等的底层函数
4 */
5
6 #include "s3c24xx.h"
7 #include "lcddrv.h"
8
9 #define GPB0_tout0 (2< 10 #define GPB0_out (1< 11 #define GPB1_out (1< 12
13 #define GPB0_MSK (3< 14 #define GPB1_MSK (3< 15
16
17 unsigned int fb_base_addr;
18 unsigned int bpp;
19 unsigned int xsize;
20 unsigned int ysize;
21
22
23 /*
24 * 初始化用于LCD的引脚
25 */
26 void Lcd_Port_Init(void)
27 {
28 GPCUP = 0xffffffff; // 禁止内部上拉
29 GPCCON = 0xaaaaaaaa; // GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND
30 GPDUP = 0xffffffff; // 禁止内部上拉