取字模的方法

很多亲们经常问摇摇棒中的字怎样取字模,今天在这里描述一下;
以“欢”为例作为讲解
程序中的“欢”点阵是这样的:
//-- 欢--
0x04,0x10,0x34,0x08,0xC4,0x06,0x04,0x01,
0xC4,0x82,0x3C,0x8C,0x20,0x40,0x10,0x30,
0x0F,0x0C,0xE8,0x03,0x08,0x0C,0x08,0x10,
0x28,0x60,0x18,0xC0,0x00,0x40,0x00,0x00,
为了直观,我们把它按PCB布线的方法把上面的点阵排类一下:
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
P00 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
P01 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
P02 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0
P03 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0
P04 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0
P05 0 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0
P06 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0
P07 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0
P20 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0
P21 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0
P22 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0
P23 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0
P24 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0
P25 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0
P26 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0
P27 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0
其中1为亮,0为LED灭(为什么1是亮,0是灭,请亲们看一下程序和电路,2个结合起来看一下就明白了,这里就不再说明)
接下来为了方便看哪些是亮的,我们把0去掉:
P00 1
P01 1
P02 1 1 1 1 1 1 1
P03 1 1 1 1 1 1 1
P04 1 1 1 1
P05 1 1 1 1 1
P06 1 1 1
P07 1 1 1
P20 1 1
P21 1 1 1
P22 1 1 1 1
P23 1 1 1 1
P24 1 1 1 1
P25 1 1 1
P26 1 1
P27 1 1 1
看到了吗,一个很大的“欢”字就出来了。

上面的点阵我们是手动排列的。

接下来教大家如何用软件取字模。

首先把点中的选项,把软件设置为以下方式取字模:
字体设置为:新宋体然后输入“欢”,点生产字模
点完后我们会得到如下的字模:
欢(0)
{0x14,0x20,0x24,0x10,0x44,0x4C,0x84,0x43,0x64,0x43,0x1C,0x2C,0x20,0x20,0x18,0x10}, {0x0F,0x0C,0xE8,0x03,0x08,0x06,0x08,0x18,0x28,0x30,0x18,0x60,0x08,0x20,0x00,0x00},/*"欢/* (16 X 16 , 新宋体) */
这个就是我们要的“欢”字的字模,很多亲们就会问,为什么软件取出来的字模和程序中的不一样,那是因为程序中的字模,我们是手动排列的。

用软件取出来的字模也是可以的。

我们可以按照软件取出来的自模自己排列一下:
|
P00 1
P01 1
P02 1 1 1 1 1 1 1
P03 1 1 1 1 1 1 1 1 1
P04 1 1 1 1
P05 1 1 1 1 1
P06 1 1 1
P07 1 1
P20 1 1 1
P21 1 1 1 1 1
P22 1 1 1
P23 1 1 1
P24 1 1 1 1
P25 1 1 1 1 1
P26 1 1 1 1 1
P27 1
也是一个|“欢”,只是字体不一样。

合集下载

威尔取模软件GBK字库GB2312字库说明书

威尔取模软件GBK字库GB2312字库说明书

威尔取模软件使用介绍(V1.0)一、简介1.1 界面介绍二、我要取几个汉字的字模2.1 取模2.1.1 打开软件2.1.2 在中文字符集文本框中输入要取模的文字,比如“欢迎使用威尔取模软件”,如下图所示。

2.1.3 选择要取模的字体,比如我要取宋体的字模,就选择宋体。

如下图所示。

此处列出的是系统安装的所有字体,如果要取自己下载的字体的模,请先安装该字体。

2.1.4 添加我要取模的字号,宽度,高度等信息。

点击添加按钮,打开添加窗口,如下图所示。

在字号,宽度,高度框中输入你要取模的文字大小。

比如我要取16*16的点阵,就在宽度和高度中输入16、16。

然后计算字号,字号=0.75*宽度。

输入12。

点击添加。

点击添加以后回到主界面,你会发现主界面字号列表框里面就多了一种你刚刚添加的字号了。

这时候点击你刚刚添加的字号选中它,然后再在预览框中输入一个汉字,看看效果。

2.1.5 如果效果不错可以跳过这一步。

如果效果不好有以下两种情况。

1.文字太大或者太小,如下图两种情况所示。

这时候就需要重新设置字号了。

增大或者减小字号。

2.字符不居中,如下图所示。

这时候调节右下方的位置调整滑块,将文字调节居中,如下图所示。

2.1.6 选择要生成C语言格式还是二进制文件格式。

如果是C语言格式,还可以选择是否生成数组的数组名。

2.1.7 假如我只要取我刚刚设置的16*16点阵字体,那么就要选择“取选中字号”,并选中16*16那一列。

如下图所示。

2.1.8 假如我只要取中文字模,那么就勾上取模中文,同时去掉取模英文的勾,如下图所示。

2.1.9 好了,所有设置妥当,可以开始取模啦。

点击“开始取模”。

如果选择的是C语言格式则取模完成后自动弹出结果窗口,如下图所示。

三、我要取整个GBK字库或者GB2312字库的字模3.1 取模3.1.1 打开软件3.1.2 假如我要取整个GBK字库的字模,那么点击右侧“GBK字库”按钮,自动输入GBK字符集所有文字。

汉字字模存储和提取的方法

汉字字模存储和提取的方法

汉字字模存储和提取的方法
汉字字模的存储和提取是汉字信息处理系统中的重要环节,常用的方法有以下几种:
1. 存储在程序存储器中:这是在程序不大或单片机无外部扩展数据存储区功能的情况下使用的方法。

2. 通过外扩的EEPROM存储汉字字模数据:采用哈佛结构的单片机,如8051单片机及其派生产品,程序存储器(ROM)和数据存储器(RAM)可分别寻址。

将提取的汉字字模数据存放在EPROM或EEPROM内,并设定该芯片的片选地址,只要知道某个汉字字模数据在该芯片的存储位置,通过程序计算出偏移地址,即可实现显示功能。

3. 使用外扩的EEPROM存储整个汉字库:某些高端单片机,如Motorola 的M68300系列32位单片机,寻址范围可达8M。

以上信息仅供参考,如有需要,建议查阅计算机科学和电子工程相关书籍或咨询专业人士。

12864液晶图像显示图文教程——最全版

12864液晶图像显示图文教程——最全版

由图可以看到水平坐标一个单位是两字节(即 16 位 D15~D0),X 地址会自动加 1,是直接加一个单位 (即两字节 16 位),比如 0001(也即 0X80+000X80+01),从第一行第一列跳到第一行第二列。 代码: void display_image(uchar *p) { uchar i,j; write_cmd(0x34);//扩充指令集动作 write_cmd(0x34);//关绘图显示功能 /*上半屏显示设置*/ for(i=0;i<32;i++)//上半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x80); //水平地址 for(j=0;j<16;j++) { write_data(*p);//连续写入 16 个字节 p++; } } /*下半屏半屏显示设置*/ for(i=0;i<32;i++)//下半屏 { write_cmd(0x80+i);//垂直地址 write_cmd(0x88);//水平地址 for(j=0;j<16;j++)//连续写入 16 个字节 { write_data(*p); p++; } } write_cmd(0x36);//开绘图显示 write_cmd(0x30);//回到基本指令集 } 源程序: #include <reg52.h> #include "12864.h" X 坐标(水平)方向以 2 字节 Byte 为单位,Y 坐标(垂直) 方向以 1 位 Bit 为单位,先连续写入垂直与水平坐标,再写入 两字节数据到 GDRAM。 这里是这样进行的:i=0 时,j=0,1 时,写入两字节到垂直 (0X80+00)水平(0X80+00)这格(D15~D0)里;然后 X 坐标地址自增 1, 地址变为垂直 (0X80+00) , 水平 (0X80+01) 这格,在 j=2,3 时写入两字节,………一直到垂直(0X80+00) 水平(0X80+07)这格,在 j=14,15 时写入两字节,此时循环 for(j=0;j<16;j++)结束跳出,刚好第一行 128 位写完数据;然后 i++,开始写第二行……

验证码识别技术课件

验证码识别技术课件

移。
3、知道了数字的偏移位置,就可以计算出数字在二维数组
里的位置,通过循环将数字的6*10=60个数据取出来拼接在
一起,就形成了与数字字模类似的字符串。
4、将字符串与每一个字模的字符串比较,求其相似度,取
最高的相似度对应的数字,或者相似度达到95%以上就可以
断定是某个数字。
学习交流PPT
13
• 第三个图片,看似更复杂,处理上面提到背景色
和干扰素一直变化外,验证字符的颜色也在变化,
并且各个字符的颜色也各不相同。
• 第四个图片,除了第三学个习交图流PPT片上提到的特征外,
5
验证码识别几个步骤
• 一、取出字模 • 1、多刷新几次验证码,将验证码图片保存起来,
要搜集齐0-9的图片。
• 2、用图片处理软件打开图片,图片的视图放大, 这样就能很清楚地观察到图片的每个像素。
学习交流PPT
11
输出结果:
学习交流PPT
12
四、对照样本
把步骤二中的图片特征码和步骤三中的验证码的字模进行对 比,得到验证图片上的数字。
算法过程:
1、将图片二值化后的值保存到二维数组里。
2、通过循环,求出每一个数字的位置,要用到前面得到的
数字的宽、高、间隔、左边偏移、顶部偏移。
例如:第i个数字左边偏移 =(数字宽 + 间隔)* i + 左边偏
• 3、各种图片格式的随机数字+随机大写英文字母+ 随机干扰像素+随机位置。
•
4、汉字是注册目前最新的验证码,随机生成,打
起来更难了,影响用户体学验习交流,PPT所以,一般应用的比较
3
我们先看几种网上比较常见的验证码图片

12864指令以及PROTUES的应用

12864指令以及PROTUES的应用

表3.1 AMPIRE128×64接口说明表管脚电平说明管脚号1 CS1 H/L 片选择信号,低电平时选择前64列2 CS2 H/L 片选择信号,低电平时选择后64列3 GND 0V 逻辑电源地4 VCC 5.0V 逻辑电源正5 V0 LCD驱动电压,应用时在VEE与V0之间加一2K可调电阻6 RS H/L 数据\指令选择:高电平:数据D0-D7将送入显示RAM;低电平:数据D0-D7将送入指令寄存器执行7 R/W H/L 读\写选择:高电平:读数据;低电平:写数据8 E H/L 读写使能,高电平有效,下降沿锁定数据9 DB0 H/L 数据输入输出引脚10 DB1 H/L 数据输入输出引脚11 DB2 H/L 数据输入输出引脚12 DB3 H/L 数据输入输出引脚13 DB4 H/L 数据输入输出引脚14 DB5 H/L 数据输入输出引脚15 DB6 H/L 数据输入输出引脚16 DB7 H/L 数据输入输出引脚17 RST L 复位信号,低电平有效18 VOUT -10V LCD驱动电源2. 指令描述(1)显示开/关设置CODE:R/W RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 L L L L H H H H H H/L 功能:设置屏幕显示开/关。

DB0=H,开显示;DB0=L,关显示。

不影响显示RAM(DD RAM)中的内容。

(2)设置显示起始行CODE:R/W RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 L L H H行地址(0~63)功能:执行该命令后,所设置的行将显示在屏幕的第一行。

显示起始行是由Z地址计数器控制的,该命令自动将A0-A5位地址送入Z地址计数器,起始地址可以是0-63范围内任意一行。

Z地址计数器具有循环计数功能,用于显示行扫描同步,当扫描完一行后自动加一。

(3)设置页地址CODE:R/W RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 L L H L H H H页地址(0~7)功能:执行本指令后,下面的读写操作将在指定页内,直到重新设置。

基于VB实现的的汉字点阵字模的提取方法

基于VB实现的的汉字点阵字模的提取方法
公式与() 3式类似, 为:
起始位置=7X[内 4 内 2 ( 码高字节一11 X 十( 码低字节一11] 6) 9 6) () 4 在不同的2 点阵字库中, 4 各种非汉字符号的存放方式不一样. 有的省去了 1 个区, 前 5 并将这 1个 5
F n(0 o t7 )
F n (1 o t7 )
F n (0 F n ( 1 o t3 ) o t3 )
F n( ) o t5
图1 点阵字库中字模的存储方式 1 6
圈2 点阵字库中字模的存储方式 2 4
由汉字或符号的区位码可以唯一确定其在点阵字库中的起始位置, 计算方法如下:
〔 收稿日 20-1-2; 期〕03 2 3[ 修改稿收到日 20-0-2 期〕04 2 0
' 得到机 内码
然后, 将得到的机内码转化为十六进制, 再分别取得其高位和低位字节
s Q Ma t u =Mi( e ( t e ) 2 r d x i N i ,, H n Ma 1 )
iQ M =" H &sQ M n ua & &# Ma We d He ( t e n Ma , ) 3 ,
Gti a i(B m pd CutP i)将来自 Bt hi a, on, t : e tP s t Bm w I s B 位图的 二进制位复制到一个缓冲区 3 用〔0 ; 在A I P浏览器加人以 上两个A I 数及BT A 结构后, P函 IM P 就可在程序中 引用这两个函 数了.
() 5
3 其体应用实例
下面以1 1 X 点阵字库为例 给出利用 VsaB s 语言提取字模的实现方法. 6 6 i l i u ac 首先, 求得汉字的机内码:
itah d= A cs E cWod r nE cWo s(t ah r) r

TFT Img2lcd 取字模 设置

TFT Img2lcd 取字模设置(2010-12-16 15:45:21)转载原文原文地址:TFT Img2lcd 取字模设置作者:stm32/bbs//bbs_content_all.jsp?bbs_sn=831085大家好:经过两个晚上的努力,终于用AVR驱动起来这个型号是FL032-C0 控制芯片是ILI9320 的240*320 TFT LCD. AVR芯片用的是M32当然这个屏最合适用ARM来驱动。

16bit总线,很方便的。

这个液晶屏是从二手交易论坛grant那弄来的,grant由于采购错误买了10块,现在还有6块,我刚才又发邮件定了一块。

因此最多还有5块,需要的可以去看看。

/bbs/bbs_content.jsp?bbs_sn=823134&bbs_page_no=1& bbs_id=1011另外这个屏的资料也全在那里。

闲话少说,上程序:程序1:用的是M32芯片,编译平台AVRStudio4.13+WINAVR20070525 -s优化级别,16MHz 时钟频率连线:LCD M32D0~D7 <---> PA0~PA7D8~D15 <---> PD0~PD7CS ---> PB0RS ---> PB1WR ---> PB2RD ---> PB4RESET ---> PB5管脚定义在程序中很容易就可以改的,其中控制脚可以任意更改。

程序完成的功能是,把屏分成八份,显示八种颜色,即RGB的排列组合。

然后程序会在中间显示一幅小照片,鉴于M32的存储空间有限,所以图片很小了。

PS:程序没有注释,大家将就着看了。

不好意思这是程序:点击此处下载ourdev_176129.zip(文件大小:129K)效果图:(抱歉,用手机那30W拍的,不清楚)程序2:用的是M32芯片,编译平台AVRStudio4.13+WINAVR20070525 -s优化级别,16MHz 时钟频率,这次使用SD卡作存储连线:LCD M32D0~D7 <---> PA0~PA7D8~D15 <---> PD0~PD7CS ---> PB0RS ---> PB1WR ---> PB2RD ---> PB4RESET ---> PC0SD卡 M32SO ---〉 MISOSI <--- MOSICLK <--- SCKCS <--- SS程序完成的功能是搜索SD卡更目录下的batch文件夹下的bin文件。

C语言读取汉字字模

我们刚刚输出“王”的内码为:205(高字节),245(低字节)。由上面的换算关系,可以得到“王”字的区位码为:
区码=205-160=45
位码=245-160=85
查一下区位码表,4585所表示的汉字正好是“王”。
也可以打开输入法,选择内码输入法,然后选择区位码,输入4585,就会输出“王”字。
English char = 65,
Chinease char= 205,245,
查ASCII码字符表,很容易得到A的ASCII码为65。
我们可以查ASCII码表,得到出ASCII码对应的字符,那我们有什么办法来知道一个汉字内码对应的汉字了?
让我们先来认识一下区位码:
1981年5月,我国国家标准总局颁布了《信息交换用汉字编码字符集》(GB2312-80),简称国家标准汉字编码,也叫国标码。国标码共收进标准字符7445个。其中一级汉字3755个,二级汉字3008个,共计6763个汉字。 由于汉字的字符多,一个字节(即8位二进制代码)不足以表示所有的常用汉字。汉字国标码的每个汉字或符号在计算机中都使用2个字节(16位二进制)代码来表示。
void getAscCode(char *c,char buff[])
{
unsigned long offset;
FILE *ASC;
/*打开字库文件asc16*/
if((ASC=fopen("asc16","rb"))==NULL){
printf("Can't open asc,Please add it?");
在GB2312-80代码表中,纵向分为0~93,共94行。将行号称为区号,列号称为位号,分别有94个区和94个位。区号和位号用十进制表示,不足两位前面补0。这样每个汉字或符号都可用4位十进制表示。这就是我们常说的区位码。每一区共有94个汉字,而位记录该汉字在该区中的具体位置。(记得我们以前读书的时候,报考计算机考试,填写姓名都要我们用区位码填,我们都拿着自己的姓名一个个去查,我们查的那个东东就是区位码。现在想想,真是心寒呀。还好,我后来就没有查了,弄了个excel的宏。把班上人的姓名全部放到一个excel中,然后一点鼠标,哈哈…… 区位码全自动出来了)。

字模的原理和获取

HZK16文件是按照GB 2312-80标准,也就是通常所说的国标码或区位码的标准排列的。国标码分为94个区(Section),每个区94个位(Position),所以也称为区位码。其中01~09区为符号、数字区,16~87区为汉字区。而10~15区、88~94区是空白区域。
如何取得汉字的区位码呢?在计算机处理汉字和ASCII字符时,使每个ASCII字符占用1个字节,而一个汉字占用两个字节,其值称为汉字的内码。其中第一个字节的值为区号加上32(20H),第二个字节的值为位号加上32(20H)。为了与ASCII字符区别开,表示汉字的两个字节的最高位都是1,也就是两个字节的值都又加上了128(80H)。这样,通过汉字的内码,就可以计算出汉字的区位码。
if(AnsiCode[0]<160) //英文字母和字符,转换为全角的字符内码
{
BYTE temp=AnsiCode[0];
AnsiCode[0]=HIBYTE(temp-0x21+0xA3A1); //0xA3A1是ASCII码为0X21的字符对应的全角字符的内码,这是一个偏移量的计算
AnsiCode[1]=LOBYTE(temp-0x21+0xA3A1);
字模获取工具的制作
分析过字模的原理后,就可以来编写工具,首先要准备字库文件,HZK16.DAT,可以从网上下载。
根据原理,先打开文件,然后根据汉字的内码获取区码和位码,然后根据区吗和位码索引到文件中的地址,再读取32个字节数据到BUFFER中即大功告成。
下面是VC中的一段代码,供参考:
view plaincopy to clipboardprint?
一、什么是字模
单片机应用经常会用到液晶显示模块,是用点阵的方式显示的,要显示汉字或字符的时候会用到字模,字模就是字在点阵上显示时对应的编码,如图1显示的“正”字,使用16×16点阵。点阵中黄色的点是高亮的,对应于二进制编码中的1,绿色的低亮对应于二进制编码中的0。如第一行二进制编码应该是00000000 00001000刚好用两个字节表示就是0x0,0x08,这样,16总共需要用32个字节来表示,这32个字节就是“正”的字模。在单片机程序中,将字模发送给液晶显示模块,就能够显示出响应的汉字或字符。

LCD使用实验

LCD使用实验二、预备知识使用的黑白屏的液晶屏,只显示黑白图像和文字,像素大小为128*128。

汉字与图片取模方法:①软件:相关开发工具LCD 液晶取模软件—Lcmzimo.exe②A. 汉字字模的提取:设置参数:数据排序顺序——从上到下从左到右取模方式——纵向8 点上高位输出格式——可自定义字库选择——可自定义(实例中:我们选取16点阵字库)点击参数确认,输入需要取字模的字符串,得到如下所示:将显示区域里面的内容复制到工程文件的gbhz.h 文件中,若存在相关的汉字字模的数据结构定义,只需将每个汉字的数据复制到相应的数据表中。

③BMP 图片取模参数设定与之前相同,还需设置图片截取范围的参数,由于LCD 显示屏的像素为128X128 故输出大小最大为128X128,否则显示不完整。

图片的格式只能为*.bmp,16色位图。

若图片格式不是*.bmp,16色位图,则可以用画图工具改变图片格式。

图片的格式只能为*.bmp。

点击载入图片,选一个二维码图片为例。

可用图框放大进行查看,如图:点击数据保存,保存为*.h 的头文件,将头文件的内容复制到icon.h 文件中,如下图所示。

(注意main.c文件中的EWM_96X96,要更改为你需要显示的icon.h文件中的一致。

)三、实验步骤:LCD 显示程序设计:利用LCD 显示汉字与图片。

1、初始化1)GPIO 初始化void LCD_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStructure;//GPIO结构体定义RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2P eriph_GPIOC, ENABLE); //使能端口时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //开启复用时钟GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//禁用JTAG,使能SW//数据引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 ; //PCGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOC,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_8 ; //PBGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOB,&GPIO_InitStructure);//控制引脚GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOC,&GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_9);//将引脚置GPIO_ResetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_10 | GPIO_Pin_11);//将引脚复位//LCD-RDGPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIO_SetBits(GPIOB,GPIO_Pin_13); //输出高//背光灯初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PA端口时钟//释放JTAG的IO口保留SWDRCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//引脚PA8GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//时钟频率GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIO_SetBits(GPIOA,GPIO_Pin_8); //输出高电平,开启背光灯}2)LCD初始化//lcd写模式void LCD_WRITE(u8 x){if(x&0x01)PCout(14) = 1;else PCout(14) = 0;if(x&0x02)PCout(15) = 1;else PCout(15) = 0;if(x&0x04)PBout(4) = 1;else PBout(4) = 0;if(x&0x08)PBout(3) = 1;else PBout(3) = 0;if(x&0x10)PCout(12) = 1;else PCout(12) = 0;if(x&0x20)PBout(8) = 1;else PBout(8) = 0;if(x&0x40)PCout(6) = 1;else PCout(6) = 0;if(x&0x80)PCout(7) = 1;else PCout(7) = 0;}//写命令void LCD_WR_CMD(u8 cmd){LCD_CS = 0;LCD_RS = 0;LCD_RD = 0;LCD_WR = 0;LCD_WRITE(cmd);LCD_RD = 1;LCD_CS = 1;LCD_RD = 0;}//写数据void LCD_WR_DATA(u8 data){LCD_CS = 0;LCD_RS = 1;LCD_RD = 0;LCD_WR = 0;LCD_WRITE(data);LCD_RD = 1;LCD_CS = 1;LCD_RD = 0;}void LCD_Init(void){LCD_GPIO_Init(); /*GPIO初始化*///lcd硬件复位LCD_RESET = 0;Delay_Ms(20);LCD_RESET = 1;Delay_Ms(20);LCD_WR_CMD(0xae); //关显示LCD_WR_CMD(0xa9); //a9 LCD_WR_CMD(0xc8);LCD_WR_CMD(0xa0); //a0 LCD_WR_CMD(0xab);LCD_WR_CMD(0xa6);LCD_WR_CMD(0xa4);LCD_WR_CMD(0x4c); //n-line LCD_WR_CMD(0x00); //0a LCD_WR_CMD(0x38); //frameLCD_WR_CMD(0x08);LCD_WR_CMD(0x48); //dutyLCD_WR_CMD(0x80); //128LCD_WR_CMD(0xb0);LCD_WR_CMD(0x40);LCD_WR_CMD(0x00);LCD_WR_CMD(0x44); //com0LCD_WR_CMD(0x00);LCD_WR_CMD(0x52); //bias 54LCD_WR_CMD(0x25); //27LCD_WR_CMD(0x81); //LCD_WR_CMD(0x22); //18LCD_WR_CMD(0xa8); //LCD_WR_CMD(0x2c);Delay_Ms(200);LCD_WR_CMD(0x2e);Delay_Ms(200);LCD_WR_CMD(0x2f);Delay_Ms(200);LCD_WR_CMD(0x7B); //Enter Test Command Set 3LCD_WR_CMD(0x10); //Set Color Mode(0x11Black/White mode),0x10=Gray mode (default)LCD_WR_CMD(0x00); //Exit Test Command Set 3LCD_WR_CMD(0xaf);}//更新数组到LCD的显存void LCD_RefreshGram(void){u8 i,n;for(i=0;i<16;i++){LCD_WR_CMD(0xb0+i);LCD_WR_CMD(0x10);LCD_WR_CMD(0x00);for(n=0;n<128;n++){LCD_WR_DATA(LCD_GRAM[i][n]);LCD_WR_DATA(LCD_GRAM[i][n]);}}}//清除显示缓存void LCD_ClearGram(void){u8 i,n;for(i=0;i<16;i++){for(n=0;n<128;n++){LCD_GRAM[i][n]=0x00;}}}//清除显示缓存void LCD_ClearGramLine(u8 line1,u8 line2){u8 i,n;for(i=line1;i<line2;i++){for(n=0;n<128;n++){LCD_GRAM[i][n]=0x00;}}}//以下函数均是将数据写入显示缓存中--------------- //画点,x,y 点坐标//t:点状态1填充0清空void LCD_DrawPoint(u8 x,u8 y,u8 t){u8 temp=0;if(x>127||y>127) return;//超出范围了temp=1<<(y%8);if(t) LCD_GRAM[y/8][x]|=temp;else LCD_GRAM[y/8][x]&=~temp;}//画线void LCD_DrawLine(u16 sx,u16 sy,u16 ex,u16 ey) {u16 t;int xerr=0,yerr=0,delta_x,delta_y,distance;int incx,incy,uRow,uCol;delta_x=ex-sx; //计算坐标增量delta_y=ey-sy;uRow=sx;uCol=sy;if(delta_x>0)incx=1; //设置单步方向else if(delta_x==0)incx=0;//垂直线else {incx=-1;delta_x=-delta_x;}if(delta_y>0)incy=1;else if(delta_y==0)incy=0;//水平线else{incy=-1;delta_y=-delta_y;}if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴else distance=delta_y;for(t=0;t<=distance+1;t++ )//画线输出{LCD_DrawPoint(uRow,uCol,1);//画点xerr+=delta_x ;yerr+=delta_y ;if(xerr>distance){xerr-=distance;uRow+=incx;}if(yerr>distance){yerr-=distance;uCol+=incy;}}}//画矩形void LCD_DrawRect(u16 sx,u16 sy,u16 width,u16 height){u16 ex = sx + width -1;u16 ey = sy + height -1;LCD_DrawLine(sx,sy,ex,sy);LCD_DrawLine(sx,sy,sx,ey);LCD_DrawLine(sx,ey,ex,ey);LCD_DrawLine(ex,sy,ex,ey);}//画圆void LCD_DrawCircle(u16 x0,u16 y0,u8 r){int a,b;int di;a=0;b=r;di=3-(r<<1); //判断下个点位置的标志while(a<=b){LCD_DrawPoint(x0+b,y0-a,1); //1LCD_DrawPoint(x0+a,y0-b,1); //2LCD_DrawPoint(x0-a,y0-b,1); //3LCD_DrawPoint(x0-b,y0-a,1); //4LCD_DrawPoint(x0-b,y0+a,1); //5LCD_DrawPoint(x0-a,y0+b,1); //6LCD_DrawPoint(x0+a,y0+b,1); //7LCD_DrawPoint(x0+b,y0+a,1); //8a++;//使用Bresenham算法画圆if(di<0)di +=4*a+6;else{di+=10+4*(a-b);b--;}}}//显示一个字符//x,y 点坐标//mode:0,反白显示;1,正常显示//size:选择字体8、16void LCD_ShowOneChar(u8 x,u8 y,u8 chr,u8 size,u8 mode) {u8 temp,t,t1;u8 y0=y;u8 csize=16;u8* pdata=NULL;chr=chr-' ';//得到偏移后的值if(chr > 94) return; //超出范围//确定字符点阵起始地址和数据个数if(size == 8){csize = 5;pdata = (u8*)ascii_table_5x8[chr]; //调用0805字体}else if(size == 16){csize = 16;pdata = (u8*)ascii_table_8x16[chr]; //调用1608字体}else return;//显示字符for(t=0;t<csize;t++){temp=pdata[t];for(t1=0;t1<8;t1++)if(temp&0x80)LCD_DrawPoint(x,y,mode);else LCD_DrawPoint(x,y,!mode);temp<<=1;y++;if((y-y0)==size){y=y0;x++;break;}}}}//显示一串字符void LCD_ShowStrChar(u8 x,u8 y,uc8* str,u8 size,u8 mode){u8 i=0;u8 xlen = 8;if(size == 8) xlen = 6; //实际为5列,空一列更美观else if(size == 16) xlen = 8;else return;while(str[i] != 0x00){if(x > 127) break; //超出范围了if((str[i] >= 0x20) && (str[i] <= 0x7f)){LCD_ShowOneChar(x,y,str[i],size,mode); //是可见字符}elseLCD_ShowOneChar(x,y,' ',size,mode);//非可见字符显示空格}x += xlen; //下一个位置i++; // 下一个字符}}//显示一个汉字void LCD_ShowOneHz(u8 x,u8 y,uc8* ptr,u8 size,u8 mode){u8 temp,t1,t;u16 num=0;u16 y0=y;uc8 *pdata=NULL;u8 csize=(size/8+((size%8)?1:0))*size;//得到字体一个字符对应点阵集所占的字节数//查找点阵数据if(size==16){while(GB_1616[num].Index[0] > 0x80){if((*ptr==GB_1616[num].Index[0])&&(*(ptr+1)==GB_1616[num].Index[1])) break;num++;if(num > (sizeof(GB_1616) / sizeof(FNT_GB16) - 1))return; //搜索下标约束}pdata = GB_1616[num].Msk;}else if(size==24){while(GB_2424[num].Index[0] > 0x80){if((*ptr==GB_2424[num].Index[0])&&(*(ptr+1)==GB_2424[num].Index[1])) break;num++;if(num > (sizeof(GB_2424) / sizeof(FNT_GB24) - 1))return; //搜索下标约束}pdata = GB_2424[num].Msk;}else return;//显示for(t=0;t<csize;t++){temp=pdata[t];for(t1=0;t1<8;t1++){if(temp&0x80)LCD_DrawPoint(x,y,mode);else LCD_DrawPoint(x,y,!mode);temp<<=1;y++;if((y-y0)==size){y=y0;x++;break;}}}}//显示一串汉字void LCD_ShowStrHz(u8 x,u8 y,uc8* ptr,u8 size,u8 mode){uc8 *pcStr=ptr;while((*pcStr!=0)&&(*pcStr>0x80))//判断是汉字{LCD_ShowOneHz(x,y,pcStr,size,mode);x+=size;pcStr+=2;}}/************************************************函数名称:LCD_ShowAllString功能:自适应显示字符和汉字参数:x,y,* ptr,size,mode x,y:显示坐标* ptr:显示内容size:显示尺寸支持08*05和16*08字符,16*16和32*32汉字mode:显示模式,1-正常0-反白返回值:无作者:andyLuo*************************************************///显示所有字符和汉字void LCD_ShowAllString(u8 x,u8 y,uc8* ptr,u8 size,u8 mode){uc8 *pcStr = ptr;while(*pcStr != '\0'){if(*pcStr > 0x7f){LCD_ShowOneHz(x,y,pcStr,size,mode);pcStr += 2;x += size;}else{LCD_ShowOneChar(x,y,*pcStr,size,mode);pcStr++;x += size/2;}}}//画单色图标void LCD_DrawIcon(u8 x,u8 y,uc8* icon,u8 mode) {u16 xlen,ylen,csize;u16 y0=y,i,j;u8 temp;if(icon != NULL){xlen = icon[0];ylen = icon[1];csize=(ylen/8+((ylen%8)?1:0))*xlen+2;}for(i=2;i<csize;i++){temp = icon[i];for(j=0;j<8;j++){if(temp&0x80) LCD_DrawPoint(x,y,mode);else LCD_DrawPoint(x,y,!mode);temp<<=1;y++;if((y-y0)==ylen){y=y0;x++;break;}}}}void LCD_DrawLineX(u8 x,u8 y_start,u8 y_end,u8 mode)//画水平线{u8 temp;if(x > 127 || y_start > 127 || y_end > 127) return;if(y_end < y_start){temp = y_end;y_end = y_start;y_start = temp;}for(;y_start <= y_end;y_start++) LCD_DrawPoint(x,y_start,mode);}void LCD_DrawLineY(u8 x_start,u8 x_end,u8 y,u8 mode)//画垂直线{u8 temp;if(x_start > 127 || x_end > 127 || y > 127) return;if(x_end < x_start){temp = x_end;x_end = x_start;x_start = temp;}for(;x_start <= x_end;x_start++) LCD_DrawPoint(x_start,y,mode);}void LCD_Fill(u8 x_start,u8 y_start,u8 x_end,u8 y_end,u8 mode)//填充{u8 i,j;u8 temp;if(x_start > 127 || y_start > 127 || x_end > 127 || y_end > 127) return;if(x_start > x_end){temp = x_start;x_start = x_end;x_end = temp;}if(y_start > y_end){temp = y_start;y_start = y_end;y_end = temp;}if(x_start == x_end && y_start == y_end){LCD_DrawPoint(x_start,y_start,mode);return;}if(x_start == x_end){LCD_DrawLineX(x_start,y_start,y_end,mode);return;}if(y_start == y_end){LCD_DrawLineY(x_start,x_end,y_start,mode);return;}for(i = 0;i <= (x_end - x_start);i++){for(j = 0;j <= (y_end - y_start);j++){LCD_DrawPoint(x_start + i,y_start + j,mode);}}}2、功能代码1)主函数#include "public.h"#include "led.h"#include "key.h"#include "systick.h"#include "exti.h"#include "nbxx.h"void Control_Key(void){u8 keynum = g_keyValue;g_keyValue = 0;switch(keynum){case KEY_K1_S:Led_On();break;case KEY_K2_S:Led_Off();break;case KEY_K3_L:Led_On();Delay_Ms(500);Led_Off();Delay_Ms(500);Led_On();Delay_Ms(500);Led_Off();Delay_Ms(500);break;}}int main(void){//Delay_Init();//延时函数初始化Led_Init();//初始化与LED连接的硬件接口Key_Init();LCD_Init();LCD_ShowAllString(0,0,"哈哈哈哈",16,1);LCD_ShowAllString(0,16,"哈哈哈哈",24,1);//LCD_DrawIcon(0,0,nbxx,0);LCD_RefreshGram();//更新显示while(1){Delay_Ms(10);Key_Scan(); //10ms//添加LED间隔1s闪烁的功能Control_Key();}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档