参考:http://www.cnblogs.com/lifexy/p/7604011.html

在上一节LCD层次分析时,得出写个LCD驱动入口函数,需要以下4步:

1)分配一个fb_info结构体:framebuffer_alloc();

2)设置fb_info;

3)设置硬件相关的操作;

4)使能LCD,并注册fb_info:register_framebuffer();

本节需要用到的函数:

函数dma_alloc_writecombine():(分配显存)

void * dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);//分配DMA缓存区给现存
//返回值为:申请到的DMA缓冲区的虚拟地址,若为NULL,表示分配失败,则需要使用dma_free_writecombine()释放内存,避免内存泄漏
//参数如下://*dev:指针,这里填0,表示这个申请的缓冲区里没有内容//size:分配的地址大小(字节单位)//*handle:申请到的物理起始地址//gfp:分配出来的内存参数,标志定义在<linux/gfp.h>,常用标志如下://GFP_ATOMIC  用来从中断处理和进程上下文之外的其它代码中分配内存.从不睡眠//GFP_KERNEL  内核内存的正常分配,可能睡眠//GFP_USER 用来为用户空间页来分配内存;它可能睡眠

分配一段DMA缓存区,分配出来的内存会禁止cache缓存(因为DMA传输不需要CPU)

它和dm_alloc_coherent()函数相似,不过dma_alloc_writecombine()函数是分配出来的内存会禁止cache缓存以及禁止写入缓冲区

---------------------------------------------------------------------------------------

函数dma_free_writecombine():(释放显存)

void dma_free_writecombine(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle);
//cpu_addr:虚拟地址
//handle:物理地址

释放DMA缓冲区,dev和size参数和上面的函数一样

---------------------------------------------------------------------------------------

函数frambuffer_alloc():(申请fb_info结构体)

struct fb_info *framebuffer_alloc(size_t size, struct device *dev)//申请一个fb_info结构体
//size:额外的内存(里面放私有数据private)
//*dev:指针,这里填写NULL,表示这个申请的结构体没有内容

---------------------------------------------------------------------------------------

函数register_frambuffer()和函数frambuffer_release():

int register_framebuffer(struct fb_info *fb_info)//向内核中注册fb_info结构体,若内存不够,注册失败会返回负数
void framebuffer_release(struct fb_info *info)//注销内核中fb_info结构体

---------------------------------------------------------------------------------------

本节需要用到的结构体:

fb_info结构体如下:

struct fb_info {int node;int flags;struct fb_var_screeninfo var; //可变的参数struct fb_fix_screeninfo fix;    //固定的参数
… …struct fb_ops *fbops;    //操作函数
… …char __iomem *screen_base;   //显存虚拟起始地址unsigned long screen_size;    //显存虚拟地址长度void *pseudo_palette;     /* Fake palette of 16 colors */ //假的16色调色板,里面存放了16色的数据,可以通过8bpp数据来找到调色板里面的16色颜色索引值,模拟出16色颜色来,节省内存,不需要的话就指向一个不用的数组即可
};

其中操作函数fb_info->fbops结构体写法如下:

static struct fb_ops s3c_lcdfb_ops = {.owner        = THIS_MODULE,//可以参考\drivers\video\Atmel_lcdfb.c.fb_setcolreg  = s3c_lcdfb_setcolreg, //设置调色板fb_info->pseudo_palette,自己构造该函数//下面三个函数是对显存的操作.fb_fillrect    = cfb_fillrect,    //填充一个矩形,用/driver/video/cfbfillrect.c里的函数即可.fb_copyarea = cfb_copyarea,    //拷贝一个区域,用/driver/video/cfbcopyarea.c里的函数即可.fb_imageblit    = cfb_imageblit,   //图形填充,用/driver/video/imageblit.c里的函数即可
};

固定的参数fb_info->fix 结构体如下:

struct fb_fix_screeninfo {char id[16];           //id名字unsigned long smem_start; //framebuffer物理起始地址__u32 smem_len;          //framebuffer长度,字节为单位__u32 type;         //lcd类型,默认值为0即可__u32 type_aux;           //附加类型,为0__u32 visual;           //画面设备,常见参数如下
// FB_VISUAL_MONO01     0   单色,0:白色,1:黑色
// FB_VISUAL_MONO10     1   单色,1:黑色,1:白色
// FB_VISUAL_TRUECOLOR      2   真彩(TFT:真彩)
// FB_VISUAL_PSEUDOCOLOR    3   伪彩
// FB_VISUAL_DIRECTCOLOR    4   直彩__u16 xpanstep;           /* 如果没有硬件panning就赋值为0 */__u16 ypanstep;         /* 如果没有硬件panning就赋值为0 */__u16 ywrapstep;        /* 如果没有硬件panning就赋值为0 */__u32 line_length;      /* 一行的字节数,例:(RGB565)240*320,那么这里就等于240*16/8 *//* 以下成员都可以不需要 */unsigned long mmio_start;   /*内存映射IO的起始地址,用于应用层直接访问寄存器,可以不需要 */__u32 mmio_len;            /* 内存映射IO的长度,可以不需要 */__u32 accel;            /* Indicate to driver which *//*  specific chip/card we have    */__u16 reserved[3];        /* Reserved for future compatibility */
};

可变的参数fb_info->var结构体如下:

struct fb_var_screeninfo {__u32 xres;            /* 可见屏幕一行有多少个像素点 */__u32 yres;          /* 可见屏幕一列有多少个像素点 */__u32 xres_virtual;      /* 虚拟屏幕一行有多少个像素点 */__u32 yres_virtual;      /* 虚拟屏幕一列有多少个像素点 */__u32 xoffset;           /* 虚拟到可见屏幕之间的行偏移,若可见和虚拟的分频率一样,就直接设为0 */__u32 yoffset;         /* 虚拟到可见屏幕之间的列偏移 */__u32 bits_per_pixel;        /* 每个像素的位数即BPP,比如:RGB565,则填入16 */__u32 grayscale;        /* 非0时,指的是灰度,真彩直接填0即可 */struct fb_bitfield red;       //fb缓存的R位域,fb_bitfield结构体成员如下:
//  __u32 offset;           区域偏移值,比如RGB565中的R,就在第11位
//  __u32 length;           区域长度,比如RGB565的R,共有5位
//  __u32 msb_right;        msb_right==0,表示数据左边最大,msb_right!=0,表示数据右边最大
};struct fb_bitfield green; /* fb缓存的G位域 */struct fb_bitfield blue;  /* fb缓存的B位域 *//* 以下参数都可以不填,默认为0 */struct fb_bitfield transp; /* 透明度,不需要填0即可 */    __u32 nonstd;           /* !=0表示非标准像素格式 */__u32 activate;          /* 设为0即可 */__u32 height;            /* 外设高度(单位mm),一般不需要填 */__u32 width;         /* 外设宽度(单位mm),一般不需要填 */__u32 accel_flags;       /* 过时的参数,不需要填 *//* 除了pixclock本身外,其它的都以像素时钟为单位 */__u32 pixclock;           /* 像素时钟(皮秒) */__u32 left_margin;        /* 行切换,从同步到绘图之间的延迟 */__u32 right_margin;     /* 行切换,从绘图到同步之间的延迟 */__u32 upper_margin;     /* 帧切换,从同步到绘图之间的延迟 */__u32 lower_margin;     /* 帧切换,从绘图到同步之间的延迟 */__u32 hsync_len;        /* 水平同步的长度 */__u32 vsync_len;       /* 垂直同步的长度 */__u32 sync;            /* see FB_SYNC_*        */__u32 vmode;          /* see FB_VMODE_*       */__u32 rotate;         /* angle we rotate counter clockwise */__u32 reserved[5];       /* 保留 */
};

1、写驱动程序:
(写驱动可以参考自带的LCD平台驱动drivers/video/s3c2410fb.c)
(LCD控制寄存器设置:参考之前的LCD裸机驱动:(硬件设置)https://blog.csdn.net/xiaodingqq/article/details/80724190)

1.1 步骤如下:
在驱动init入口函数中:

(1)分配一个fb_info结构体

(2)设置fb_info

(2.1)设置固定的参数fb_info->fix

(2.2)设置可变的参数fb_info->var

(2.3)设置操作函数fb_info->fbops

(2.4)设置fb_info其它的成员

(3)设置硬件相关的操作

(3.1)配置LCD引脚

(3.2)根据LCD手册设置LCD控制器

(3.3)分配显存(framebuffer),把地址告诉LCD控制器和fb_info

(4)开启LCD,并注册fb_info:register_framebuffer()

(4.1)直接在init函数中开启LCD(后面讲到电源管理,再来优化)

控制LCDCON5允许PWREN信号,

然后控制LCDCON1输出PWREN信号,

输出GPB0高电平来开背光,

(4.2)注册fb_info

在驱动exit出口函数中:

(1)卸载内核中的fb_info

(2)控制LCDCON1关闭PWREN信号,关背光灯,iounmap注销地址

(3)释放DMA缓存地址dma_free_writecombine()

(4)释放注册的fb_inifo

1.2具体的代码如下:

#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/interrupt.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.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/fb.h>static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,  //设置调色板unsigned int green, unsigned int blue,unsigned 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;unsigned long reserved[9]; //保留9个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,        //填充一个矩形.fb_copyarea    = cfb_copyarea,        //拷贝一个区域.fb_imageblit   = cfb_imageblit,   //图形填充
};static struct fb_info *s3c_lcd;
static volatile unsigned long *gpbcon;
static volatile unsigned long *gpbdat;
static volatile unsigned long *gpccon;
static volatile unsigned long *gpdcon;
static volatile unsigned long *gpgcon;
static volatile struct lcd_regs* lcd_regs;
static u32 pseudo_palette[16];  //假的调色板,调色板数组,被fb_info->pseudo_palette调用/* from pxafb.c */
static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{chan &= 0xffff;chan >>= 16 - bf->length;return chan << bf->offset;
}static int s3c_lcdfb_setcolreg(unsigned int regno, unsigned int red,   //设置调色板unsigned int green, unsigned int blue,unsigned int transp, struct fb_info *info)
{unsigned int val;if (regno > 16)    //regno哪一个调色板return 1;/* 用read,green,blue三原色构造出val */val = chan_to_field(red,   &info->var.red);val |= chan_to_field(green, &info->var.green);val |= chan_to_field(blue,  &info->var.blue);//((u32 *)(info->pseudo_palette))[regno] = val;pseudo_palette[regno] = val; //放到调色板数组中return 0;
}static int lcd_init(void)
{/* 1. 分配一个fb_info *///第一个参数大小:size表示分配额外的空间(里面放私有数据private)s3c_lcd = framebuffer_alloc(0, NULL);  //不分配额外的空间/* 2.  设置 *//* 2.1 设备固定的参数fix */strcpy(s3c_lcd->fix.id, "mylcd");//名字ids3c_lcd->fix.smem_len    = 480*272*16/8;  //显存的长度(需要看LCD手册)分辨率resolution:480*272,RGB(Bit):565,一个像素16位s3c_lcd->fix.type        = FB_TYPE_PACKED_PIXELS;    //在fb.h,使用默认值(值为0)s3c_lcd->fix.visual      = FB_VISUAL_TRUECOLOR;   /* visual视觉的 TFTLCD:真彩色 */s3c_lcd->fix.line_length = 480*2;  //一行480个像素,一个像素16位(2个字节)/* 2.2 设置可变的参数var */s3c_lcd->var.xres           = 480;  //x方向的分辨率s3c_lcd->var.yres           = 272; //y方向的分辨率s3c_lcd->var.xres_virtual   = 480; //电脑桌面点击右键,设置分辨率(虚拟分辨率)s3c_lcd->var.yres_virtual   = 272;    //虚拟分辨率s3c_lcd->var.bits_per_pixel = 16;    //每个像素用多少位/* RGB:565 */s3c_lcd->var.red.offset     = 11;    //红色的偏移值从bit11开始s3c_lcd->var.red.length     = 5;    //红色的长度为5位s3c_lcd->var.green.offset   = 5;  //绿色的偏移值从bit5开始s3c_lcd->var.green.length   = 6; //绿色的长度为6位s3c_lcd->var.blue.offset    = 0;  //蓝色的偏移值从bit0开始s3c_lcd->var.blue.length    = 5; //蓝色的长度为5位s3c_lcd->var.activate       = FB_ACTIVATE_NOW;    //使用默认值/* 2.3 设置操作函数fbops       */s3c_lcd->fbops                 = &s3c_lcdfb_ops;/* 2.4 其他的设置 */s3c_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);  //映射8个字节gpbdat = gpbcon+1;    //指针加1相当于加4gpccon = ioremap(0x56000020, 4);    //一页一页地映射的,所以size写4或者1024都可以gpdcon = ioremap(0x56000030, 4);gpgcon = ioremap(0x56000060, 4);//参考以前的裸机程序lcddrv.c*gpccon  = 0xaaaaaaaa;   /* GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND */*gpdcon  = 0xaaaaaaaa;   /* GPIO管脚用于VD[23:8] */*gpbcon &= ~(3);  /* GPB0(KEYBOARD)设置为输出引脚 */*gpbcon |= 1;*gpbdat &= ~1;    /* 输出低电平,背光先不开启 */*gpgcon |= (3<<8); /* GPG4用作LCD_PWREN *//* 3.2 根据LCD手册设置LCD控制器,比如VCLK的频率等 *///映射所有的lcdconX控制器lcd_regs = ioremap(0x4D000000, sizeof(struct lcd_regs));/* bit[17:8]: VCLK = HCLK / [(CLKVAL+1) x 2]  ,具体可看LCD手册*    10MHz(100ns) = 100MHz / [(CLKVAL+1) x 2]*   CLKVAL = 4* bit[6:5]:0b11,TFT LCD* bit[4:1]:0b1100 16bpp for TFT (每个像素用16位来表示)* bit[0]  :0 = Disable the video output and the LCD control signal. */lcd_regs->lcdcon1 = (4<<8) | (3<<5) | (0x0c<<1); /* 垂直方向的时间参数* bit[31:24]:VBPD,VSYNC之后再过多长时间才能发出第1行数据*             LCD手册 tvb=2*             所以VBPD=1* bit[23:14]:多少行,272行,所以LINEVAL=272-1=271* bit[13:6] :VFPD,发出最后一行数据之后,再过多长时间才发出VSYNC*             LCD手册 tvf=2,所以VFPD=2-1=1* bit[5:0]  :VSPW,VSYC信号的脉冲宽度,LCD手册 tvp=10,所以VSPW=10-1=9*/lcd_regs->lcdcon2 = (1<<24) | (271<<14) | (1<<6) | (9);/* 水平方向的时间参数* bit[25:19]:HBPD,HSYNC之后再过多长时间才能发出第1个像素的数据*             LCD手册 thb=2*             所以HBPD=1* bit[18:8]: 多少列,480列,所以LINEVAL=480-1=479* bit[7:0] : HFPD,发出最后一行里,最后一个像素之后,再过多长时间才发出HSYNC*             LCD手册 thf=2,所以HFPD=2-1=1*/lcd_regs->lcdcon3 = (1<<19) | (479<<8) | (1);/* 水平方向的同步信号* bit[7:0] : HSPW,HSYC信号的脉冲宽度,LCD手册 thp=41,所以HSPW=41-1=40*/lcd_regs->lcdcon4 = 40;/* 信号的极性 * bit[11]:1=565 format* bit[10]:0 = The video data is fetched at VCLK falling edge 在下降沿取数据* bit[9]:1 = HSYNC信号要反转,即低电平有效(水平方向的同步信号,在2440与LCD手册相反,所以要反转)* bit[8]:1 = VSYNC信号要反转,即低电平有效* bit[6]:0 = VDEN不用反转(数据引脚VD0~VD23)* bit[3]:0 = PWREN输出低电平* bit[1]:0 = BSWAP* bit[0]:1 = HWSWP 看2440手册 P413*/lcd_regs->lcdcon5 = (1<<11) | (0<<10) | (1<<9) | (1<<8) | (1<<0);/* 3.3 分配显存(frambuffer,在SDRAM内存划分出来的),并把地址告诉LCD控制器 *///第3个参数存放物理地址,返回值为这块内存的虚拟地址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);   //第0位和最高位忽略,保存缓冲起始地址A[30:1]lcd_regs->lcdsaddr2 = ((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1) & 0x1fffff;   //结束地址=开始地址+长度,只关心21位,保存缓冲结束地址A[21:1]lcd_regs->lcdsaddr3 = (480*16/16);    /* 一行的长度(单位:半字,就是2个字节) *///s3c_lcd->fix.smem_start = xxx;  //显存的物理地址/* 启动LCD */lcd_regs->lcdcon1 |= (1<<0);    /* 使能LCD控制器 */lcd_regs->lcdcon5 |= (1<<3);    /* 使能LCD本身 */*gpbdat |= 1; /* 原来输出低电平,现在输出高电平,使能背光灯 *//* 4. 注册 */register_framebuffer(s3c_lcd);return 0;
}static void lcd_exit(void)
{unregister_framebuffer(s3c_lcd);lcd_regs->lcdcon1 &= ~(1<<0);    /* 关闭LCD本身,省电 */*gpbdat &= ~1;  /* 关闭背光灯 */dma_free_writecombine(NULL, s3c_lcd->fix.smem_len, s3c_lcd->screen_base, s3c_lcd->fix.smem_start);//释放显存,第三个参数cpu地址,就是虚拟地址,第四个参数,handle物理地址iounmap(lcd_regs);iounmap(gpbcon);iounmap(gpccon);iounmap(gpdcon);iounmap(gpgcon);framebuffer_release(s3c_lcd); //释放掉fb_info的sc3_lcd结构体
}module_init(lcd_init);
module_exit(lcd_exit);
MODULE_LICENSE("GPL");

2、重新编译内核,去掉原来的LCD驱动程序

在内核代码目录下,输入命令make menuconfig,进入menu菜单重新设置内核参数:

进入-> Device Drivers-> Graphics support<M> S3C2410 LCD framebuffer support

(上面“<*>s3c2410 LCD framebuffer support”是之前自带的驱动程序,这里去掉后以<M>模块方式编译进内核)

(<M>模块方式编译进内核)

然后make uImage编译内核(如果生成的是zImage,而不是uImage,可以点击这里)

编译好的uImage 在 arch/arm/boot/uImage

make modules编译模块(编译好的3个模块在drivers/video

cp arch/arm/boot/uImage /work/nfsroot
cp drivers/video cfb*.ko /work/nfsroot

为什么要编译模块?

因为LCD驱动相关的文件也没有编进内核,而fb_ops里的成员fb_fillrect(),fb_copyarea(),fb_imageblit()用的都是drivers/video下面的3个文件所以需要这3个的.ko模块。

3、使用新的uImage来启动开发板

(3.1) 启动开发板,进入uboot的菜单界面,然后输入q退出菜单,进入命令行。

(3.2) 打开tftpd32.exe软件,选择需要传输文件的目录,以及PC机(服务器)的ip地址。

(3.3) 在uboot的命令行,输入命令tftp 30000000 uImage(把在PC机的uImage传到地址30000000上(SDRAM))。

(3.4) 输入bootm 30000000,开发板从地址30000000开始启动内核。

4、挂载驱动

(4.1) 把编译好的LCD驱动模块和drivers/video里的3个.ko模块放入nfs文件系统(/work/nfsroot)中,

(4.2) 使用nfs网络文件系统挂载,输入命令:

mount -t nfs -o intr,nolock,rsize=1024,wsize=1024 192.168.1.3:/work/nfsroot /mnt

(如果nfs挂载后,不能读取,可以点击这里)

(4.3) 先装载3个/drivers/video下编译好的模块(cfbcopyvarea.ko、cfbfillrect.ko、cfbimgblt.ko),再来装载LCD驱动模块(lcd.ko)。

(4.4) 挂载LCD驱动后,可以通过ls -l /dev/fb*命令查看已挂载的LCD设备节点。

5、测试运行

echo hello > /dev/tty1

ls -l > /dev/tty1

6、优化。(使用上节的键盘驱动在LCD终端打印命令行)

(5.1)vi /etc/inittab        (修改inittab,inittab:配置文件,用于启动init进程时,读取inittab)

添加tty1::askfirst:-/bin/sh        (将sh进程(命令行)输出到tty1里,也就是LCD输出信息)

(5.2)然后重启,insmod装载/drivers/video下编译好的模块,再来insmod装载LCD驱动模块,tty1设备便有了,就能看到信息。

(5.3)最后insmod上一节的键盘驱动buttons.ko后,按下"Enter"按键,便能在LCD终端上操作linux了。

(5.4)如果按下Enter键,它就启动了一个进程号770的-sh进程,如下图发现这个-sh的描述符指向tty1:

S3C2440 (4.3寸)LCD驱动程序之层次分析(十六)相关推荐

  1. Linux内核 LCD 驱动程序框架

    Linux 内核 LCD 驱动程序框架 1. framebuffer 简介 1.1 什么是 framebuffer 1.2 framebuffer的作用 2. framebuffer 驱动的框架 3. ...

  2. 树莓派触摸屏连接方法(微雪7寸LCD)

    微雪 7寸LCD 触摸屏 显示器 适用 树莓派 BB BLACK 电脑 HDMI高清,购买地址如下: https://detail.tmall.com/item.htm?spm=a220o.10008 ...

  3. 嵌入式驱动编写-LCD驱动程序

    如何来写LCD的驱动程序,首先 看芯片开发手册和原理图 根据原理图,找到s3c2440的GPIO控制管脚,gpb   gpc  gpd  gpg管脚控制 需要设置寄存器 以及设置LCD控制寄存器 查看 ...

  4. linux驱动LCD 驱动程序代码编写

    转自 在编写代码之前我们先来看一看原理图 引脚说明: VCLK:发出lcd时钟信号,每来一个时钟,就会在屏幕上显示一个像素      --GPC1  :配置为lcd引脚 VLINE:发出lcd行扫描信 ...

  5. LCD驱动程序——代码编写(二)

    转自http://liu1227787871.blog.163.com/blog/static/205363197201242393031250/ 在编写代码之前我们先来看一看原理图 引脚说明: VC ...

  6. linux lcd驱动调试 echo dev/fb0,LCD驱动程序 - osc_msmij2gf的个人空间 - OSCHINA - 中文开源技术交流社区...

    LCD驱动程序 假设 app: open("/dev/fb0", ...) 主设备号: 29, 次设备号: 0 kernel: fb_open int fbidx = iminor ...

  7. lcd图片转二进制工具_辽宁2.8寸LCD屏价格,测距仪LCD显示屏_思迈微

    首页 > 新闻中心 发布时间:2020-11-15 08:27:09 导读:思迈微为您提供辽宁寸LCD屏价格,测距仪LCD显示屏的相关知识与详情: 以上便是对LED点阵式显示屏的软硬件系统.组成 ...

  8. LCD笔记(7)LCD驱动程序框架_配置时钟

    1. 硬件相关的操作 LCD驱动程序的核心就是: 分配fb_info 设置fb_info 注册fb_info 硬件相关的设置 硬件相关的设置又可以分为3部分: 引脚设置 时钟设置 LCD控制器设置 本 ...

  9. [nRF51822] 1、一个简单的nRF51822驱动的天马4线SPI-1.77寸LCD彩屏DEMO

    最近用nRF51822写了个天马4线SPI的1.77寸LCD彩屏驱动,效果如下: 屏幕的规格资料为:http://pan.baidu.com/s/1gdfkr5L 屏幕的驱动资料为:http://pa ...

最新文章

  1. 深度学习指数的使用——np.exp(-4)和1e-4的区别
  2. 数据是互联网下半场产品人突围之道
  3. jquery标签选择器应用示例
  4. php中target用法,Yii使用DbTarget实现日志功能的示例代码
  5. 在竞争激烈的ToB公司,这个创始团队拒绝一夜暴富,坚持做好产品
  6. Delphi/C#之父:Anders Hejlsberg
  7. python做的大型游戏_Python实现数据量较大的生命游戏
  8. 犯病的chorme(谷歌浏览器)之css加载失败
  9. NodeJS写模块和引入模块的例子
  10. 适用于苹果Mac的 5 个最佳 SSH 客户端软件
  11. 类/对象/构造函数/析构函数
  12. js 表单打开新窗口
  13. 翻译: 深入神经网络概览Dive into Deep Learning
  14. 十次方:区块链需要服务器吗?
  15. 为什么会有这么多中间表?
  16. 优秀的网站加速插件 – WP rocket详细设置教程
  17. 数组方法的增删等19种操作:unshift 、shift,push、pop、splice等等...!
  18. 【屌丝之作】3D遥控坦克大战
  19. Mac Elasticsearch 7.9.3 安装指南
  20. Hive(11):Hive的函数之内置函数

热门文章

  1. C#之禁用任务管理器(对注册表项的访问被拒绝)
  2. 计算机病毒学课本,计算机病毒实验教程
  3. 实验一 /*被动扫描,利用搜索引擎或相关网站*/
  4. 如何用python写一个文件管理程序
  5. Python界面编程第九课:Pyside2 (Qt For Python)创建数字时钟
  6. 关于 “exported needs to be explicitly specified for <activity>.” 问题的解决。
  7. 当年的三国java游戏_三国卡牌类手游塞班 分享问几年前玩的一个三国
  8. qHD、HD、FHD、QHD、UHD的区别
  9. 网页打印非常优秀的插件 Print.js
  10. IDEA软件安装与配置