跪求16X16LED点阵汉字显示的原理图,s51单片机汇编源程序,汉字字摸提取工具,可扩展64X16点阵显示。

跪求16X16LED点阵汉字显示的原理图,s51单片机汇编源程序,汉字字摸提取工具,可扩展64X16点阵显示。,第1张

硬件资源:

1、一片AT89S51单片机

2、由4个8*8点阵LED模块组成一个16X16点阵LED

3、4个按键开关(功能预留)

4、一个REST手动复位按键

    注意:本电路板耗电较大,正常工作时LM7805稳压器比较烫手,有条件的客户可以加装散热器或者直接用5V/1A开关电源供电(跳过7805稳压器)

工作原理分析:

    从理论上说,不论显示图形还是文字,只要控制与组成这些图形或文字的各个点所在位置相对应的LED器件发光,就可以得到我们想要的显示结果,这种同时控制各个发光点亮灭的方法称为静态驱动显示方式。16×16的点阵共有256个发光二极管,显然单片机没有这么多端口,如果我们采用锁存器来扩展端口,按8位的锁存器来计算,1 6×16的点阵需要256/8=32个锁存器。这个数字很庞大,因为我们仅仅是16×16的点阵,在实际应用中的显示屏往往要大得多,这样在锁存器上花的成本将是一个很庞大的数字。

    因此在实际应用中的显示屏都不采用这种设计,而采用另一种称为动态扫描的显示方法。动态扫描的意思简单地说就是逐行轮流点亮,这样扫描驱动电路就可以实现多行(比如16行)的同名列共用一套列驱动器。具体就1 6×16的点阵来说,把所有同l行的发光管的阳极连在一起,把所有同一列的发光管的阴极连在一起(共阳的接法),先送出对应第1行发光管亮灭的数据并锁存,然后选通第l行使其燃亮一定轿敬的时间,然后熄灭;再送出第2行的数据并镇存,然后选通第2行使其燃亮相同的时间,然后熄灭;-…?第16行之后,又重新燃亮第1行,腹轮回。当这样轮回的速度足够快(每秒24次以上),由于人眼的视觉暂留现象,就能看到显示屏上稳定的图形了。

    采用扫描方式进行显示时,每行有一个行驱动器,各行的同名列共用一个列驱动器。显示数据通常存储在单片机的存储器中,按8位一个字节的形式顺序排放。显示时要把一行中各列的数据都传送到相应的列驱动器上去,这就存在一个显示数据传输的问题。从控制电路到列驱动器的数据传输可以采用并行方式或串行方式。显然,采用并行方式时,从控制电路到列驱动器的线路数量大,相应的硬件数目多。当列数很多时,并行传输的方案是不可取的。

    采用串行传输的方法,控制电路可以只用一根信号线,将列数据一位一位传往列驱动器,在硬件方面无疑是十分经济的。但是,串行传输过程较长,数据按顺序一位一位地输出给列驱动器,只有当一行的各列数据都已传输到位之后,这一行的各列才能并行地进行显示。这样,对于一行的显示过程就可以分解成列数据准备(传输)和列数据显示两个部分。对于串行传输方式来说,列数据准备时间可能相当长.在行扫描周期确定的情况下,留给行显示的时间就太少了,以致影响到LED的亮度。

    解决串行传输中列数据准备和列数据显示的时间矛盾问题,可以采用重叠处理的方法。即在显示本行各列数据的同时,传送下一行的列数据。为了达到重叠处理的目的,列数据的显示就需要具有锁存功能。经过上述分析,可以归纳出列驱动器电路应具备的主要功能。对于列数据准备来说,它应能实现串人并出的移位功能;对于列数据显示来说,应具有并行锁存的功能。这样,本行已准备好的数据打入并行锁存器进行显示时,串并移位寄存器就可以准备下一行的列数据,而不会影响本行的显示。

硬件电路大致上可以分成单片机系统及外围电路、列驱动电路和行驱动电路三部分

单片机系统及外围电路:

 伍首   单片机采用89C51或其兼容系列的芯片,采用24MHz或更高频率的晶振,以获得较高的刷新频率,使显示更稳定。单片机的串口与列驱动器相连,用来送显示数据。P1口低4位与行驱动器相连,送出行选信号;P1.5~P1.7口则用来发送控制信号。PO和P2口空着,在有必要时可以扩展系统的ROM和RAM。

列驱动电路:

    列驱动电路由集成电路74HC595构成。它具有一个8位串人并出的移位寄存器和一个8位输出锁存器的结构,而且移位寄存器和输出锁存器的控制闭橘慎是各自独立的,可以实现在显示本行各列数据的同时,传送下一行的列数据,即达到重叠处理的目的。

    它的输入侧有8个串行移位寄存器,每个移位寄存器的输出都连接一个输出锁存器。引脚SI是串行数据的输入端。引脚SCK是移位寄存器的移位时钟脉冲,在其上升沿发生移位,并将SI的下一个数据打人最低位。移位后的各位信号出现在各移位寄存器的输出端,也就是输出锁存器的输入端。RCK是输出锁存器的打人信号,其上升沿将移位寄存器的输出打人到输出锁存器。引脚G是输出三态门的开放信号,只有当其为低时锁存器的输出才开放,否则为高阻态。SCLR信号是移位寄存器的靖0输入端,当其为低时移位寄存器的输出全部为o。由于SCK和RCK两个信号是互相独立的,所以能够做到输人串行移位与输出锁存互不干扰。芯片的输出端为QA~QH.最高位QH可作为多片74HC595级联应用时,向上一级的级联输出。但因QH受输出锁存器打人控制,所以还从输出锁存器前引出了QH’,作为与移位寄存器完全同步的级联输出。

行驱动电路:

    单片机P1口低4位输出的行号经4/16线译码器4515译码后生成1 6条行选通信号线,再经过驱动器驱动对应的行线。一条行线上要带动16列的LED进行显示,按每一LED器件20 mA电流计算,16个LED同时发光时,需要320 mA电流,选用三极管8550作为驱动管可满足要求。

系统程序的设计

    显示屏软件的主要功能是向屏体提供显示数据,并产生各种控制信号,使屏幕按设计的要求显示。根据软件分层次设计的原理,可把显示屏的软件系统分成两大层:第一层是底层的显示驱动程序,第二层是上层的系统应用程序。显示驱动程序负责向屏体送显示数据,并负责产生行扫描信号和其它控制信号,配合完成LED显示屏的扫描显示工作。显示驱动程序由定时器T0中断程序实现。系统应用程序完成系统环境设置(初始化)、显示效果处理等工作,由主程序来实现。

    从有利于实现较复杂的算法(显示效果处理)和有利于程序结构化考虑,显示屏程序适宜采用c语言编写。

显示驱动程序:

    显示驱动程序在进人中断后首先要对定时器T0重新赋初值,以保证显示屏刷新率的稳定,1/16扫描显示屏的刷新率(帧频)计算公式如下:

刷新率(帧频)=1/16×T0溢出率=1/16×fosc/12(65536—to) 其中fosc为晶振频率,to为定时器T0初值(工作在16位定时器模式)。

     然后显示驱动程序查询当前燃亮的行号,从显示缓存区内读取下一行的显示数据,并通过串口发送给移位寄存器。为消除在切换行显示数据的时候产生拖尾现象,驱动程序先要关闭显示屏,即消隐,等显示数据打人输出锁存器并锁存,然后再输出新的行号,重新打开显示。

图7.4 显示驱动程序流程图

系统主程序:

    系统主程序开始以后,首先是对系统环境初始化,包括设置串口、定时器、中断和端口;然后向上滚动显示“单片机是工业中最基础的运用......”。由于单片机没有停机指令,所以可以设置系统程序不断地循环执行上述显示效果。

装配图片

以下是部分源程序,不完整,仅供参考,这是完整的资料。

**********************************

* *

* 单个16*16点阵电子屏字符显示器 *

* AT89C52 12MHZ晶振 *

**********************************

显示字用查表法,不占内存,字符用16*16共阳LED点阵,

效果:向上滚动显示19个字,再重复循环。

R1:查表偏址寄存器,B:查表首址,R2:扫描地址(从00-0FH)。

R3:滚动显示时控制移动速度,单字显示可控制静止显示的时间。

************

中断入口程序

************

ORG 0000H

LJMP START

ORG 0003H

RETI

ORG 000BH

LJMP INTT0

ORG 0013H

RETI

ORG 001BH

RETI

ORG 0023H

RETI

ORG 002BH

RETI

************

初始化程序

************

************

主程序

************

START: MOV 20H,#00H 清标志,00H为第16行开始扫描标志,01为1帧扫描结束标志

MOV A,#0FFH 端口初始化

MOV P1,A

MOV P2,A

MOV P3,A

MOV P0,A

CLR P1.6 串行寄存器打入输出端控制位

MOV TMOD,#01H 使用T0作16位定时器,行扫描用。

MOV TH0,#0FCH 1ms初值(12MHZ)

MOV TL0,#18H

MOV SCON,#00H 串口0方式传送显示字节

MOV IE,#82H T0中断允许,总中断允许

MOV SP,#70H

MAIN: LCALL DIS1 显示准备,黑屏,1.5秒

MOV DPTR,#TAB

LCALL MOVDISP 向上滚动显示一页(8个字)

INC DPH

LCALL MOVDISP 向上滚动显示一页(8个字)

INC DPH

LCALL MOVDISP 向上滚动显示一页(8个字)

AJMP MAIN

********************

多字滚动显示子程序

********************

每次8个字,入口时定义好DPTR值

MOVDISP: MOV B,#00H 向上移动显示,查表偏址暂存(从00开始)

DISLOOP: MOV R3,#07H 移动速度

DISMOV: MOV R2,#00H 第0行开始

MOV R1,B

SETB TR0 开扫描(每次一帧)

WAITMOV: JBC 01H,DISMOV1 标志为1扫描一帧结束(16毫秒为1帧,每行1毫秒)

AJMP WAITMOV

DISMOV1: DJNZ R3,DISMOV 1帧重复显示(控制移动速度)

INC B 显示字的下一行(每行2字节)

INC B

MOV A,R1 R1为0,8个字显示完

JZ MOVOUT

AJMP DISLOOP

MOVOUT: RET 移动显示结束

*****************

单字显示子程序

*****************

显示表中某个字

DIS1: MOV R3,#5AH 静止显示时间控制(16MS*#=1.6秒)

DIS11: MOV R2,#00H 一帧扫描初始值(行地址从00-0FH)

MOV DPTR,#TAB 取表首址

MOV R1,#00H 查表偏址(显示第一个字)

SETB TR0 开扫描(每次一帧)

WAIT11: JBC 01H,DIS111 为1,扫描一帧结束

AJMP WAIT11

DIS111: DJNZ R3,DIS11

RET

************

扫描程序

************

注意省略了一部分

***************

扫描文字表

***************

TAB: DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH 黑屏

DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH

DB 0F7H,0DFH,0F9H,0CFH,0FBH,0BFH,0C0H,007H,0DEH,0F7H,0C0H,007H,0DEH,0F7H,0DEH,0F7H -- 文字: 单 --

DB 0C0H,007H,0DEH,0F7H,0FEH,0FFH,000H,001H,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH

DB 0FFH,0BFH,0EFH,0BFH,0EFH,0BFH,0EFH,0BBH,0E0H,001H,0EFH,0FFH,0EFH,0FFH,0EFH,0FFH -- 文字: 片 --

DB 0E0H,00FH,0EFH,0EFH,0EFH,0EFH,0EFH,0EFH,0DFH,0EFH,0DFH,0EFH,0BFH,0EFH,07FH,0EFH

DB 0EFH,0FFH,0EFH,007H,0EFH,077H,001H,077H,0EFH,077H,0EFH,077H,0C7H,077H,0CBH,077H -- 文字: 机 --

DB 0ABH,077H,0AFH,077H,06EH,0F7H,0EEH,0F5H,0EDH,0F5H,0EDH,0F5H,0EBH,0F9H,0EFH,0FFH

DB 0FFH,0FFH,0F0H,00FH,0F7H,0EFH,0F0H,00FH,0F7H,0EFH,0F0H,00FH,0FFH,0FFH,000H,001H -- 文字: 是 --

DB 0FEH,0FFH,0F6H,0FFH,0F6H,007H,0F6H,0FFH,0EAH,0FFH,0DCH,0FFH,0BFH,001H,0FFH,0FFH

DB 0FFH,0FFH,0C0H,003H,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH -- 文字: 工 --

DB 0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,000H,001H,0FFH,0FFH,0FFH,0FFH

DB 0FBH,0BFH,0FBH,0BFH,0FBH,0BFH,0FBH,0BBH,0BBH,0B9H,0DBH,0B3H,0DBH,0B7H,0EBH,0AFH -- 文字: 业 --

DB 0E3H,0AFH,0EBH,09FH,0FBH,0BFH,0FBH,0BFH,0FBH,0BBH,000H,001H,0FFH,0FFH,0FFH,0FFH

DB 0FEH,0FFH,0FEH,0FFH,0DEH,0F7H,0C0H,003H,0DEH,0F7H,0DEH,0F7H,0DEH,0F7H,0DEH,0F7H -- 文字: 中 --

DB 0DEH,0F7H,0C0H,007H,0DEH,0F7H,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH

DB 0FEH,0FFH,0FEH,0FFH,0DEH,0F7H,0C0H,003H,0DEH,0F7H,0DEH,0F7H,0DEH,0F7H,0DEH,0F7H -- 文字: 中 --

DB 0DEH,0F7H,0C0H,007H,0DEH,0F7H,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH

DB 0E0H,00FH,0EFH,0EFH,0E0H,00FH,0EFH,0EFH,0E0H,00FH,0FFH,0FFH,000H,001H,0DDH,0FFH -- 文字: 最 --

DB 0C1H,003H,0DDH,077H,0C1H,0AFH,0DCH,0DFH,0C1H,0AFH,01DH,071H,0FCH,0FBH,0FDH,0FFH

DB 0F7H,0DFH,0F7H,0DFH,080H,003H,0F7H,0DFH,0F0H,01FH,0F7H,0DFH,0F0H,01FH,0F7H,0DFH -- 文字: 基 --

DB 000H,001H,0F7H,0DFH,0EEH,0E7H,0C0H,011H,03EH,0FBH,0FEH,0FFH,080H,003H,0FFH,0FFH

DB 0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,000H,001H,0FCH,07FH,0FCH,0BFH,0FAH,0BFH,0FAH,0DFH -- 文字: 本 --

DB 0F6H,0EFH,0EEH,0E7H,0D0H,011H,03EH,0FBH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FFH,0FFH

DB 0EFH,07FH,0EFH,07FH,0DFH,07FH,083H,003H,0BAH,0FBH,0BAH,0FBH,0B9H,0FBH,083H,07BH -- 文字: 的 --

DB 0BBH,0BBH,0BBH,09BH,0BBH,0DBH,0BBH,0FBH,083H,0FBH,0BBH,0D7H,0BFH,0EFH,0FFH,0FFH

DB 0FEH,0FFH,0FFH,07FH,0C0H,003H,0DFH,0FFH,0DDH,0FFH,0DEH,0F7H,0CFH,073H,0D7H,037H -- 文字: 应 --

DB 0DBH,06FH,0DBH,06FH,0D9H,0DFH,0BBH,0DFH,0BFH,0BFH,0A0H,001H,07FH,0FFH,0FFH,0FFH

DB 0FFH,0FFH,0E0H,003H,0EFH,07BH,0EFH,07BH,0EFH,07BH,0E0H,003H,0EFH,07BH,0EFH,07BH -- 文字: 用 --

DB 0EFH,07BH,0E0H,003H,0EFH,07BH,0EFH,07BH,0DFH,07BH,0DFH,07BH,0BFH,06BH,07FH,077H

DB 0FDH,0FFH,0FEH,0FFH,0FFH,07FH,000H,001H,0FDH,0FFH,0FDH,0FFH,0FCH,00FH,0FDH,0EFH -- 文字: 方 --

DB 0FBH,0EFH,0FBH,0EFH,0F7H,0EFH,0F7H,0EFH,0EFH,0EFH,0DFH,06FH,03FH,09FH,0FFH,0FFH

DB 0FDH,0FFH,0FEH,0FFH,0FFH,07FH,000H,001H,0FDH,0FFH,0FDH,0FFH,0FCH,00FH,0FDH,0EFH -- 文字: 方 --

DB 0FBH,0EFH,0FBH,0EFH,0F7H,0EFH,0F7H,0EFH,0EFH,0EFH,0DFH,06FH,03FH,09FH,0FFH,0FFH

DB 0FFH,05FH,0FFH,067H,0FFH,06FH,080H,003H,0FFH,07FH,0FFH,07FH,0FFH,07FH,0C1H,07FH -- 文字: 式 --

DB 0F7H,0BFH,0F7H,0BFH,0F7H,0BFH,0F4H,0DFH,0E3H,0DDH,08FH,0EDH,0DFH,0F5H,0FFH,0FBH

DB 0F9H,0BFH,0C7H,0AFH,0F7H,0B7H,0F7H,0B7H,0F7H,0BFH,000H,001H,0F7H,0BFH,0F7H,0B7H -- 文字: 我 --

DB 0F1H,0D7H,0C7H,0CFH,037H,0DFH,0F7H,0AFH,0F6H,06DH,0F7H,0F5H,0D7H,0F9H,0EFH,0FDH

DB 0FFH,007H,0C0H,06FH,0EDH,0EFH,0F6H,0DFH,0C0H,001H,0DDH,0FDH,0BDH,0FFH,0C0H,003H -- 文字: 爱 --

DB 0FBH,0FFH,0F8H,00FH,0F3H,0DFH,0F4H,0BFH,0EFH,03FH,09CH,0CFH,073H,0F1H,0CFH,0FBH

DB 0F7H,0DFH,0F9H,0CFH,0FBH,0BFH,0C0H,007H,0DEH,0F7H,0C0H,007H,0DEH,0F7H,0DEH,0F7H -- 文字: 单 --

DB 0C0H,007H,0DEH,0F7H,0FEH,0FFH,000H,001H,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH

DB 0FFH,0BFH,0EFH,0BFH,0EFH,0BFH,0EFH,0BBH,0E0H,001H,0EFH,0FFH,0EFH,0FFH,0EFH,0FFH -- 文字: 片 --

DB 0E0H,00FH,0EFH,0EFH,0EFH,0EFH,0EFH,0EFH,0DFH,0EFH,0DFH,0EFH,0BFH,0EFH,07FH,0EFH

DB 0EFH,0FFH,0EFH,007H,0EFH,077H,001H,077H,0EFH,077H,0EFH,077H,0C7H,077H,0CBH,077H -- 文字: 机 --

DB 0ABH,077H,0AFH,077H,06EH,0F7H,0EEH,0F5H,0EDH,0F5H,0EDH,0F5H,0EBH,0F9H,0EFH,0FFH

DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH 黑屏

DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH

END

这基本是一个不可枯袭租能看成的任务,按照变成的思路,你应该为每一个单独的汉子进行编写一个相应的函数,然后读入txt文档之后,进行每个字的对应比对。简单一点你禅森可以按照五笔的想法把汉没兆字进行分解,但是你读入的汉字就需要结构辨识,这也是很麻烦的。

#include <stdio.h>

#include <alloc.h>

#include <ctype.h>

#include <dos.h>

#include <dir.h>

#include <io.h>

#include <graphics.h>

#define GETADR(n,str) (str *) calloc (n,sizeof(str)) // 申请N个指定字符串长度的地址

#define W16 16

#define C16 32

unsigned char bit[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}

FILE *fi

char *dot,str[20]

main(int argc,char *argv[])

{

int i,j,nn,xc,yc,MaxX,MaxY,menul[1000]

int graphdriver=DETECT,graphmode

if(argc!=2){ //检测是否输入了2个参数

puts("LT16<???.N4>")

exit(0)

}

dot=GETADR(C16,char) //辩枯获取16个char长度的内存地址

fnmerge(str,"","",argv[1],".N4") //建立str 为路径 ,文件名是 第一个参数.N4 的文件(这里可能有bug,str没初始化)

if((fi=fopen(str,"r"))==NULL){ //打开这个文件用于输入手灶哗

puts("Can't open DATA.")

exit(0)

}

fscanf(fi,"%d",&nn)//读毕行取一个整数

if(nn<=0||nn>1000) //这个数字必须在 0~1000之间

exit(0)

for (i=0i<nni++)

fscanf(fi,"%d",&menul[i])//根据这个数字来决定继续读取的数字数量

fclose(fi)

if((fi=fopen("CLIB16.DOT","rb"))==NULL){ //打开 CLIB16.DOT 这个文件

puts("Can't open CLIB16.DOT")

exit(0)

}

initgraph(&graphdriver,&graphmode,"")// 初始化图形模式

MaxX=getmaxx()// 获得屏幕最大坐标范围

MaxY=getmaxy()

xc=0

yc=20

for(j=0j<nnj++){

i=readlibdot(menul[j]) //读取点阵数据

putchar16(xc,yc) //显示到对应的坐标系

xc+=20

if(xc>MaxX-20){

yc+=20

xc=0

if(yc>MaxY-20){

getch()

clearviewport()

yc=0

}

}

}

getch() //按任意键继续

closegraph() //关闭图形模式

}

readlibdot(int j)

{

int i0,j1,j2

long order,k1

j1=j/100

j2=j-j1*100

if(j1>=9)

j1=j1-6

k1=94*j1+j2-95

order=C16*k1

fseek(fi,order,SEEK_SET)

i0=fread(dot,C16,1,fi)

return(i0)

}

putchar16(int bx,int by) //显示readlibdot 得到的汉字(保存在dot 里面)的每个象素点阵

{

int i,j,kk,k,x1,y1

unsigned char marker

kk=0

y1=by

for(i=0i<16i++,y1++){

for(j=0j<2j++){

x1=bx+j*8

marker=*(dot+kk)

kk++

for(k=0k<8k++){

if(!(marker&bit[k]))

continue

putpixel(x1+k,y1,YELLOW)

}

}

}

return

}

点阵字库

一般我们使用16*16的点阵宋体字库,所谓16*16,是每一个汉字在纵、横各16点的区域内显示的。

不过后来又有了HZK12、HZK24,HZK32和HZK48字库及黑体、楷体和隶书字库。

虽然汉字库种类繁多,但都是按照区位的顺序排列的。前一个字节为该汉字的区号,后一个字节为该字的位号。

每一个区记录94个汉字,位号则为该字在该区中的位置。

因此,汉字在汉字库中的具体位置计算公式为:94*(区号-1)+位号-1。

减1是因为数组是以0为开始而区号位号是以1为开始的。

这仅为以汉字为单位该汉字在汉字库中的位置,那么,如何得到以字节为单位得到该汉字在汉字库中的位置呢?

只需乘上一个汉字字模占用的字节数即可,

即:(94*(区号-1)+位号-1)*一个汉字字模占用字节数,而按每种汉字库的汉字大小不同又会得到不同的结果。

以16*16点阵字库为例,计算公式则为:(94*(区号-1)+(位号-1))*32。

汉字库文该从该位置起的32字节信息即记录了该字的字模信息。

了解点阵汉字及汉字库的构成原理后,显示汉字就变得简单。以16*16点阵字库为例,

通常的方法是:将文件工作指针移到需要的汉字字模处、将汉字库文件读入一2*16数组再用for循环一位位地显示。

#include "graphics.h"

#include "stdio.h"

main()

{ int i=VGA,j=VGAHI,k

unsigned char mat[16][2],chinease[3]="我"

FILE *HZK

if((HZK=fopen("hzk16","rb"))==NULL)exit(0)

initgraph(&i,&j,"")

i=chinease[0]-0xa0j=chinease[1]-0xa0/*获得区码与位码*/

fseek(HZK,(94*(i-1)+(j-1))*32l,SEEK_SET)

fread(mat,32,1,HZK)

for(j=0j<16j++)

for(i=0i<2i++)

for(k=0k<8k++)

if(mat[j][i]&(0x80>>k)) /*测试为1的位则显示*/

putpixel(i*8+k,j,WHITE)

getch()

closegraph()

fclose(HZK)

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12421515.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存