編寫程序
/*
*硬件平臺:韋東山嵌入式Linxu開發板(S3C2440.v3)
*軟件平臺:運行於VMware Workstation 12 Player下UbuntuLTS16.04_x64 系統,
*參考資料:開發版原理圖,S3C2440A datasheet,AT043TN24 datasheet
*/
目錄
一、框架講解
- 第一層:測試菜單層:
lcd_test.c
- 第二層:根據目的劃分三個C文件:
framebuffer.c
、geometry.c
、font.c
- 第三層:LCD參數設置:
lcd.c
,考慮到拓展性,如果需要用到不同尺寸的lcd時,需要修改太多東西,所以在這一層下分了一個小層,用來放各種尺寸lcd的參數設置文件如lcd_4_3.c
,通過在lcd.c
調用對應的文件。 - 第四層:LCD控制器設置:
lcd_controller.c
,考慮到拓展性,如果用到不同芯片驅動的lcd時,需要修改太多東西,所以在這一層下分了一個小層,用來放各種芯片的lcd控制器設置文件如s3c2440_lcd_controller.c
,通過在lcd_controller.c
調用對應的文件。
二、設置文件編寫
1、lcd.c文件編寫
#include "lcd.h"
#include "lcd_controller.h"
#define LCD_NUM 10
/* 存儲多種尺寸lcd的結構體數組 */
static p_lcd_params p_array_lcd[LCD_NUM];
/* 存儲被選中的lcd的結構體 */
static p_lcd_params p_g_selected_lcd;
/* 註冊函數:下層代碼調用,把編寫好的lcd_params結構體放入到p_array_lcdr */
int register_lcd(p_lcd_params plcd)
{
int i;
for (i = 0; i < LCD_NUM; i++){
if(!p_array_lcd[i]){
p_array_lcd[i] = plcd;
return i;
}
}
return -1;
}
/* 尋找函數:上層代碼調用,根據名字作爲索引,找到該芯片在p_array_lcd中的位置並返回 */
int select_lcd(char *name)
{
int i;
for (i = 0; i < LCD_NUM; i++){
if ((p_array_lcd[i]) && !(strcmp(p_array_lcd[i]->name, name))){
p_g_selected_lcd = p_array_lcd[i];
return i;
}
}
return -1;
}
/* 得到lcd參數 */
void get_lcd_params(unsigned int *fb_base, int *xres, int *yres, int *bpp)
{
*fb_base = p_g_selected_lcd->frm_base;
*xres = p_g_selected_lcd->xres;
*yres = p_g_selected_lcd->yres;
*bpp = p_g_selected_lcd->bpp;
}
/* lcd使能函數 */
void lcd_enable(void)
{
lcd_controller_enable();
}
/* lcd關閉函數 */
void lcd_disable(void)
{
lcd_controller_disable();
}
/* lcd初始化函數 */
int lcd_init(void)
{
/* 註冊LCD */
lcd_4_3_add();
/* 註冊LCD控制器 */
lcd_controller_add();
/* 選擇某款LCD */
select_lcd("lcd_4.3");
/* 選擇LCD控制器 */
select_lcd_controller("s3c2440_lcdcon");
/* 利用LCD參數,初始化LCD */
lcd_controller_init(p_g_selected_lcd);
}
2、lcd_4_3.c文件編寫
#include "lcd.h"
#define LCD_FB_BASE 0x33c00000
/* lcd參數設置 */
lcd_params lcd_4_3_params = {
.name = "lcd_4.3",
.pin_pol = {
.clk = NORMAL, //normal:下降沿觸發
.hsync = INVERT, //normal:高脈衝
.vsync = INVERT, //normal:高脈衝
.rgb = NORMAL, //normal:對應位爲1
.de = NORMAL, //normal: 高電平傳輸數據
.pwren = NORMAL, //normal: 高電平有效
},
.time_seq = {
/* 水平方向 */
.thp = 41, //thp:水平脈衝寬度,Horizontal Pulse width
.thb = 2, //thb:左邊黑框, Horizontal Back porch
.thf = 2, //thf:右邊黑框, Horizontal Front porch
/* 垂直方向 */
.tvp = 10, //tvp:垂直脈衝寬度,Vertical Pulse width
.tvb = 2, //tvb:上邊黑框, Vertical Back porch
.tvf = 2, //tvf:下邊黑框, Vertical Front porch
.vclk= 9, //MHz
},
.xres = 480,
.yres = 272,
.bpp = 8, //不支持24bpp
.frm_base = LCD_FB_BASE,
};
/* 把該尺寸lcd的結構體註冊到lcd.c的p_array_lcd結構體數組中 */
void lcd_4_3_add(void)
{
register_lcd(&lcd_4_3_params);
}
3、lcd_controller.c文件編寫
#include "lcd_controller.h"
#define LCD_CONTROLLER_NUM 10
/* 存儲多種芯片的lcd控制器的結構體數組 */
static p_lcd_controller p_array_lcd_controller[LCD_CONTROLLER_NUM];
/* 存儲被選中的lcd控制器的結構體 */
static p_lcd_controller p_g_selected_lcd_controller;
/* 註冊函數:下層代碼調用,把編寫好的lcd_controller結構體放入到p_array_lcd_controller */
int register_lcd_controller(p_lcd_controller plcdcon)
{
int i;
for (i = 0; i < LCD_CONTROLLER_NUM; i++){
if(!p_array_lcd_controller[i]){
p_array_lcd_controller[i] = plcdcon;
return i;
}
}
return -1;
}
/* 尋找函數:上層代碼調用,根據名字作爲索引,找到該芯片在p_array_lcd_controller中的位置並返回 */
int select_lcd_controller(char *name)
{
int i;
for (i = 0; i < LCD_CONTROLLER_NUM; i++){
if((p_array_lcd_controller[i]) && !(strcmp(p_array_lcd_controller[i]->name, name))){
p_g_selected_lcd_controller = p_array_lcd_controller[i];
return i;
}
}
return -1;
}
void lcd_controller_add(void)
{
s3c2440_lcd_controller_add();
}
/*
* 對於上層:用來接受不同的LCD參數
* 對於下層:利用參數設置對應的LCD控制器
*/
int lcd_controller_init(p_lcd_params plcdparams)
{
/* 調用對應初始化函數 */
if (p_g_selected_lcd_controller){
p_g_selected_lcd_controller->init(plcdparams);
p_g_selected_lcd_controller->init_palette();
return 0;
}
return -1;
}
/* lcd控制器使能 */
void lcd_controller_enable(void)
{
/* 調用對應初始化函數 */
if (p_g_selected_lcd_controller)
p_g_selected_lcd_controller->enable();
}
/* lcd控制器關閉 */
void lcd_controller_disable(void)
{
/* 調用對應初始化函數 */
if (p_g_selected_lcd_controller)
p_g_selected_lcd_controller->disable();
}
4、s3c2440_lcd_controller.c文件編寫
4.1 寄存器配置
/*
* [17:8] CLKVAL: TFT: VCLK = HCLK / [(CLKVAL+1) x 2]
* CLKVAL = HCLK/VCLK/2-1 = 100/9/2-1 = 4.5 + 0.5 = 5
* [6:5] :11 = TFT LCD panel
* [4:1] : bpp 支持8,16,24bpp
* [0] : LCD video output and the logic enable/disable
*/
int CLKVAL = (double)VCLK/HCLK/2-1 + 0.5;
int BPP = plcparams->bpp == 8 ? 0xb :\
plcparams->bpp == 16 ? 0xc : 0xd;
LCDCON1 = (CLKVAL<<8) | (0x3<<5) | (BPP<<1);
/* [31:24] : VBPD = tvb - 1
* [23:14] : LINEVAL = yres - 1
* [13:6] : VFPD = tvf - 1
* [5:0] : VSPW = tvp - 1
*/
LCDCON2 = ((plcparams->time_seq.tvb - 1)<<24) | \
((plcparams->yres - 1)<<14) | \
((plcparams->time_seq.tvf - 1)<<6) | \
((plcparams->time_seq.tvp - 1)<<0);、
/* [25:19] : HBPT = thb - 1
* 18:8] : HOZBAL = xres - 1
* [7:0] `: HFPD = thf - 1
*/
LCDCON3 = ((plcparams->time_seq.thb - 1)<<19) | \
((plcparams->xres - 1)<<8) | \
((plcparams->time_seq.thf - 1)<<0);
/* [7:0] : HSPW = thp - 1
*/
LCDCON4 = ((plcparams->time_seq.thp - 1)<<0);
/* 用來設置引腳極性, 設置16bpp, 設置內存中象素存放的格式
* [12] : BPP24BL
* [11] : FRM565, 1-565
* [10] : INVVCLK, 0 = The video data is fetched at VCLK falling edge
* [9] : HSYNC是否反轉
* [8] : VSYNC是否反轉
* [7] : INVVD, rgb是否反轉
* [6] : INVVDEN
* [5] : INVPWREN
* [4] : INVLEND
* [3] : PWREN, LCD_PWREN output signal enable/disable
* [2] : ENLEND
* [1] : BSWP
* [0] : HWSWP
*/
pixeplace = plcparams->bpp == 24 ? (0) : |\
plcparams->bpp == 18 ? (1) : |\
(1<<1);
LCDCON5 = (plcparams->pin_pol.clk << 10) |\
(plcparams->pin_pol.hsync << 9) |\
(plcparams->pin_pol.vsync << 8) |\
(plcparams->pin_pol.rgb << 7) |\
(plcparams->pin_pol.de << 6) |\
(plcparams->pin_pol.pwren << 5) |\
(1<<11) | pixeplace;
/*
* [20: 0]:LCDBASEL [21: 1] of end address
*/
addr = plcparams->frm_base + plcparams->xres * plcparams->yres * plcparams->bpp;
addr >>=1;
addr &=0x1fffff;
LCDSADDR2 = addr;
/* framebuffer 地址
* [29:21] :LCDBANK [30:22] of fb
* [20: 0] :LCDBASEU [21: 1] of fb
*/
addr = plcparams->frm_base & ~(1<<31);
LCDSADDR1 = (addr >> 1);
4.2 完整代碼
#include "lcd.h"
#include "lcd_controller.h"
#include "../s3c2440_soc.h"
#define HCLK 100
void jz2440_lcd_pin_init(void)
{
/* 初始化引腳 : 背光引腳 */
GPBCON &= ~0x3;
GPBCON |= 0x01;
/* LCD專用引腳: VD0-VD23 */
GPCCON = 0xaaaaaaaa;
GPDCON = 0xaaaaaaaa;
/* PWREN */
GPGCON |= (3<<8);
}
/* 根據傳入的LCD參數設置LCD控制器 */
void s3c2440_lcd_controller_init(p_lcd_params plcparams)
{
int pixeplace;
unsigned int addr;
jz2440_lcd_pin_init();
/*
* [17:8] : CLKVAL TFT: VCLK = HCLK / [(CLKVAL+1) x 2]
* CLKVAL = HCLK/VCLK/2-1 = 100/9/2-1 = 4.5 + 0.5 = 5
* [6:5] :11 = TFT LCD panel
* [4:1] : bpp 支持8,16,24bpp
* [0] : LCD video output and the logic enable/disable
*
*/
//int CLKVAL = 5;
int CLKVAL = (float)HCLK/plcparams->time_seq.vclk/2-1+0.5;
int BPP = plcparams->bpp == 8 ? 0xb :\
plcparams->bpp == 16 ? 0xc :\
0xd; /* 0xd:24、32bpp */
LCDCON1 = (CLKVAL << 8) | (3 << 5) | (BPP << 1);
/* [31:24] : VBPD = tvb - 1
* [23:14] : LINEVAL = yres - 1
* [13:6] : VFPD = tvf - 1
* [5:0] : VSPW = tvp - 1
*/
LCDCON2 = ((plcparams->time_seq.tvb - 1) << 24) |\
((plcparams->yres - 1) << 14) |\
((plcparams->time_seq.tvf - 1) << 6) |\
((plcparams->time_seq.tvp - 1) << 0);
/* [25:19] : HBPT = thb - 1
* 18:8] : HOZBAL = xres - 1
* [7:0] `: HFPD = thf - 1
*/
LCDCON3 = ((plcparams->time_seq.thb - 1) << 19) |\
((plcparams->xres - 1) << 8) |\
((plcparams->time_seq.thf - 1) << 0);
/* [7:0] : HSPW = thp - 1
*/
LCDCON4 = ((plcparams->time_seq.thp - 1)<<0);
/* 用來設置引腳極性, 設置16bpp, 設置內存中象素存放的格式
* [12] : BPP24BL
* [11] : FRM565, 1-565
* [10] : INVVCLK, 0 = The video data is fetched at VCLK falling edge
* [9] : HSYNC是否反轉
* [8] : VSYNC是否反轉
* [7] : INVVD, rgb是否反轉
* [6] : INVVDEN
* [5] : INVPWREN
* [4] : INVLEND
* [3] : PWREN, LCD_PWREN output signal enable/disable
* [2] : ENLEND
* [1] : BSWP
* [0] : HWSWP
*/
pixeplace = plcparams->bpp == 32 ? (0) : \
plcparams->bpp == 16 ? (1) : \
(1<<1);
LCDCON5 = (plcparams->pin_pol.clk << 10) |\
(plcparams->pin_pol.hsync << 9) |\
(plcparams->pin_pol.vsync << 8) |\
(plcparams->pin_pol.rgb << 7) |\
(plcparams->pin_pol.de << 6) |\
(plcparams->pin_pol.pwren << 5) |\
(1<<11) | pixeplace;
/* framebuffer 地址
* [29:21] :LCDBANK [30:22] of fb
* [20: 0] :LCDBASEU [21: 1] of fb
*/
addr = plcparams->frm_base & ~(1<<31);
LCDSADDR1 = (addr >> 1);
/*
* [20: 0]:LCDBASEL [21: 1] of end address
*/
addr = plcparams->frm_base + plcparams->xres * plcparams->yres * plcparams->bpp/8;
addr >>=1;
addr &=0x1fffff;
LCDSADDR2 = addr;
}
/* 根據傳入的LCD參數設置LCD控制器 */
void s3c2440_lcd_controller_enable(void)
{
/* 背光引腳 :GBP0 */
GPBDAT |= (1<<0);
/* pwren :給LCD提供AVDD */
LCDCON5 |= (1<<3);
/* LCDCON1'BITO':設置LCD控制器是否輸出信號 */
LCDCON1 |= (1<<0);
}
/* 根據傳入的LCD參數設置LCD控制器 */
void s3c2440_lcd_controller_disable(void)
{
/* 背光引腳 :GBP0 */
GPBDAT &= ~(1<<0);
/* pwren :給LCD提供AVDD */
LCDCON5 &= ~(1<<3);
/* LCDCON1'BITO':設置LCD控制器是否輸出信號 */
LCDCON1 &= ~(1<<0);
}
/* 設置調色板之前關閉LCD控制器 */
void s3c2440_lcd_controller_init_palette(void)
{
volatile unsigned int *palette_base = (volatile unsigned int *)0x4D000400;
int i;
int bit = LCDCON1 & (1<<0);
/* LCDCON1'BIT 0 : 設置LCD控制器是否輸出信號 */
if (bit)
LCDCON1 &= ~(1<<0);
for (i = 0; i < 256; i++)
{
/* 低16位 : rgb565 */
*palette_base++ = i;
}
if (bit)
LCDCON1 |= (1<<0);
}
/* 定義結構體變量,存儲各種初始化函數的地址 */
struct lcd_controller s3c2440_lcd_controller = {
.name = "s3c2440_lcdcon",
.init = s3c2440_lcd_controller_init,
.enable = s3c2440_lcd_controller_enable,
.disable = s3c2440_lcd_controller_disable,
.init_palette = s3c2440_lcd_controller_init_palette,
};
/* 把s3c24400_lcd_controller註冊進p_array_lcd_controller中 */
void s3c2440_lcd_controller_add(void)
{
register_lcd_controller(&s3c2440_lcd_controller);
}
三、目的函數編寫
1、畫點framebuffer.c文件編寫
#include "lcd.h"
#include "framebuffer.h"
/* 實現畫點
/* bpp:32位 需要轉換成 16bpp
* 像素的基地址:fb_base + (每行多少字節)(xres*bpp/8)*y + (一行中像素多少字節)(x*bpp/8)
* 獲得LCD參數: fb_base xres bpp
*/
static unsigned int fb_base;
static int xres, yres, bpp;
/* 獲得LCD參數 */
void fb_get_lcd_params(void)
{
get_lcd_params(&fb_base, &xres, &yres, &bpp);
}
/* 把32bitsbpp 轉成 16bitsbpp */
unsigned short convert32bppto16bpp(unsigned int rgb)
{
/* rgb:0x00RRGGBB */
int r = (rgb>>16) & 0xff;
int g = (rgb>>8) & 0xff;
int b = rgb & 0xff;
/* rgb:0x565 */
r = r >> 3;
g = g >> 2;
b = b >> 3;
return ((r<<11) | (g<<5) | b);
}
/* 畫點函數 */
void draw_piont(int x, int y, unsigned int color)
{
unsigned char *pc; /* 8bpp */
unsigned short *pw; /* 16bpp */
unsigned int *pdw; /* 32bpp */
unsigned int pixel_base = fb_base + (xres * bpp / 8) * y + (x * bpp / 8); //計算出單個像素地址
switch (bpp)
{
case 8:
pc = (unsigned char *)pixel_base;
*pc = color;
break;
case 16:
pw = (unsigned short *)pixel_base;
*pw = convert32bppto16bpp(color);
break;
case 32:
pdw = (unsigned int *)pixel_base;
*pdw = color;
break;
}
}
2、畫線、圈geometry.c文件編寫
#include "framebuffer.h"
#include "geometry.h"
/*
* http://blog.csdn.net/p1126500468/article/details/50428613
*/
//-------------畫圓函數。參數:圓心,半徑,顏色----------
// 畫1/8圓 然後其他7/8對稱畫
// ---------------->X
// |(0,0) 0
// | 7 1
// | 6 2
// | 5 3
// (Y)V 4
//
// L = x^2 + y^2 - r^2
void draw_circle(int x, int y, int r, int color)
{
int a, b, num;
a = 0;
b = r;
while(22 * b * b >= r * r) // 1/8圓即可
{
draw_piont(x + a, y - b,color); // 0~1
draw_piont(x - a, y - b,color); // 0~7
draw_piont(x - a, y + b,color); // 4~5
draw_piont(x + a, y + b,color); // 4~3
draw_piont(x + b, y + a,color); // 2~3
draw_piont(x + b, y - a,color); // 2~1
draw_piont(x - b, y - a,color); // 6~7
draw_piont(x - b, y + a,color); // 6~5
a++;
num = (a * a + b * b) - r*r;
if(num > 0)
{
b--;
a--;
}
}
}
//-----------畫線。參數:起始座標,終點座標,顏色--------
void draw_line(int x1,int y1,int x2,int y2,int color)
{
int dx,dy,e;
dx=x2-x1;
dy=y2-y1;
if(dx>=0)
{
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 1/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
draw_piont(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 2/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
draw_piont(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)
if(dx>=dy) // 8/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
draw_piont(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else // 7/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
draw_piont(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
else //dx<0
{
dx=-dx; //dx=abs(dx)
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 4/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
draw_piont(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 3/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
draw_piont(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)
if(dx>=dy) // 5/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
draw_piont(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 6/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
draw_piont(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
}
3、寫字font.c文件編寫
#include "font.h"
#include "framebuffer.h"
/* 根據字母的點陣在LCD上描畫文字 使用linux的8x16點陣 */
extern const unsigned char fontdata_8x16[];
/* 獲得LCD參數 */
static unsigned int fb_base;
static int xres, yres, bpp;
void font_init(void)
{
get_lcd_params(&fb_base, &xres, &yres, &bpp);
}
void fb_print_char(int x, int y, char c, unsigned int color)
{
int i, j;
/* 根據c的ascii碼在fontdata_8x16中得到點陣數據 */
unsigned char *dots = &fontdata_8x16[c * 16];
unsigned char data;
int bit;
/* 根據點陣來設置對應像素的顏色 */
for (j = y; j < y+16; j++){
data = *dots++;
bit = 7;
for (i = x; i < x+8; i++){
if (data & (1 << bit))
draw_piont(i, j, color);
bit--;
}
}
}
void fb_print_string(int x, int y, char *str, unsigned int color)
{
int i, j;
i = 0;
while (str[i]){
if (str[i] == '\n')
y = y + 16;
else if (str[i] == '\r')
x = 0;
else{
fb_print_char(x, y, str[i], color);
x = x + 8;
/* 超出行邊界 */
if (x >= xres){
x = 0;
y = y + 16;
}
}
i++;
}
}
四、測試函數編寫
#include "geometry.h"
#include "font.h"
void lcd_test(void)
{
unsigned int fb_base;
int xres;
int yres;
int bpp;
int x, y;
unsigned short *p;
unsigned int *p2;
unsigned char *p0;
/* 初始化LCD */
lcd_init();
/* 使能LCD */
lcd_enable();
/* 獲得LCD的參數:fb_base,分辨率(xres、yres),bpp */
get_lcd_params(&fb_base, &xres, &yres, &bpp);
fb_get_lcd_params();
font_init();
/* 往framebuf裏寫數據
* bpp:8 , 紅綠藍 palette[xx]
* bpp:16,紅綠藍 565
* bpp:32,紅綠藍 RRGGBB
*/
if (bpp == 8){
/* palette[12] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p0++ = 12;
/* palette[47] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p0++ = 47;
/* palette[88] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p0++ = 88;
/* palette[0] */
p0 = (unsigned char *)fb_base;
for (x = 0; x < xres; x++)
for (y = 0; y < yres; y++)
*p0++ = 0;
}
else if (bpp == 16){
/* Red */
p = (unsigned short *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p++ = 0xf800;
/* Green */
p = (unsigned short *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p++ = 0x7e0;
/* Blue */
p = (unsigned short *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p++ = 0x1f;
/* black */
p = (unsigned short *)fb_base;
for (x = 0; x < xres; x++)
for (y = 0; y < yres; y++)
*p++ = 0;
}
else if (bpp == 32){
/* Red */
p2 = (unsigned int *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p2++ = 0xff0000;
/* Green */
p2 = (unsigned int *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p2++ = 0x00ff00;
/* Blue */
p2 = (unsigned int *)fb_base;
for (x = 0; x < xres ; x++)
for (y = 0; y < yres; y++)
*p2++ = 0x0000ff;
/* black */
p2 = (unsigned int *)fb_base;
for (x = 0; x < xres; x++)
for (y = 0; y < yres; y++)
*p2++ = 0;
}
//delay(1000000);
/* 畫線 */
draw_line(0, 0, xres - 1, 0, 0xff11);
draw_line(xres - 1, 0, xres - 1, yres - 1, 0xffff);
draw_line(0, yres - 1, xres - 1, yres - 1, 0xff00);
draw_line(0, 0, 0, yres - 1, 0xff00ef);
draw_line(0, 0, xres - 1, yres - 1, 0xff45);
draw_line(xres - 1, 0, 0, yres - 1, 0xff07);
//delay(1000000);
/* 畫圓 */
draw_circle(xres/2, yres/2, yres/4, 0xff);
/* 寫字 */
fb_print_string(10, 10, "www.100ask.net\n\r100ask.taobao.com", 0xff);
}