单片机十六进制转ascii码ASCII字符集是怎么获取的,我想把字体大小改打一点?

在上一节我们介绍了LCD的硬件基础只是、以及S3C2440 LCD控制器相关的寄存器。这一节我们将会动手在LCD上显示一幅日落的图片。

一、LCD初始化编程步骤

在上一节我们介绍了S3C2440这些引脚对应的LCD TFT上的引脚。这里就不在重复介绍了。我们需要配置Port C和Port D为LCD功能。

端口C相关寄存器的相关信息。

端口C的上拉使能寄存器
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

由上表可知,B端口的控制寄存器可以将每个引脚配置为四种模式:

配置端口C功能复用为LCD:

当端口配置为输入端口时,相应位为引脚状态。当端口配置为输出端口时,引脚状态将与相应位相同。当端口配置为功能引脚,将读取到未定义值。

0:使能附加上拉功能到相应端口引脚

1:禁止附加上拉功能到相应端口引脚

端口D相关寄存器的相关信息。

端口D的上拉使能寄存器
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

由上表可知,B端口的控制寄存器可以将每个引脚配置为四种模式:

配置端口D功能复用为LCD:

当端口配置为输入端口时,相应位为引脚状态。当端口配置为输出端口时,引脚状态将与相应位相同。当端口配置为功能引脚,将读取到未定义值。

0:使能附加上拉功能到相应端口引脚

1:禁止附加上拉功能到相应端口引脚

LCD_PWR对应的引脚,所以设置GPG4就可以控制LED背光电源了。(GPGCON:9-8写入11),这时候LCD电源的打开/关闭可以通过LCDCON5位3来控制:

其他信号线包括VD0-VD23和VFRAME、VLINE、VCLK等,分别在GPCCON,GPDCON中选择相应功能。这些在上一节已经介绍过。这里就稍微提一下

(VCLK)LCD的Datasheet上一般会写有一个推荐的频率,上一节已经介绍过我使用的屏幕推荐频率为6.4M,我们通过计算得到的CLKVAL=7比较合适。写入LCDCON1位17-8;

2) 设置其他相关参数

3) 设置视频缓冲区的地址

S3C2440支持虚拟屏幕,可以通过改变LCD寄存器实现屏幕快速移动;
PAGEWIDTH:虚拟屏幕一行的字节数,如果不使用虚拟屏幕,设置为实际屏幕的行半字数,如16位宽320像素,设为320 ;
OFFSIZE:虚拟屏幕左侧偏移的字节数,如果不使用虚拟屏幕,设置为0;

* 0 = 禁止视频输出和LCD 控制信号 1 = 允许视频输出和LCD 控制信号 /* [21:11] OFFSIZE:表示虚拟屏偏移尺寸 即上一行最后像素点到下一行第一个像素点之间间隔多少个像素点

到此LCD初始化步骤就介绍完成了,整体代码如下:

如果想在LCD上显示一幅图片,只需要向LCD_BUFFER缓冲区写入图片数据即可。

在Ecllispe调试模式下,将代码直接下载SDRAM地址0x运行,图片显示正常:

但是通过MiniTools下载到SDRAM地址0x运行,图片却显示异常:

目前原因还未排查清楚。

既然我们能使用LCD去显示图片,那么去显示字符其实也是很简单的道理。我们可以把每个字符看成一个比较小的图片。

比如16*16的汉字显示原理就是在一个长宽16的正方形中绘制若干个点,这样就只有弄清楚哪些点是要显示的就行了。比如第一行要显示一个点我们就可以 xxxxxxxoxxxxxxxx, 我们只有把中间的圈显示,其余的点不显示就可以了。

这样我们就可以用一个数组来保存这些点,每一位表示是否要显示,当然这一位要显示什么颜色, 我们可以自行设置。

对于字模数组的提取现在已经有很多好用的字模提取软件,字库软件的,到网上搜一个然后就很容易了,只要输入想要显示的汉字软件就帮你把字模的数组显示好了,你只有把这个字模数组放到程序当中去就可以了。

当然这里要注意字模提取的顺序,还有有些字模软件中可以设置要不要倒序的问题,这里我用的是 PCtoLCD2002.EXE 这个软件,我的LCD的取模方式是横向取模,字节不倒序,C51格式 。

可以看到一共生成32个字节,每两个字节对应图片中一行的16个点,我们以第一行对应的两个字节为例 0x08 0x80,转换成二进制就是0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0,也就是说将第一行16个像素中的第5个、9个像素点亮。

当然要是有很多汉字要显示的话一个一个字去提取就不容易了。现在已经有人或者有一些标准已经把汉字弄成了一些字库,像16*16的话就标准库GB2312 ,但是注意,这些库好像要么是没有后缀名要么是数据库形式,对于裸机还是比较不方便,这里的话可以去找一下有人把这些做成了C语言数组形式这样就比较好用 了,不过这样有点占内存,16*16 / 8 = 32 就是一个字占32个字节,常用汉字字符库的话一般有6 7千个,那么简单算一下应该就需要差不多200k的内存,对于单片机来说还是比较难以消化的。

有了字库我们就只需要找个我们需要的汉字然后取出来显示就好了,但是怎么找这么汉字,当然这么问题别人早已经解决。

首先对于汉字在GB2312编码中使用两个字节表示,收录7445个图形字符,其中包括6763个汉字。,其中一级汉字3755个,二级汉字3008个;同时收录包括拉丁字母、希腊字母、日文平假名及片假名字母、俄罗斯语西里尔字母在内的682个全形字符。

GB2312对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。

  • 01-09区为特殊符号;
  • 10-15区没有编码;
  • 6-55区为一级汉字,按拼音排序,共3755个;
  • 56-87区为二级汉字,按部首/笔画排序,共3008个;
  • 88-94区没有编码;
  • GB2312只是编码表,在计算机中通常都是用"EUC-CN"表示法,即在每个区位加上0xA0来表示。区和位分别占用一个字节。

举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。

字节编码,通常采用EUC储存方法,以便兼容于ASCII。每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”,第二个字节称为“低位字节”。

有了区位码。这样我们查找汉字是就比较方便了,首先我们通过区号找个是属于哪个区,然后再通过位号找个属于哪个位就可以找到汉字了,

假设我们将我们的GB2312字库采用二位数组表示,数组长度为94*94=8836:

我们将汉字采用GB2312编码,我们需要计算每个汉字在二位数组的索引,该索引为(高位字节-0xA1)*94 + (低位字节-0xA1)。

在GB2312编码表里面,区位码里有英文和数字,按道理说是不是也应该是双字节的呢。

而一般情况下,我们见到的英文和数字是单字节的,以ASCII编码,也就是说现代的GB2312编码是兼容ASCII编码的。比如一个数字2,对应的二进制是0x32,而不是 0xA3 0xB2。那么问题来了,0xA3 0xB2 又对应到什么呢?还是2(笑)。注意看了,这里的2跟2是不是有点不太一样?!确实是不一样的。这里的双字节2是全角的二,ASCII的2是半角的二,一般输入法里的切换全角半角就是这里不同。

同一个编码文件里,怎么区分ASCII和中文编码呢?从我们知道标准ASCII只有128个字符,0~127即0x00~0x7F()。所以区分的方法就是,高字节的最高位为0则为ASCII,为1则为中文。

我们如何将字库转为二位数组呢,下面这个程序读取一个字库二进制文件,并遍历整个字库文件,转换为二位数组,保存下来:

//把每个数组元素以十进制的方式存入data.txt中 // 读取32位长度,返回0 读取完毕 // 显示读取到16进制
* 横向取模 C51 取模顺向: 从第一行开始向右 ,每取8个点作为一个字节,如果最后不足8个点就补满8位。 取模顺序是从高到低,即第一个点作为最高位。 比如0x08,0x80对应第一行
* 横向取模 C51 取模顺向
* len : 字符串所占字节长度 比如:4 /* 计算区号和位号 */ /* 到字库数组查找对应的字模数组 */

需要注意的是这段代码文件必须以GBK编码(兼容GB2312),这样这些字符写到开发板data执行的内存空间上是才是GBK编码,比如“我爱你刘燕 I LOVE YOU ”保存到内存的数据为:

执行测试代码,显示效果

这个代码已经远超过4kb,并且没有将代码从NAND拷贝到SDRAM运行,只可以下载到SDRAM 0x处运行。

}

在此先谢谢大家的帮忙!目前问题已经有点眉目了!

有以下几个问题请教大家:
1:如果发送端:指令+(参数)+0x0D,程序中还需要怎么修改?因为最终输出要的是ASIIC码。

//要通过RS232通讯口控制驱动,指令格式如下
驱动器采用ASCII 码指令与上位机通讯。
ASCII码指令的构成:
发送端:指令+(参数)+0x0D
指令:仅使用字母的字符串;
参数:指令后为ASCII码数字,有些指令后面无参数;
结束符:发送端以0x0D(回车)结束,回应端以0x0D,0x0A(换行)结束;

//下面程序已经编译通过,在实验板上也通过了。

}

我要回帖

更多关于 单片机十六进制转ascii码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信