韋東山第二期視頻之心得體會

韋東山第二期視頻之心得體會

姓名:張猛

引用自:http://blog.csdn.net/u013985662/article/details/45575777

【嵌牛導讀】:最近一直在收看韋東山老師的嵌入式視頻,收獲頗豐。第二期主要是關于一些設備驅動的編寫示例,從最基礎的按鍵驅動、LED驅動到復雜的LCD、觸摸屏、網卡、以及各種總線驅動。今天主要對之前學習的LCD驅動做一個學習心得,將學習中的一些問題和收獲和大家一起分享。

【嵌牛鼻子】:嵌入式 驅動LED

【嵌牛提問】:嵌入式學習過程中應該注意的坑,應該怎么樣子學習提高效率

【嵌牛正文】:

我的開發板的Linux系統是linux-2.6.32.2,和我在Ubuntu虛擬機中的專用于編譯模塊文件的內核源碼包一致(在剛開始因為兩者的版本不一致導致在mini2440中加載.ko文件一直都報錯:"invalid module format",也是個印象深刻的教訓)。我的mini2440的LCD是滕寶的TD35,雖然和視頻中的JZ2440不一樣,但是大同小異,具體步驟如下。

首先在模塊驅動程序中的初始化函數中進行一些基礎操作,包括fb_info結構體的分配、設置LCD的固定參數(fb_info結構體中的fb_fix_screeninfo結構體實例fix)、設置可變的參數(fb_info中的fb_var_screeninfo結構體實例var)、設置操作函數(fb_ops結構體)、處理一些硬件相關的操作(如配置用于LCD的GPIO引腳)、以及最后的注冊工作等等。

在這些韋東山老師整理出來的配置步驟中,我主要與大家分享下面幾點:

1、第二步設置固定參數中有幾點要格外注意。第一,fb_info.fix結構體中的成員smem_len和line_length變量的單位都是字節,很多時候單位是位的話要記得轉換為字節。第二,成員visual要設為真彩色(FB_VISUAL_TRUECOLOR)。第三,成員smem_len表示了圖像大小,要查看數據手冊,單位同樣也是字節。

2、第三步設置可變參數也有幾點要注意。第一,var的成員xres表示的是一行的像素點,yres表示一列的像素點,而虛擬像素點xres_virtual和yres_virtual只需和xres,yres取相同值即可。第二,我的像素深度是16位,而初始像素深度為24位,其中RGB各占一個字節,但在16位像素中,RGB分別占5、6、5位,8位取高5位或高6位實現裁剪到5位或6位。

3、第四步操作函數中記得加上調色板相關的函數,在16位像素深度的圖像處理中要用到調色板(palette)。將16位的像素值作為調色板數組的索引值,然后從數據類型為24位或32位的調試板中取色,這樣達到了要求的像素深度。

4.第五步中主要是設置LCD相關的寄存器,包括LCDCON1至LCDCON5,以及LCDSADDR1到LCDSADDR3。這些寄存器的配置既需要閱讀s3c2440的數據手冊,也需要閱讀LCD的數據手冊,尤其的行信號的場信號的時序圖,通過在其參數范圍內進行調整,直到屏幕上出現理想的視圖。

前面這些步驟就實現了基礎的配置了,具體的代碼如下:

static int __init lcd_init(void)

{

/*1.分配一個fb_info結構體*/

s3c_lcd=framebuffer_alloc(0,NULL);

/*2.1設置固定的參數*/

strcpy(s3c->fix.id,"mylcd");

//s3c->fix.smem_start之后再設

s3c_lcd.fix.smem_len=320*240*16/8;

s3c_lcd.fix.type=FB_TYPE_PACKED_PIXELS;

s3c_lcd.fix.visual=FB_VISUAL_TRUECOLOR;

s3c_lcd.fix.line_length=240*2;

/*2.2設置可變參數*/

s3c_lcd->var.xres=240;

s3c_lcd->var.yres=320;

s3c_lcd->var.xres_virtual=240;

s3c_lcd->var.yres_virtual=320;

s3c_lcd->var.bits_per_pixel=16;

s3c_lcd->var.red.offset=11;

s3c_lcd->var.red.length=5;

s3c_lcd->var.green.offset=5;

s3c_lcd->var.red.length=6;

s3c_lcd->var.blue.offset=0;

s3c_lcd->var.red.length=5;

s3c_lcd->var.active=FB_ACTIVATE_NOW;

/**設置操作函數***/

s3c_lcd->fbops=&s3c_lcdfb_ops;

/**其他設置*****/

s3c_lcd->pseudo_palette=pseudo_palette;//調色板

s3c_lcd->screen_size=240*320*2;

/**3.硬件相關的操作*******/

/*配置GPIO用于LCD*****/

GPCCON=ioremap(0x56000010, 4);

GPDCON=ioremap(0x56000030,4);

GPGCON=ioremap(0x56000060,4);

*GPCCON=0xaaaaaaaa;

*GPDCON=0xaaaaaaaa;

//配置LCD背光使能口

//GPGCON做LCD_POWER使能LCD電源口

*GPGCON | =(3<<8);

/**3.2根據LCD手冊設置LCD控制器*****/

lcd_regs=ioremap(0x4D000000,sizeof(struct lcd_regs));

lcd_regs->lcdcon1=(6<<8)|(3<<5)|(0x0c<<1);

lcd_regs->lcdcon2=(3<<24)|(319<<14)|(1<<6)|(0<<0);

lcd_regs->lcdcon3=(19<<19)|(239<<8)|(9<<0);

lcd_regs->lcdcon4=9;

lcd_regs->lcdcon5=(1<<11)|(0<<10)|(1<<9)|(1<<8)|(1<<0);

/*3.3分配顯存,并把地址告訴LCD控制器******/

s3c_lcd->screen_base=dma_alloc_writecombine(NULL,s3c_lcd->fix.smem_len,&s3c_lcd->fix.smem_start,GFP_KERNEL)

lcd_regs->lcdsaddr1=(s3c_lcd->fix.smem_start>>1)&~(3<<30);

lcd_regs->lcdsaddr2=((s3c_lcd->fix.smem_start+s3c_lcd->fix.smem.len)>>1)&0x1fffff;

lcd_regs->lcdsaddr3=(240*16/16);

//啟動LCD

lcd_regs->lcdcon1 |=(1<<0);

lcd_regs->lcdcon5 |=(1<<3);

/**4.注冊****/

register_framebuffer(s3c_lcd);

}

5.在完成這些初始化過程之后,就是自己發揮的部分了,可以通過讀取HZK16文件來實現漢字庫的導入來實現漢字,也可以通過Linux源碼包的ASCII庫文件來來實現顯示字母和數字等常用標識。下面是我的部分字庫讀取函數,代碼如下:

void lcd_show_ascii(unsigned char*fbmem_start,int x,int y,unsigned char c,unsigned int forecolor,int backcolor)

{

//指向內核中已定義的ASCII數組

unsigned char *dots=(unsignedchar *)&fontdata_8x16[c*16];

int i,b;

unsigned char by;

for(i=0;i<16;i++)//一個字母占16個字節共16*8位

{

by=dots[i];

for(b=7;b>=0;b--)//16表示行數,8表示列數

{

if(by&(1<

{

lcd_show_point(fbmem_start,x+7-b,y+i,forecolor);

}

else//否則為背景色,即不顯示

{

lcd_show_point(fbmem_start,x+7-b,y+i,backcolor);

}

}

}

}

這整個過程有些復雜,但只需按部就班加上對實際情況的具體分析,相信就可以實現想要的效果了。當實現之后,就可以利用這個LCD屏幕來作為自己顯示的又一個終端了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容