ok6410LCD测试程序
2012-10-09 13:12
1096 查看
1.在屏幕上分别显示红绿蓝三个长方形:
[cpp]
view plaincopy
#ifndef LCD_APP_H
#define LCD_APP_H
/*自定义结构体用来在用户空间里管理帧缓冲的信息*/
typedef struct fd_dev
{
int fd;//帧缓冲设备文件描述符
void *pfb;//指向帧缓冲映射到用户空间的首地址
int xres,yres,siz;//一帧图像的宽度、高度和大小
int bpp;//每个像素的位数
}fb_dev_t;
/*实现缓冲设备的打开和关闭操作的接口*/
int fb_open(fb_dev_t *fbd,char *fbn)
{
struct fb_var_screeninfo vinfo;
if(-1 == (fbd->fd=open(fbn,O_RDWR))){
printf("Error:cannot open framebuffer device.\n");
_exit(EXIT_FAILURE);
}
/*获取LCD的可变参数*/
ioctl(fbd->fd,FBIOGET_VSCREENINFO,&vinfo);
//将可变参数的中的相关数据保存到自定的结构体fbd中
fbd->xres = vinfo.xres;
fbd->yres = vinfo.yres;
fbd->bpp = vinfo.bits_per_pixel;
fbd->siz = fbd->xres * fbd->yres *fbd->bpp/8;
printf("%dx%d,%dbpp,screensize = %d\n",fbd->xres,fbd->yres,
fbd->bpp,fbd->siz);
/*将帧缓冲映射到内存*/
fbd->pfb = mmap(0,fbd->siz,PROT_READ|PROT_WRITE,
MAP_SHARED,fbd->fd,0);
if((int)fbd->pfb == -1){
printf("Error:failed to map framebuffer device to memory.\n");
_exit(EXIT_FAILURE);
}
return 0;
}
int fb_close(fb_dev_t *fbd)
{
munmap(fbd->pfb,fbd->siz);//解除映射
close(fbd->fd);//关闭设备文件
}
/*填充制定的巨型区域*/
int fb_drawrect(fb_dev_t *fbd,int x0,int y0,int w,int h,int color)
{
int x,y;
for(y=y0;y<y0+h;y++)
{
for(x = x0;x<x0+w;x++)
*((short*)(fbd->pfb)+y*fbd->xres+x)=color;
}
return 0;
}
#endif
测试程序lcd_app.c
[cpp]
view plaincopy
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include "lcd_app.h"
#include "bmplib.h"
#define FB_DEV_NAME "/dev/fb0"
#define RED_COLOR565 0x0F100
#define GREEN_COLOR565 0x007E0
#define BLUE_COLOR565 0x0001F
int main(int argc,char *argv[])
{
fb_dev_t *fbd;
fbd = (fb_dev_t*)malloc(sizeof(fb_dev_t));
fb_open(fbd,FB_DEV_NAME);
if(fbd->bpp == 16){
printf("Red/Green/Blue Screen\n");
fb_drawrect(fbd,0,0,fbd->xres,fbd->yres/3,RED_COLOR565);
fb_drawrect(fbd,0,fbd->yres/3,fbd->xres,fbd->yres*2/3,GREEN_COLOR565);
fb_drawrect(fbd,0,fbd->yres*2/3,fbd->xres,fbd->yres,BLUE_COLOR565);
}else
printf("16 bits only!\n");
//fb_drawbmp(fbd,0,0,argv[1]);
fb_close(fbd);
return 0;
}
2.在lcd上显示位图bmplib.h
[cpp]
view plaincopy
#ifndef BMPLIB_H
#define BMPLIB_H
typedef struct
{
/*位图头文件*/
char type[2];//文件类型,必须为"BM"(0x4D42)
char siz[4];//文件的大小
char reserved[4];//保留,必须为0
char off[4];//位图阵列相对于文件头的偏移字节
}bmp_file_header_t;
typedef struct{
/*位图信息头*/
char siz[4];
char width[4];//位图的宽度
char height[4];//位图的高度
char planes[2];//目标设备的位平面数,必须设置为1
char bitcount[2];//每个像素的位数,1,4,8,或24
char compress[3];//位图阵列的压缩方法,0=不压缩
char img_siz[4];//图像大小(字节)
char xpel[4];//目标设备水平每米像素的个数
char ypel[4];//目标像素垂直每米像素的个数
char clr_used[4];//位图实际使用的颜色表的颜色数
char clr_important[4];//重要颜色索引的个数
}bmp_info_header_t;
/*bitmap格式的图像文件会带有54字节的信息头,其中包含了图像和文件的基本信息,
紧接在文件头之后的就是实际的图像数据*/
typedef struct{
char blue;
char green;
char red;
char reserved;
}rgb_32_t;
/*对位图进行操作*/
typedef struct{
rgb_32_t *curp;//指向当前像素点
int width,height,bitcount,siz;//图形长宽、大小等信息
int fd;//图像文件描述符
void *data;//图像有效数据
}bmp_t;
//字符形到整形的转换
int char_to_int(char *ch)
{
return *((int*)ch);
}
/*打开位图操作*/
int bmp_open(bmp_t *bmp,char *bmpn)
{
bmp_file_header_t fhr;//位图文件头
bmp_info_header_t ihr;//位图信息头
if(-1 == (bmp->fd=open(bmpn,O_RDONLY))){
printf("Error:cannot open framebuffer device.\n");
_exit(EXIT_FAILURE);
}
read(bmp->fd,&fhr,sizeof(bmp_file_header_t));//读取文件头
read(bmp->fd,&ihr,sizeof(bmp_info_header_t));//读取信息头
bmp->width = char_to_int(ihr.width);
bmp->height = char_to_int(ihr.height);
bmp->bitcount = char_to_int(ihr.bitcount);//像素位数
bmp->siz = (bmp->width *bmp->height*bmp->bitcount)/8;
printf("bmp->width = %d\n",bmp->width);
printf("bmp->height = %d\n",bmp->height);
printf("bmp->bitcount = %d\n",bmp->bitcount);
printf("bmp->siz = %d\n",bmp->siz);
bmp->data = malloc(bmp->siz);//为位图数据分配存储空间
read(bmp->fd,bmp->data,bmp->siz);//读取数据
bmp->curp = (rgb_32_t *)bmp->data;//获取当前像素点
return 0;
}
int bmp_close(bmp_t *bmp)
{
close(bmp->fd);
free(bmp->data);
return 1;
}
/*
因为开发板的帧缓冲区在驱动中被设置为16位数据表示一个像素点,因此需要对24或
32位的位图进行转换,使用下面的函数
*/
static inline short transfer_to_16bit(char r,char g,char b)
{
return ((r>>3)<<11)|((g>>2)<<5)|(b>>3);
}
static inline short bmp_get_pixel_16bit(bmp_t *bmp)
{
//将当前位图转化为16位位图信息
return transfer_to_16bit(bmp->curp->red,bmp->curp->green,bmp->curp->blue);
}
//移动到下一像素点
static inline void bmp_next_pixel(bmp_t *bmp)
{
if(24==bmp->bitcount)//如果是24位位图
bmp->curp = (rgb_32_t*)((int)bmp->curp+3);
else if(32 == bmp->bitcount)//如果是32位位图
bmp->curp = (rgb_32_t*)((int)bmp->curp+4);
}
/*绘制位图*/
int fb_drawbmp(fb_dev_t *fbd,int x0,int y0,char *bmpn)
{
int x,y,x1,y1;
bmp_t bmp;
bmp_open(&bmp,bmpn);
x1 = x0+bmp.width;
y1 = y0+bmp.height;
for(y = y1;y>y0;y--){
for(x = x0;x<x1;x++){
//如果超出LCD屏幕坐标范围
if(x>fbd->xres||y>fbd->yres){
bmp_next_pixel(&bmp);//移动到下一个像素点
continue;
}
*((short*)(fbd->pfb)+y*fbd->xres+x) = bmp_get_pixel_16bit(&bmp);
bmp_next_pixel(&bmp);//移动到下一像素点
}
}
bmp_close(&bmp);
return 0;
}
#endif
测试程序:
lcd_bmp.c
[cpp]
view plaincopy
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include "lcd_app.h"
#include "bmplib.h"
#define FB_DEV_NAME "/dev/fb0"
#define RED_COLOR565 0x0F100
#define GREEN_COLOR565 0x007E0
#define BLUE_COLOR565 0x0001F
int main(int argc,char *argv[])
{
fb_dev_t *fbd;
fbd = (fb_dev_t*)malloc(sizeof(fb_dev_t));
fb_open(fbd,FB_DEV_NAME);
/*
if(fbd->bpp == 16){
printf("Red/Green/Blue Screen\n");
fb_drawrect(fbd,0,0,fbd->xres,fbd->yres/3,RED_COLOR565);
fb_drawrect(fbd,0,fbd->yres/3,fbd->xres,fbd->yres*2/3,GREEN_COLOR565);
fb_drawrect(fbd,0,fbd->yres*2/3,fbd->xres,fbd->yres,BLUE_COLOR565);
}else
printf("16 bits only!\n");
*/
fb_drawbmp(fbd,0,0,argv[1]);
fb_close(fbd);
return 0;
}
位图程序测试方法,例如这里有一张名为clock.bmp的图片
编译上述文件后生成lcd_bmp
运行如下命令:
./lcd_bmp clock.bmp
实验现象:
![](http://my.csdn.net/uploads/201205/15/1337075616_3028.jpg)
分享到:
[cpp]
view plaincopy
#ifndef LCD_APP_H
#define LCD_APP_H
/*自定义结构体用来在用户空间里管理帧缓冲的信息*/
typedef struct fd_dev
{
int fd;//帧缓冲设备文件描述符
void *pfb;//指向帧缓冲映射到用户空间的首地址
int xres,yres,siz;//一帧图像的宽度、高度和大小
int bpp;//每个像素的位数
}fb_dev_t;
/*实现缓冲设备的打开和关闭操作的接口*/
int fb_open(fb_dev_t *fbd,char *fbn)
{
struct fb_var_screeninfo vinfo;
if(-1 == (fbd->fd=open(fbn,O_RDWR))){
printf("Error:cannot open framebuffer device.\n");
_exit(EXIT_FAILURE);
}
/*获取LCD的可变参数*/
ioctl(fbd->fd,FBIOGET_VSCREENINFO,&vinfo);
//将可变参数的中的相关数据保存到自定的结构体fbd中
fbd->xres = vinfo.xres;
fbd->yres = vinfo.yres;
fbd->bpp = vinfo.bits_per_pixel;
fbd->siz = fbd->xres * fbd->yres *fbd->bpp/8;
printf("%dx%d,%dbpp,screensize = %d\n",fbd->xres,fbd->yres,
fbd->bpp,fbd->siz);
/*将帧缓冲映射到内存*/
fbd->pfb = mmap(0,fbd->siz,PROT_READ|PROT_WRITE,
MAP_SHARED,fbd->fd,0);
if((int)fbd->pfb == -1){
printf("Error:failed to map framebuffer device to memory.\n");
_exit(EXIT_FAILURE);
}
return 0;
}
int fb_close(fb_dev_t *fbd)
{
munmap(fbd->pfb,fbd->siz);//解除映射
close(fbd->fd);//关闭设备文件
}
/*填充制定的巨型区域*/
int fb_drawrect(fb_dev_t *fbd,int x0,int y0,int w,int h,int color)
{
int x,y;
for(y=y0;y<y0+h;y++)
{
for(x = x0;x<x0+w;x++)
*((short*)(fbd->pfb)+y*fbd->xres+x)=color;
}
return 0;
}
#endif
测试程序lcd_app.c
[cpp]
view plaincopy
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include "lcd_app.h"
#include "bmplib.h"
#define FB_DEV_NAME "/dev/fb0"
#define RED_COLOR565 0x0F100
#define GREEN_COLOR565 0x007E0
#define BLUE_COLOR565 0x0001F
int main(int argc,char *argv[])
{
fb_dev_t *fbd;
fbd = (fb_dev_t*)malloc(sizeof(fb_dev_t));
fb_open(fbd,FB_DEV_NAME);
if(fbd->bpp == 16){
printf("Red/Green/Blue Screen\n");
fb_drawrect(fbd,0,0,fbd->xres,fbd->yres/3,RED_COLOR565);
fb_drawrect(fbd,0,fbd->yres/3,fbd->xres,fbd->yres*2/3,GREEN_COLOR565);
fb_drawrect(fbd,0,fbd->yres*2/3,fbd->xres,fbd->yres,BLUE_COLOR565);
}else
printf("16 bits only!\n");
//fb_drawbmp(fbd,0,0,argv[1]);
fb_close(fbd);
return 0;
}
2.在lcd上显示位图bmplib.h
[cpp]
view plaincopy
#ifndef BMPLIB_H
#define BMPLIB_H
typedef struct
{
/*位图头文件*/
char type[2];//文件类型,必须为"BM"(0x4D42)
char siz[4];//文件的大小
char reserved[4];//保留,必须为0
char off[4];//位图阵列相对于文件头的偏移字节
}bmp_file_header_t;
typedef struct{
/*位图信息头*/
char siz[4];
char width[4];//位图的宽度
char height[4];//位图的高度
char planes[2];//目标设备的位平面数,必须设置为1
char bitcount[2];//每个像素的位数,1,4,8,或24
char compress[3];//位图阵列的压缩方法,0=不压缩
char img_siz[4];//图像大小(字节)
char xpel[4];//目标设备水平每米像素的个数
char ypel[4];//目标像素垂直每米像素的个数
char clr_used[4];//位图实际使用的颜色表的颜色数
char clr_important[4];//重要颜色索引的个数
}bmp_info_header_t;
/*bitmap格式的图像文件会带有54字节的信息头,其中包含了图像和文件的基本信息,
紧接在文件头之后的就是实际的图像数据*/
typedef struct{
char blue;
char green;
char red;
char reserved;
}rgb_32_t;
/*对位图进行操作*/
typedef struct{
rgb_32_t *curp;//指向当前像素点
int width,height,bitcount,siz;//图形长宽、大小等信息
int fd;//图像文件描述符
void *data;//图像有效数据
}bmp_t;
//字符形到整形的转换
int char_to_int(char *ch)
{
return *((int*)ch);
}
/*打开位图操作*/
int bmp_open(bmp_t *bmp,char *bmpn)
{
bmp_file_header_t fhr;//位图文件头
bmp_info_header_t ihr;//位图信息头
if(-1 == (bmp->fd=open(bmpn,O_RDONLY))){
printf("Error:cannot open framebuffer device.\n");
_exit(EXIT_FAILURE);
}
read(bmp->fd,&fhr,sizeof(bmp_file_header_t));//读取文件头
read(bmp->fd,&ihr,sizeof(bmp_info_header_t));//读取信息头
bmp->width = char_to_int(ihr.width);
bmp->height = char_to_int(ihr.height);
bmp->bitcount = char_to_int(ihr.bitcount);//像素位数
bmp->siz = (bmp->width *bmp->height*bmp->bitcount)/8;
printf("bmp->width = %d\n",bmp->width);
printf("bmp->height = %d\n",bmp->height);
printf("bmp->bitcount = %d\n",bmp->bitcount);
printf("bmp->siz = %d\n",bmp->siz);
bmp->data = malloc(bmp->siz);//为位图数据分配存储空间
read(bmp->fd,bmp->data,bmp->siz);//读取数据
bmp->curp = (rgb_32_t *)bmp->data;//获取当前像素点
return 0;
}
int bmp_close(bmp_t *bmp)
{
close(bmp->fd);
free(bmp->data);
return 1;
}
/*
因为开发板的帧缓冲区在驱动中被设置为16位数据表示一个像素点,因此需要对24或
32位的位图进行转换,使用下面的函数
*/
static inline short transfer_to_16bit(char r,char g,char b)
{
return ((r>>3)<<11)|((g>>2)<<5)|(b>>3);
}
static inline short bmp_get_pixel_16bit(bmp_t *bmp)
{
//将当前位图转化为16位位图信息
return transfer_to_16bit(bmp->curp->red,bmp->curp->green,bmp->curp->blue);
}
//移动到下一像素点
static inline void bmp_next_pixel(bmp_t *bmp)
{
if(24==bmp->bitcount)//如果是24位位图
bmp->curp = (rgb_32_t*)((int)bmp->curp+3);
else if(32 == bmp->bitcount)//如果是32位位图
bmp->curp = (rgb_32_t*)((int)bmp->curp+4);
}
/*绘制位图*/
int fb_drawbmp(fb_dev_t *fbd,int x0,int y0,char *bmpn)
{
int x,y,x1,y1;
bmp_t bmp;
bmp_open(&bmp,bmpn);
x1 = x0+bmp.width;
y1 = y0+bmp.height;
for(y = y1;y>y0;y--){
for(x = x0;x<x1;x++){
//如果超出LCD屏幕坐标范围
if(x>fbd->xres||y>fbd->yres){
bmp_next_pixel(&bmp);//移动到下一个像素点
continue;
}
*((short*)(fbd->pfb)+y*fbd->xres+x) = bmp_get_pixel_16bit(&bmp);
bmp_next_pixel(&bmp);//移动到下一像素点
}
}
bmp_close(&bmp);
return 0;
}
#endif
测试程序:
lcd_bmp.c
[cpp]
view plaincopy
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include "lcd_app.h"
#include "bmplib.h"
#define FB_DEV_NAME "/dev/fb0"
#define RED_COLOR565 0x0F100
#define GREEN_COLOR565 0x007E0
#define BLUE_COLOR565 0x0001F
int main(int argc,char *argv[])
{
fb_dev_t *fbd;
fbd = (fb_dev_t*)malloc(sizeof(fb_dev_t));
fb_open(fbd,FB_DEV_NAME);
/*
if(fbd->bpp == 16){
printf("Red/Green/Blue Screen\n");
fb_drawrect(fbd,0,0,fbd->xres,fbd->yres/3,RED_COLOR565);
fb_drawrect(fbd,0,fbd->yres/3,fbd->xres,fbd->yres*2/3,GREEN_COLOR565);
fb_drawrect(fbd,0,fbd->yres*2/3,fbd->xres,fbd->yres,BLUE_COLOR565);
}else
printf("16 bits only!\n");
*/
fb_drawbmp(fbd,0,0,argv[1]);
fb_close(fbd);
return 0;
}
位图程序测试方法,例如这里有一张名为clock.bmp的图片
编译上述文件后生成lcd_bmp
运行如下命令:
./lcd_bmp clock.bmp
实验现象:
![](http://my.csdn.net/uploads/201205/15/1337075616_3028.jpg)
分享到:
相关文章推荐
- ok6410LCD测试程序
- OK6410 uart 简单测试程序
- ok6410的定时器0 测试程序
- 在ok6410 Androdi开发板运行c程序,添加驱动模块,并测试android驱动
- 【OK6410裸机程序】LCD驱动
- 飞凌ok6410的串口测试程序
- ok6410 按键测试c语言版程序
- ok6410的定时器0 测试程序
- OK6410之使用串口烧写运行全裸程序
- ok6410第一个裸板程序led
- OK6410按键驱动--Qt程序(改)亲测可以运行
- ok6410 LED/GPIO 控制 C#程序
- OK6410的单个按键驱动程序(Linux),测试通过
- OK6410裸机程序(一)——GPIO(LED)
- 第二步在TQ2440(S3C2440)上实现点灯程序--->完结,测试OK .
- ok6410-第05篇-Linux 下裸板程序的开发
- OK6410用DNW下载led和ds18b20的裸机程序
- UBOOT-2012-10在OK6410平台的移植(八)LCD输出
- OK6410如何通过tftp下载运行C程序
- OK6410裸机程序(二)——系统时钟