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

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

硬件资源:

1、一片AT89S51单片机

2、由4个88点阵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位与行驱动器相连,送出行选信号;P15~P17口则用来发送控制信号。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位定时器模式)。

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

图74 显示驱动程序流程图

系统主程序:

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

装配

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

;

;

; 单个1616点阵电子屏字符显示器

; AT89C52 12MHZ晶振

;

;显示字用查表法,不占内存,字符用1616共阳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 P16 ;串行寄存器打入输出端控制位

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 ;显示准备,黑屏,15秒

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#=16秒)

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

程序是按行来处理的,每行是16个点阵,需要2个字节来存储,根据程序表达的意思,点阵表也是按行来建立的,而每次取数只能一个字节,所以i这个行号需要乘以2,ia是每行的字节位置,取值范围为1,2

到目前为止,我们编写的C 程序,其用于人机交互的提示或菜单都是英文

的,那么如何在没有汉化的Turbo C 集成开发环境下编制显示汉字的程序呢?

解决这一编程问题,我们首先必须了解有关汉字编码及字库的知识。根据对汉字使

用频率的研究,可把汉字分成高频字(约100 个),常用字(约3000 个),次常用字(约4000 个),

罕见字(约8000 个)和死字(约45000 个),即正常使用的汉字达15000 个。我国1981 年公布

了《通讯用汉字字符集(基本集)及其交换码标准》GB2312-80 方案,把高频字、常用字、和

次常用字集合成汉字基本字符集(共6763 个),在该集中按汉字使用的频度,又将其分为一

级汉字3755 个(按拼音排序)、二级汉字3008 个(按部首排序),再加上西文字母、数字、图

形符号等700 个。

汉字编码:

区位码

国家标准的汉字字符集(GB2312—80)在汉字 *** 作系统中是以汉字库的形式提供的。汉

字库结构作了统一规定,即将字库分成94 个区,每个区有94 个汉字(以

位作区别)每一个汉字在汉字库中有确定的区和位编号(用两个字节),这就是所谓的区位码

(区位码的第一个字节表示区号,第二个字节表示位号,因而只要知道了区位码,就可知道

该汉字在字库中的地址,每个汉字在字库中是以点阵字模形式存储的,如一般采用16×16

点阵形式,每个点用一个二进位表示,存1 的点,当显示时,可以在屏上显示一个亮点,存

0 的点,则在屏上不显示,这样把存某字的16×16 点阵信息直接用来在显示器上按上述原

则显示,则将出现对应的汉字。

内码

汉字使用两字节表示,国家制定了统一标准,称为国标码。国标码规定,每个字节使用

后面7 位,第一位为0。为了区别于英文的ASCII 码,国标码在计算机上使用的时候,规定

汉字每个字节第一位设置为1,以表示该两字节为汉字,称为内码。以“大”字为例子:

国标码3473H: 0 0 1 1 0 1 0 0 0 1 1 1 0 0 1 1

内码B4F3H: 1 0 1 1 0 1 0 0 1 1 1 1 0 0 1 1

国标码与内码有一定的转换公式,即16 进制的区位码,两个字节各加80H,就成为了

国标码。

汉字字模在字库中存放的位置根据汉字的区位码来确定,内码是汉字在机内的表示。由

于区位码和内码存在固定的转换关系,所以当在支持汉字输入的系统中,键盘输入的汉字内

码即在程序中存在,将其转换为区位码,再从字库中找到对应的汉字字模,然后再用有关的

位 *** 作和循环语句,对每个字节的每一位进行判断,如同过滤一样,如果某位是1,则按设

置的颜色在屏幕的相应位置画点(用graphicsh 中的显示象素点的函数putpixel()),若某位

为0,则不画点,这样就可按预先设置的颜色在相应位置显示出该汉字来。

内码到区位码的转换

若汉字内码为十六进制数h2h1l2l1,则区号qh 相位号wh 分别为:

qh= h2h1-0xa0;

wh= l2l1-0xa0;

若用十进制表示内码为dld2,则

qh=dl-l60;

wh=d2-160;

即区位码qw 为:

qw=100(d1-160)十(d2-160);

反过来,若已经知道了区位码qw。则也可求得区号和位号:

qh=qw/100;

wh=qw-100qh;

因而该汉字在汉字库中离起点的偏移位置(以字节为单位),可计算为:

offset=(94(qh-1)+(wh-1)) 32;

注意:字库中每1 区有94 个字符。

这样,就可以找寻到文件的偏移量,读出一个char bytes[32]数组。这样bytes 数组中则

存了要显示汉字的16×16 点阵字模,然后将字模按行扫描的办法,通过循环用putpixel()函

数在屏幕设定位置显示出象点,因而组合成一个显示的汉字。

要用proteus仿真16×16点阵屏,需要用4块8×8点阵拼成,为了能够拼接,每一块8×8点阵的引脚必须加网络标号,而不能用导线连接了。先放四块,每块引脚都加网络标号,最后将四块拼在起。见下图

/

Header:

File Name: 1616点阵滚动显示汉字

Author:

Date:

/

#include <AT89X52H>

unsigned char code digittab[]={

0x40,0x04,0x47,0xC2,0x44,0x41,0x44,0x42,0xFE,0x7C,0x40,0x00,0x01,0xF2,0x7D,0x22,

0x49,0x22,0x49,0x22,0x4F,0xFE,0x49,0x22,0x49,0x22,0xFD,0x26,0x41,0xF3,0x00,0x00 / qiang---竖直向下从左到右 /

};

unsigned char code lie[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

unsigned int timecount;

unsigned char cnta;

unsigned char cntb;

unsigned char k,i=0;

void main(void)

{

TMOD=0x01;

TH0=(65536-3000)/256;

TL0=(65536-3000)%6;

TR0=1;

ET0=1;

EA=1;

k=0;

while(1)

{;

}

}

void t0(void) interrupt 1 using 0

{

P0=0x00;

P2=0x00;

TH0=(65536-3000)/256;

TL0=(65536-3000)%6;

P1=lie[k];

k ;

if(k==16) k=0;

l ;

P0=digittab[i];/此处和字模有关/

i ;

P2=digittab[i];

i ;

if(i==32)

i=0 ;

}

很简单/1616点阵屏的显示/

#include <reg51h>

#include <intrinsh>

#define DATAOUT P2 //指定P2口做为输出

sbit DATA=DATAOUT^0; //列数据输出位

sbit SCLH=DATAOUT^1; //列扫描时钟位

sbit SCLT=DATAOUT^2; //列数据锁存位

sbit AB=DATAOUT^4; //行数据输出位

sbit SCK=DATAOUT^5; //行扫描时钟位

unsigned char lhj[32];//32字节RAM做为1616点阵屏显示缓存

void display();//做为点阵扫描函数,将显示缓存的数据输出到点阵屏

void displayS(unsigned int timer);//指定时间扫描显示

void displaymove(unsigned char lp,unsigned char c,unsigned char timer);//显示汉字内容的移动效果,LP指向要显示第一个字的首地址,C表示显示字的个数,

//timer是移动的速度

void displaymovetb(unsigned char din,unsigned char lp,unsigned char timer);

//上下移动内容,din:1为向下,0为向上,lp指向要移入的内容,timer为移动速度

void delay(unsigned int a);//延时子函数

code unsigned char lin[32]={0x04,0x20,0x04,0x20,0xff,0xfe,0x04,0x20,//汉字"英"的点阵数据。汉字点阵数据,可用汉字库点阵生成软件获得

0x01,0x00,0x1f,0xf0,0x11,0x10,0x11,0x10,

0x11,0x10,0xff,0xfe,0x01,0x00,0x02,0x80,

0x04,0x40,0x08,0x30,0x10,0x1c,0x20,0x08};

code unsigned char yang[32]={//达

0x00,0x00,0x40,0x80,0x30,0x80,0x10,0x80,

0x0f,0xfc,0x00,0x80,0x00,0x80,0xe0,0x80,

0x21,0x40,0x21,0x20,0x22,0x18,0x24,0x0c,

0x28,0x08,0x50,0x02,0x8f,0xfc,0x00,0x00};

code unsigned char dian[32]={//通

0x40,0x00,0x27,0xf8,0x20,0x90,0x00,0x60,

0x07,0xf8,0x04,0x48,0xe7,0xf8,0x24,0x48,

0x24,0x48,0x27,0xf8,0x24,0x48,0x24,0x68,

0x24,0x50,0x50,0x00,0x8f,0xfe,0x00,0x00};

code unsigned char zi[32]={//讯

0x40,0x00,0x27,0xf8,0x31,0x08,0x21,0x08,

0x01,0x08,0xf1,0x08,0x17,0xe8,0x11,0x08,

0x11,0x08,0x11,0x08,0x11,0x08,0x11,0,

0x15,0,0x19,0,0x11,0x04,0x00,0x00};

code unsigned char LY[32]={//图案数据

0x00,0x00,0x30,0x00,0x30,0x20,0x30,0x30,

0x30,0x18,0x30,0x0C,0x30,0x06,0x3F,0x7F,

0x3F,0x7F,0x00,0x06,0x00,0x0C,0x00,0x18,

0x00,0x30,0x00,0x20,0x00,0x00,0x00,0x00};

void main(void) //主入口函数

{

unsigned char i=0,j=0;

for(i=0;i<32;i++)

lhj[i]=LY[i];//将图案数据复制到显示缓存

while(1){

displayS(2); //显示图案约2秒

displaymove(lin,4,7);//将从"英"开始的四个汉字从右向左移动

displayS(1); //等持约1秒

displaymovetb(1,0,10); //将点阵上显示的内容向下以10的速度移出,补上0,即清空显示屏

displayS(1); //等待1秒

displaymovetb(0,lin,10); //达"达"字以10的速度向上移动

displaymovetb(0,yang,10); //将"通"字以10的速度向上移动

displaymovetb(0,dian,10); //将"讯"字以10的速度向上移动

displaymovetb(0,zi,10); //将"子"字以10的速度向上移动

displaymovetb(0,0,10); //以10的速度向上清空

displayS(1); //等待1秒

displaymovetb(1,LY,10); //将"图案"以10的速度向下移动

}

}

void display()//显示

{

unsigned char i,ia,j,tmp; //定义变量

DATAOUT=0XFF; //置位高电平做准备

AB=0; //将行数据位清0,准备移位

for(i=0;i<16;i++){ //循环输出16行数据

SCK=0; //为行移位做准备

SCLT=0; //为列锁存做准备

for(ia=2;ia>0;){ //每行16个点,循环位移两个字节

ia--; //循环两次

tmp=~lhj[i2+ia]; //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成,

//电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据

for(j=0;j<8;j++){ //循环两次,每次移一个字节,

SCLH=0; //为列移位做准备

DATA=tmp&0x01; //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位

tmp>>=1; //将数据缓冲右移一位,为下次输出做准备

SCLH=1; //将DATA上的数据移入寄存器

} //移入单字节结束

} //移入两个字节结束

DATAOUT|=0X24; //此句可以用以下两句来理解,如果不将两句合为一句,将出现拖影现像

//SCK=1; //SCK拉高,行数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)

//SCLT=1; //SCLT拉高,将数据锁存输出到相应列的点阵发光管显示,显示一行后将保持到下一行显示开始

AB=1; //行数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位,

//移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱

}

j=64;

while(j--); //每一行的显示,保持了两字节的移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度

SCK=0; //

SCK=1; //将最后一行数据移出

}

void displayS(unsigned int timer) //指定时间扫描显示

{

unsigned char i;

while(timer--){ //当timer=1时,大约1秒时间

i=130;

while(i--)

display();

}

}

void displaymove(unsigned char lp,unsigned char c,unsigned char timer)//显示汉字内容的移动效果,LP指向要显示第一个字的首地址,C表示显示字的个数,

//timer是移动的速度

{

unsigned char i=0,j=0,ia=0;

unsigned int tmp=0,timerc=0;

unsigned char tmp2[16];

c=2; //因一个汉字由32字节组成,而移位显示,要分开半个汉字16字节处理,因此将这里乘以2

for(i=0;i<16;i++)

tmp2[1]=0; //将缓冲区清0,

while(c){ //循环处理

if(lp!=0){ //当lp指向的地址为0时,直接用组缓冲0补上,效果是将当前显示的内容移出

tmp=c%2; //取余,目的是为了判断处理汉字的前半部份还是后半部份

for(i=0;i<16;i++){

tmp2[i]=lp[i2+tmp]; //取半个汉字点阵数据,16字节

}

if(tmp) //当tmp为1时,表时一个字数组处理完成,将地址转到下一个字

lp+=32;

}

//--------------

tmp=8; //变量再次利用

while(tmp){ //循环8次,是将下一个字的前半部份的字节数据移入显示缓冲

ia=0; //做为点阵数组的元素

for(i=0;i<16;i++){//移动是16行同时移,因此要处理16个字节

lhj[ia]<<=1; //移当前显示缓冲的前半行字节

if(lhj[ia+1]&0x80) //判断后半行字节的高位是否为1,是移入前半行字节低位,否则不处理

lhj[ia]++;

ia++;

lhj[ia]<<=1; //移当前显示缓冲的后半行字节

if(tmp2[i]&0x80) //判断下一个要显示汉字的前半行字节的高位是否为1,是移入,否则不处理

lhj[ia]++;

ia++;

tmp2[i]<<=1; //下一个要显示汉字的半行字节向高位移一位,准备下一次取位

}

tmp--;

timerc=timer; //处理完16行,调用显示函数更新点阵

while(timerc--) //循环做为处理的速度,即移动的速度

display();

}

//----------

c--; //移完一半,进入下一半或下一个汉字,直到结束

}

}

void displaymovetb(unsigned char din,unsigned char lp,unsigned char timer)

//上下移动内容,din:1为向下,0为向上,lp指向要移入的内容,timer为移动速度

{

unsigned char i=0,j=0,ia=0;

unsigned int tmp=0,timerc=0;

if(din){ //判断移动方向,向下

ia=32; //要移入第一个汉字的数组元素

i=16; //行索引

while(i--){ //逐行处理

j=30;

while(j){

j--;

lhj[j+2]=lhj[j]; //将上一行的内容复制到下一行,每两行内容相隔四个字节,复制15行

}

if(lp==0){ //最后一行的处理,判断移入的内容是否为空,是用0移入

lhj[0]=0;

lhj[1]=0;

}

else{ //否则,取字数组处理

ia--;

lhj[1]=lp[ia];

ia--;

lhj[0]=lp[ia];

}

timerc=timer; //处理完16行,调用显示函数更新点阵

while(timerc--) //循环做为处理的速度,即移动的速度

display();

}

}

else{ //移动方向,向上

ia=0; //向上移动,移入汉字从低位开始

for(i=0;i<16;i++){ //处理16行

for(j=0;j<30;j++) //将下一行的内容复制到上一行,每两行内容相隔四个字节,复制15行

lhj[j]=lhj[j+2];

if(lp==0){ //最后一行的处理,判断移入的内容是否为空,是用0移入

lhj[30]=0;

lhj[31]=0;

}

else{ //否则,取字数组处理

lhj[30]=lp[ia];

lhj[31]=lp[ia+1];

ia+=2;

}

timerc=timer; //处理完16行,调用显示函数更新点阵

while(timerc--) //循环做为处理的速度,即移动的速度

display();

}

}

}

void delay(unsigned int a) //延时

{

while(a--);

}

有字模软件修改你想要显示的字,程序要字模改动别告诉我你不懂

上面两块,下面两块

将上面两块的行线和行线连起来

下面两块的行线于行线连起来

就是控制上面第一行的与上面第一行的连起来,第二行于第二行的连起来。。。。。。第八行的与第八行的连起来,

下面第一行与下面第一行连起来

将上面与下面的列线连起来

控制上面第一列与控制下面第一列的连起来,第二列于第二列连起来

最后有16根行线,16根列线

以上就是关于跪求16X16LED点阵汉字显示的原理图,s51单片机汇编源程序,汉字字摸提取工具,可扩展64X16点阵显示。全部的内容,包括:跪求16X16LED点阵汉字显示的原理图,s51单片机汇编源程序,汉字字摸提取工具,可扩展64X16点阵显示。、单片机高手给点拨下,下面是16x16点阵的显示子程序的一部分,tmp=~date[i*2+ia],i*2是代表什么意思、C语言是如何用16点阵方法输出汉字的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9491071.html

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

发表评论

登录后才能评论

评论列表(0条)

保存