一、字符编码

为更好的存储和展示,于是出现了字符编码。下面来看一下字符编码的发展过程。分为三个阶段:

阶段1:ASCII码

欧美人发明,用一个字节来标志。也就是常说的ASCII码,由于英语中只有26个英文字母,以及常用符号,可以很简单的编码出来。Ox41:A;0x61:a。

阶段2:国家编码GB2312(GBK)

我们国家有上千的汉子,所以编码要比较多一些,用两个字节来表示一个汉字。对于内地采用GB2312编码(GBK);big5(繁体字)等等。

D6DO:中。

阶段3:世界统一unicode码

世界需要一个统一的标准,于是出现了unicode,常见的utf-8;utf-16等

显示文字

文字编码方式

源文件用不同的编码方式编写,会导致执行结果不一样。

怎么解决?编译程序时,要指定字符集

man gcc , /charset

-finput-charset=charset  表示源文件的编码方式, 默认以UTF-8来解析

-fexec-charset=charset   表示可执行程序里的字时候以什么编码方式来表示,默认是UTF-8

gcc -o a a.c

gcc -finput-charset=GBK-fexec-charset=UTF-8 -o utf-8_2 ansi.c

ASCII默认国标存储汉字

默认utf8保存就不会有这个问题。

二、点阵显示

1、实现思路:

(1)打开lcd设备:

(2)得到lcd信息

Fbmen.c中有很多ioctl获得可变信息和固定信息

(3)显存占据多少字节

(4)LCD提供mmap

显存fb内存映射:

fbmem= (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED,fd_fb, 0);

screen_size:大小

PROT_READ | PROT_WRITE, MAP_SHARED:可读可写

if(fbmem == (unsigned char *)-1)

{

printf("can'tmmap\n");

return-1;

}

(5)显示A+中

unsignedchar str[] = "中";

lcd_put_ascii(var.xres/2, var.yres/2, 'A');

printf("chinesecode: %02x %02x\n", str[0], str[1]);

lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);

return0;

(6)void lcd_put_ascii(int x, int y, unsignedchar c)

void lcd_put_pixel(int x, int y, unsigned int color)

(7)打开汉字库

fd_hzk16= open("HZK16", O_RDONLY);

if(fd_hzk16 < 0)

{

printf("can'topen HZK16\n");

return-1;

}

struct stat hzk_stat;

if(fstat(fd_hzk16,&hzk_stat))

{

printf("can'tget fstat\n");

return-1;

}

hzkmem= (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED,fd_hzk16, 0);

if(hzkmem == (unsigned char *)-1)

{

printf("can'tmmap for hzk16\n");

return-1;

}

(8)void lcd_put_chinese(int x, int y, unsignedchar *str)

(9)编译

有缺少头文件的错误,修改后成功

拷贝至开发板

(10)内核修改

1.配置、修改内核支持把lcd.c编译进去

cp /work/drivers_and_test_new/10th_lcd/lcd.c      drivers/video/

修改drivers/video/Makefile

#obj-$(CONFIG_FB_S3C2410)         += s3c2410fb.o

obj-$(CONFIG_FB_S3C2410)          += lcd.o

2.make menuconfig

支持lcd编译进内核

(11)测试

应用程序挂载到单板

内核配置编译lcd进内核

修改lcd驱动

从新内核启动

nfs 32000000 192.168.1.100:/work/nfs_root/uImage; bootm 32000000

三、代码

(1)应用程序代码
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>#define FONTDATAMAX 4096static const unsigned char fontdata_8x16[FONTDATAMAX] = {...
}int fd_fb;
struct fb_var_screeninfo var;   /* Current var */
struct fb_fix_screeninfo fix;   /* Current fix */
int screen_size;
unsigned char *fbmem;
unsigned int line_width;
unsigned int pixel_width;int fd_hzk16;
struct stat hzk_stat;
unsigned char *hzkmem;/* color : 0x00RRGGBB */
void lcd_put_pixel(int x, int y, unsigned int color)
{unsigned char *pen_8 = fbmem+y*line_width+x*pixel_width;unsigned short *pen_16; unsigned int *pen_32;   unsigned int red, green, blue;  pen_16 = (unsigned short *)pen_8;pen_32 = (unsigned int *)pen_8;switch (var.bits_per_pixel){case 8:{*pen_8 = color;break;}case 16:{/* 565 */red   = (color >> 16) & 0xff;green = (color >> 8) & 0xff;blue  = (color >> 0) & 0xff;color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);*pen_16 = color;break;}case 32:{*pen_32 = color;break;}default:{printf("can't surport %dbpp\n", var.bits_per_pixel);break;}}
}void lcd_put_ascii(int x, int y, unsigned char c)
{unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];int i, b;unsigned char byte;for (i = 0; i < 16; i++){byte = dots[i];for (b = 7; b >= 0; b--){if (byte & (1<<b)){/* show */lcd_put_pixel(x+7-b, y+i, 0xffffff); /* 白 */}else{/* hide */lcd_put_pixel(x+7-b, y+i, 0); /* 黑 */}}}
}void lcd_put_chinese(int x, int y, unsigned char *str)
{unsigned int area  = str[0] - 0xA1;unsigned int where = str[1] - 0xA1;unsigned char *dots = hzkmem + (area * 94 + where)*32;unsigned char byte;int i, j, b;for (i = 0; i < 16; i++)for (j = 0; j < 2; j++){byte = dots[i*2 + j];for (b = 7; b >=0; b--){if (byte & (1<<b)){/* show */lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */}else{/* hide */lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */}}}}int main(int argc, char **argv)
{unsigned char str[] = "中";fd_fb = open("/dev/fb0", O_RDWR);if (fd_fb < 0){printf("can't open /dev/fb0\n");return -1;}if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var)){printf("can't get var\n");return -1;}if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix)){printf("can't get fix\n");return -1;}line_width  = var.xres * var.bits_per_pixel / 8;pixel_width = var.bits_per_pixel / 8;screen_size = var.xres * var.yres * var.bits_per_pixel / 8;fbmem = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);if (fbmem == (unsigned char *)-1){printf("can't mmap\n");return -1;}fd_hzk16 = open("HZK16", O_RDONLY);if (fd_hzk16 < 0){printf("can't open HZK16\n");return -1;}if(fstat(fd_hzk16, &hzk_stat)){printf("can't get fstat\n");return -1;}hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);if (hzkmem == (unsigned char *)-1){printf("can't mmap for hzk16\n");return -1;}/* 清屏: 全部设为黑色 */memset(fbmem, 0, screen_size);lcd_put_ascii(var.xres/2, var.yres/2, 'A');printf("chinese code: %02x %02x\n", str[0], str[1]);lcd_put_chinese(var.xres/2 + 8,  var.yres/2, str);return 0;
}

(2)LCD驱动程序代码

#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];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];/* 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)return 1;/* 用red,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 */s3c_lcd = framebuffer_alloc(0, NULL);/* 2. 设置 *//* 2.1 设置固定的参数 */strcpy(s3c_lcd->fix.id, "mylcd");s3c_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_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_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  = 0xaaaaaaaa;   /* GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND */*gpdcon  = 0xaaaaaaaa;   /* GPIO管脚用于VD[23:8] */*gpbcon &= ~(3);  /* GPB0设置为输出引脚 */*gpbcon |= 1;*gpbdat &= ~1;     /* 输出低电平 */*gpgcon |= (3<<8); /* GPG4用作LCD_PWREN *//* 3.2 根据LCD手册设置LCD控制器, 比如VCLK的频率等 */lcd_regs = ioremap(0x4D000000, sizeof(struct lcd_regs));/* bit[17:8]: VCLK = HCLK / [(CLKVAL+1) x 2], LCD手册P14*            10MHz(100ns) = 100MHz / [(CLKVAL+1) x 2]*            CLKVAL = 4* bit[6:5]: 0b11, TFT LCD* bit[4:1]: 0b1100, 16 bpp for TFT* bit[0]  : 0 = Disable the video output and the LCD control signal.*/lcd_regs->lcdcon1  = (4<<8) | (3<<5) | (0x0c<<1);#if 1/* 垂直方向的时间参数* bit[31:24]: VBPD, VSYNC之后再过多长时间才能发出第1行数据*             LCD手册 T0-T2-T1=4*             VBPD=3* bit[23:14]: 多少行, 320, 所以LINEVAL=320-1=319* bit[13:6] : VFPD, 发出最后一行数据之后,再过多长时间才发出VSYNC*             LCD手册T2-T5=322-320=2, 所以VFPD=2-1=1* bit[5:0]  : VSPW, VSYNC信号的脉冲宽度, LCD手册T1=1, 所以VSPW=1-1=0*/lcd_regs->lcdcon2  = (1<<24) | (271<<14) | (1<<6) | (9);/* 水平方向的时间参数* bit[25:19]: HBPD, VSYNC之后再过多长时间才能发出第1行数据*             LCD手册 T6-T7-T8=17*             HBPD=16* bit[18:8]: 多少列, 240, 所以HOZVAL=240-1=239* bit[7:0] : HFPD, 发出最后一行里最后一个象素数据之后,再过多长时间才发出HSYNC*             LCD手册T8-T11=251-240=11, 所以HFPD=11-1=10*/lcd_regs->lcdcon3 = (1<<19) | (479<<8) | (1);/* 水平方向的同步信号* bit[7:0]    : HSPW, HSYNC信号的脉冲宽度, LCD手册T7=5, 所以HSPW=5-1=4*/  lcd_regs->lcdcon4 = 40;#else
lcd_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) | \S3C2410_LCDCON4_HSPW(0);#endif/* 信号的极性 * bit[11]: 1=565 format* bit[10]: 0 = The video data is fetched at VCLK falling edge* bit[9] : 1 = HSYNC信号要反转,即低电平有效 * bit[8] : 1 = VSYNC信号要反转,即低电平有效 * bit[6] : 0 = VDEN不用反转* bit[3] : 0 = PWREN输出0* bit[1] : 0 = BSWP* bit[0] : 1 = HWSWP 2440手册P413*/lcd_regs->lcdcon5 = (1<<11) | (0<<10) | (1<<9) | (1<<8) | (1<<0);/* 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) & ~(3<<30);lcd_regs->lcdsaddr2  = ((s3c_lcd->fix.smem_start + s3c_lcd->fix.smem_len) >> 1) & 0x1fffff;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);iounmap(lcd_regs);iounmap(gpbcon);iounmap(gpccon);iounmap(gpdcon);iounmap(gpgcon);framebuffer_release(s3c_lcd);
}module_init(lcd_init);
module_exit(lcd_exit);MODULE_LICENSE("GPL");

参考资料:
FreeType 字体引擎分析与指南
http://wenku.baidu.com/view/2d24be10cc7931b765ce155b.html
HZK16应用示例
http://wenku.baidu.com/view/0774d20c52ea551810a68768.html
点阵字库HZK12 HZK16 HZK24 ASC12 ASC16 简介 及 使用方法 
http://blog.csdn.net/hongjiujing/article/details/6649618
汉字拼音、五笔、GB2312、GBK、Unicode、BIG5编码速查
http://ipseeker.cn/tools/pywb.php
在线汉字编码查询,一次查询多个汉字输入法编码及内码——快典网.htm
http://bm.kdd.cc/
BIG5编码表
http://wenku.baidu.com/view/9bb3ae01b52acfc789ebc970.html
UNICODE编码表
http://wenku.baidu.com/view/7c667f563c1ec5da50e27069.html
GB2312简体中文编码表
http://wenku.baidu.com/view/0ef57bfb04a1b0717fd5dd1a.html
hzk16的介绍以及简单的使用方法
http://hi.baidu.com/hrman/blog/item/4616bc2675ce13128a82a193.html

linux应用项目(一)数码相框(2)数码相框之字符编码与字符的点阵显示相关推荐

  1. linux相框应用程序,linux应用项目(一)数码相框(1)数码相框之系统框架

    项目说明: 数码相框项目:看着简单 涉及到的内容是很多的. 项目流程: 弄清需求 设计框架 编写代码 测试 发展方向: 专家(某个问题专研深刻) 系统(设计框架功能) 弄清需求: (1)    上电, ...

  2. linux应用项目(一)数码相框(3)数码相框之电子书

    一.整体思路 这一节我们重点学习框架,就是编程的思想.架构很重要.采用分层的思想,面向对象的编程思想. 1.怎样在LCD上显示一个文件 2.如何组织代码 分层的结构 main--draw--XXX_m ...

  3. [电子书]项目储备一: 字符编码与LCD显示单个字母/汉字

    [电子书]项目储备一: 字符编码与LCD显示单个字母/汉字 1 字符编码 2 LCD显示单个字母/汉字 2.1 编程思路 2.2 代码实现 2.3 编译.测试与bug 3 总结与下文预告 1 字符编码 ...

  4. linux下字符编码转换

    2019独角兽企业重金招聘Python工程师标准>>> 关于字符编码: 字符编码笔记:ASCII,Unicode和UTF-8: http://www.ruanyifeng.com/b ...

  5. 数码相框_在LCD上显示英文字母、汉字的点阵显示(2)

    数码相框_在LCD上显示英文字母.汉字的点阵显示 主要内容: 写应用程序,使LCD显示汉字和字符 原理: 在SDRAM内存里划出一块空间为FrameBuffer显存,LCD控制器会从FrameBuff ...

  6. clion浏览linux代码,手把手教你使用 Clion 开发 Linux C++ 项目

    手把手教你使用 Clion 开发 Linux C++ 项目 关于CLion CLion是一款专为开发C及C++所设计的跨平台IDE.它是以IntelliJ为基础设计的,包含了许多智能功能来提高开发人员 ...

  7. linux基本项目环境搭建

    文章目录 linux基本项目环境搭建 java环境搭建 获取java源码包 解压 配置环境变量 使配置文件生效 验证 nginx安装 下载(java也可用此方法下载) 解压 配置(configure) ...

  8. 嵌入式 linux 启动脚本 编写,[9构建嵌入式linux系统项目-启动脚本的编写.ppt

    [9构建嵌入式linux系统项目-启动脚本的编写 启动脚本 教学回顾 shell语法 管道.重定向 变量 结构性语句 教学内容 启动脚本的写法 教学要求 熟悉掌握启动脚本的写法 shell 函数 在s ...

  9. C语言到嵌入式Linux开发项目指导

    C语言到嵌入式Linux开发项目指导 第一阶段C语言 1.常量与变量,数据类型,数据类型转换,数据输入与输出: 2.C语言运算符,C语言操作符,C语言表达式,表达式优先级: 3.C语言流程控制,分支, ...

  10. 关于Linux开源项目基础组件make编译流程

     关于Linux开源项目基础组件make编译流程 非常多Linux开源项目都会用到编译出可运行文件的make.这个是有一套流程的. 首先,GNU构建系统:https://en.wikipedia. ...

最新文章

  1. 中国地址住址五级以下
  2. mysql noinstall_windows mysql noinstall
  3. java amr 转 mp3_JAVA 音频转换AMR 转MP3,OS,Linux cent os 7
  4. 为什么报表里面记录的创建时间 比我们电脑客户端的世界时间 隔8个小时?这个是什么原因?...
  5. 未来已来 -只是尚未流行
  6. python如何输入多组数据_Python 中如何实现多组的输入输出
  7. 厉害!这位80后连发2篇Science!身处普通高校,告诉你科研不决取于平台
  8. python pip下载本地依赖包,并在离线环境中安装,并解决报错ERROR: Could not find a version that satisfies the requirement报错
  9. socket的java实现_Socket之Java实现普通版本
  10. asp.net ajax updatepanel中textbox 乱码问题 解决方案
  11. Jasper报表导出pdf中文不显示——Font simsun is not available to the JVM. See the Javadoc for more det,已解决
  12. 红米5 Plus刷开发版/小米手机刷开发版
  13. 使用PS将图片自然从清晰到模糊过渡
  14. Android显示人民币双横线的¥符号
  15. Freebase上的SPARQL查询
  16. 科恒khs202温控器使用说明书_WS203数字显示温控器使用说明书
  17. C语言常见问题(3):Although the value stored to ‘ret‘ is used in the enclosing expression
  18. 基于SpringBoot+Vue的酒店管理系统(免费获取源码+项目介绍+运行介绍+运行截图+论文)
  19. 小米市场魅力所在?你读懂小米了么?
  20. Python绘制3D图形:Axes3D

热门文章

  1. 为什么在计算机里打开U盘会闪退,U盘闪退怎么办?
  2. 安装jdk的时候为什么会有两个jre文件
  3. 关于博弈论中的一硬币正反问题的分析
  4. 谈谈网络协议,常见的网络协议有那些?
  5. github 迁移google code 项目
  6. windows系统磁盘空间清理工具SDelete
  7. 嵌入式系统开发环境的构建08:在Hyper-V中安装Windows XP操作系统
  8. mysql5.464位下载_MySQL Front 64位
  9. GPS NMEA协议,0183 定位数据格式 双模定位:GNXXX GPS+BD 完整版
  10. 如何将时间字体LED化(类似电子表)显示