lcd驱动程序如何编写显示图片功能.doc
《lcd驱动程序如何编写显示图片功能.doc》由会员分享,可在线阅读,更多相关《lcd驱动程序如何编写显示图片功能.doc(18页珍藏版)》请在三一文库上搜索。
1、lcd驱动程序如何编写显示图片功能以前没有写Lcd驱动程序,现在开始做项目了,才发现Lcd驱动程序必须认真学习,我总结所以驱动中LCD和网卡驱动是最难的,LCD主要是需要配置的寄存器太多了,还是老规矩先上代码。内核版本:linux-3.4.2 lcd:4.3上代码之前我得讲解一些基本的知识点,LCD驱动我们只需要写硬件这一块的代码就可以了,下面有三个函数内核已经帮我们写好了,我们只需要调用就可以了,这几个函数实现了内核层和应用成数据的传递,有兴趣的朋友去分析一下源码,我里驱动写好了我们可以选择动态加载驱动或者直接静态编译进内核,这个的区别在前文中我讲解的非常清楚了,希望朋友一定要去看一下,Li
2、nux驱动静态编译和动态编译方法详解这个代码相对有点复杂,朋友们一定要仔细分析。驱动程序如下:lcd.c文件如下:#include linux/module.h#include linux/kernel.h#include linux/errno.h#include linux/string.h#include linux/mm.h#include linux/slab.h#include linux/delay.h#include linux/fb.h#include linux/init.h#include linux/dma-mapping.h#include linux/interru
3、pt.h#include linux/workqueue.h#include linux/wait.h#include linux/platform_device.h#include linux/clk.h#include asm/io.h#include asm/uaccess.h#include asm/div64.h#include asm/mach/map.hstaTIc int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,unsigned int green, unsigned int blue,unsigned
4、int transp, struct fb_info *info);struct lcd_regs unsigned long lcdcon1;unsigned long lcdcon2;unsigned long lcdcon3;unsigned long lcdcon4;unsigned long lcdcon5;unsigned long lcdsaddr1;unsigned long lcdsaddr2;unsigned long lcdsaddr3;unsigned long redlut;unsigned long greenlut;unsigned long bluelut;un
5、signed long reserved9;unsigned long dithmode;unsigned long tpal;unsigned long lcdintpnd;unsigned long lcdsrcpnd;unsigned long lcdintmsk;unsigned long lpcsel;staTIc struct fb_ops s3c_lcdfb_ops = .owner = THIS_MODULE,.fb_setcolreg = s3c_lcdfb_setcolreg,.fb_fillrect = cfb_fillrect, /* 这三个函数是在内核自带的,动态加载
6、时候,需要把这个三个编译成模块当吧驱动程序编译进内核时候,就不用去管着三个函数 */val |= chan_to_field(blue,info-var.blue);/(u32 *)(info-pseudo_palette)regno = val;pseudo_paletteregno = val;return 0;staTIc int lcd_init(void)/* 1. 分配一个fb_info */s3c_lcd = framebuffer_alloc(0, NULL);/* 2. 设置 */* 2.1 设置固定的参数 */strcpy(s3c_lcd-fix.id, mylcd);s3
7、c_lcd-fix.smem_len = 480*272*16/8;s3c_lcd-fix.type = FB_TYPE_PACKED_PIXELS;s3c_lcd-fix.visual = FB_VISUAL_TRUECOLOR; /* TFT */s3c_lcd-fix.line_length = 480*2;/* 2.2 设置可变的参数 */s3c_lcd-var.xres = 480;s3c_lcd-var.yres = 272;s3c_lcd-var.xres_virtual = 480;s3c_lcd-var.yres_virtual = 272;s3c_lcd-var.bits_
8、per_pixel = 16;/* RGB:565 */s3c_lcd-var.red.offset = 11;s3c_lcd-var.red.length = 5;s3c_lcd-var.green.offset = 5;s3c_lcd-var.green.length = 6;s3c_lcd-var.blue.offset = 0;s3c_lcd-var.blue.length = 5;s3c_lcd-var.acTIvate = FB_ACTIVATE_NOW;/* 2.3 设置操作函数 */s3c_lcd-fbops = s3c_lcdfb_ops;/* 2.4 其他的设置 */s3c
9、_lcd-pseudo_palette = pseudo_palette;/s3c_lcd-screen_base = ; /* 显存的虚拟地址 */s3c_lcd-screen_size = 480*272*16/8;/* 3. 硬件相关的操作 */* 3.1 配置GPIO用于LCD */gpbcon = ioremap(0x56000010, 8);gpbdat = gpbcon+1;gpccon = ioremap(0x56000020, 4);gpdcon = ioremap(0x56000030, 4);gpgcon = ioremap(0x56000060, 4);*gpccon
10、= 0xaaaaaaaa; /* GPIO管脚用于VD7:0,LCDVF2:0,VM,VFRAME,VLINE,VCLK,LEND */*gpdcon = 0xaaaaaaaa; /* GPIO管脚用于VD23:8 */*gpbcon = (3); /* GPB0设置为输出引脚 */*gpbcon |= 1;*gpbdat = 1; /* 输出低电平 */*gpgcon |= (38); /* GPG4用作LCD_PWREN */* 3.2 根据LCD手册设置LCD控制器, 比如VCLK的频率等 */lcd_regs = ioremap(0x4D000000, sizeof(struct lc
11、d_regs);/* bit17:8: VCLK = HCLK / (CLKVAL+1) x 2, LCD手册P14* 10MHz(100ns) = 100MHz / (CLKVAL+1) x 2* CLKVAL = 4* bit6:5: 0b11, TFT LCD* bit4:1: 0b1100, 16 bpp for TFT* bit0 : 0 = Disable the video output and the LCD control signal.*/lcd_regs-lcdcon1 = (48) | (35) | (0x0c1);#if 1/* 垂直方向的时间参数* bit31:24
12、: VBPD, VSYNC之后再过多长时间才能发出第1行数据* LCD手册 T0-T2-T1=4* VBPD=3* bit23:14: 多少行, 320, 所以LINEVAL=320-1=319* bit13:6 : VFPD, 发出最后一行数据之后,再过多长时间才发出VSYNC* LCD手册T2-T5=322-320=2, 所以VFPD=2-1=1* bit5:0 : VSPW, VSYNC信号的脉冲宽度, LCD手册T1=1, 所以VSPW=1-1=0*/lcd_regs-lcdcon2 = (124) | (27114) | (16) | (9);/* 水平方向的时间参数* bit25:
13、19: HBPD, VSYNC之后再过多长时间才能发出第1行数据* LCD手册 T6-T7-T8=17* HBPD=16* bit18:8: 多少列, 240, 所以HOZVAL=240-1=239* bit7:0 : HFPD, 发出最后一行里最后一个象素数据之后,再过多长时间才发出HSYNC* LCD手册T8-T11=251-240=11, 所以HFPD=11-1=10*/lcd_regs-lcdcon3 = (119) | (4798) | (1);/* 水平方向的同步信号* bit7:0 : HSPW, HSYNC信号的脉冲宽度, LCD手册T7=5, 所以HSPW=5-1=4*/lc
14、d_regs-lcdcon4 = 40;#elselcd_regs-lcdcon2 = S3C2410_LCDCON2_VBPD(5) | S3C2410_LCDCON2_LINEVAL(319) | S3C2410_LCDCON2_VFPD(3) | S3C2410_LCDCON2_VSPW(1);lcd_regs-lcdcon3 = S3C2410_LCDCON3_HBPD(10) | S3C2410_LCDCON3_HOZVAL(239) | S3C2410_LCDCON3_HFPD(1);lcd_regs-lcdcon4 = S3C2410_LCDCON4_MVAL(13) | S3C
15、2410_LCDCON4_HSPW(0);#endif/* 信号的极性* bit11: 1=565 format* bit10: 0 = The video data is fetched at VCLK falling edge* bit9 : 1 = HSYNC信号要反转,即低电平有效* bit8 : 1 = VSYNC信号要反转,即低电平有效* bit6 : 0 = VDEN不用反转* bit3 : 0 = PWREN输出0* bit1 : 0 = BSWP* bit0 : 1 = HWSWP 2440手册P413*/lcd_regs-lcdcon5 = (111) | (010) |
16、(19) | (18) | (10);/* 3.3 分配显存(framebuffer), 并把地址告诉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) (330);lcd_regs-lcdsaddr2 = (s3c_lcd-fix.smem_start + s3c_lcd-fix.smem_len) 1) 0x1ff
17、fff;lcd_regs-lcdsaddr3 = (480*16/16); /* 一行的长度(单位: 2字节) */s3c_lcd-fix.smem_start = xxx; /* 显存的物理地址 */* 启动LCD */lcd_regs-lcdcon1 |= (10); /* 使能LCD控制器 */lcd_regs-lcdcon5 |= (13); /* 使能LCD本身 */*gpbdat |= 1; /* 输出高电平, 使能背光 */* 4. 注册 */register_framebuffer(s3c_lcd);return 0;static void lcd_exit(void)unre
18、gister_framebuffer(s3c_lcd);lcd_regs-lcdcon1 = (10); /* 关闭LCD本身 */*gpbdat = 1; /* 关闭背光 */dma_free_writecombine(NULL, s3c_lcd-fix.smem_len, s3c_lcd-screen_base, s3c_lcd-fix.smem_start);iounmap(lcd_regs);iounmap(gpbcon);iounmap(gpccon);iounmap(gpdcon);iounmap(gpgcon);framebuffer_release(s3c_lcd);modul
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- lcd 驱动程序 如何 编写 显示 图片 功能
链接地址:https://www.31doc.com/p-3253662.html