玩转16×16LED点阵屏
在单片机发烧友圈子中,有关用单片机驱动LED、数码管、LCD等的入门文章随处可见,有关驱动LED点阵屏的文章则不多,至于真正能够显示一个国标汉字的16×16点阵屏的则更少。本文向大家介绍一款用ATmega48单片机控制16×16点阵屏显示汉字,并可做出多种动画特效的实验小系统,让你尽显编程技巧,尽情玩转16×16点阵屏这一汉字显示最小单位。
原理说明
1.计算机显示汉字的基本原理
计算机显示屏上的汉字实际上是由一组有序排列的像素构成的。如果有笔画的像素不亮,而其周围的像素都是亮的,就能看到一个黑色笔画的汉字。能够清楚地显示一个汉字的最小像素数是16×16=256,这是DOS时代就定下的规矩。现在的Windows有了矢量字体,大大丰富了汉字的显示,能在屏幕上不失真地显示汉字书法的美。
现在回到16×16LED点阵屏,我们的任务是在这块方寸之地显示一个汉字,而且要能上下、左右地滚动,首先要解决的问题就是如何存放这256个汉字笔画像素的信息。
图11.1
图11.2 系统原理图
当初DOS绝不是随便定下16×16,即16行与16列的标准的。在计算机世界里,8位(bit)组成一个字节(byte),而双字节则构成一个字。于是办法有了,用两个字节共16位来代表一行的信息,16行共32个字节,用某位是0还是1来控制点亮还是熄灭对应位置的像素,就能在16×16LED屏上显示汉字,存放汉字笔画信息的问题解决了。
下一个要解决的问题是如何得到一个汉字的点阵信息。图11.1所示是中国象棋中的帅字,我们将一个汉字的显示区域划分成4个8×8的子区,即A区、B区、C区、D区。显而易见,可以用一个字节来代表一个子区中一行的信息,32个字节就能表示4个子区。获取点阵信息的方法也就随之产生了,我们只要按照某种顺序,依次将这些信息存入一个容量为32的数组就可以了。存取的顺序可以有多种,比如A、B、C、D或A、C、B、D等,存取顺序的不同,没有大的区别,只是影响将来的编程思路。以图11.1为例,我们按横向每行(区的顺序是A、B、C、D)的顺序取得的数据如下(C 语言的表示方式):
0x0F,0xF0,0x30,0x0C,0x44,0x22,0x44,0x22,
A B A B A B A B
0x95,0xFD,0x95,0x25,0x95,0x25,0x95,0x25,
A B A B A B A B
0x95,0x25,0x95,0x25,0x85,0x25,0x89,0x2D,
C D C D C D C D
0x50,0x22,0x40,0x22,0x30,0x0C,0x0F,0xF0
C D C D C D C D
图11.3 4个8×8LED模块与单片机端口的寻址关系
2.系统原理
从图11.2的原理图中可以看出,单片机ATmega48的3个端口几乎全部用上。端口D和端口B分别控制纵向左(A区和C区)、右(B区和D区)两组8×8点阵模块的列寻址。端口C则通过一个74HC154译码器将4位地址值转换成15个行控制信号。在硬件设计上,这15个控制信号也被分成两组,分别控制横向的上(A区和B区)、下(C区和D区)两组8×8点阵模块的行寻址。
4个8×8LED模块与单片机端口的寻址关系如图11.3所示。搞清这些关系将是软件设计的基础。
硬件介绍
1.单片机主控板
图11.4所示的是AVR单片机最小系统,因为引脚定义完全一致,所以可换插ATmega48/88/168/328系列单片机和ATmega8单片机。这块板子的电路图见图11.5。
图11.4 AVR单片机最小系统
图11.5 AVR单片机最小系统电路图
该板子的一个设计特点是“资源全开放”,因为ATmega48系列单片机具有引脚功能复用的特点,即所有的B端口、D端口和C端口的6个引脚通过插针全部对外开放,使用者负责定义每个引脚的工作模式和状态。例如,在你的程序中使用了串口功能,D端口的PD0 和PD1两个引脚就不能用作I/O。同理,如果系统使用了外部晶体振荡器,则PB7和PB6也不能用作他用。从图4可以看出,端口B和D都将8个引脚通过排针引了出来。而端口C的设计有些独特,不但将引脚引出,还增加了一排VCC插针和一排GND插针,这主要是为了方便接插伺服电机和众多传感器而设计的。大家知道,伺服电机3根引线的排列顺序是信号、VCC、GND,很多传感器也是如此排列3根引脚,而且端口C的引脚从0至5又具有ADC的第二功能。如此一来,需要接插伺服电机和传感器时就方便多了。板子上还提供专门的位置将串口引出。而外部晶体振荡器则通过开关控制其是否接入系统。当然,改变系统振荡源时不要忘记相关标志位的设置。ISP下载部分则是标准的10针插座,可接插多种下载器。
2. 16×16点阵屏模块
这块板子上的主要元件就是4个8×8LED模块和一只74HC154地址译码器,如图11.6所示。本文不准备详述点阵模块这种发光元件的基本原理,爱好者们可以找到很多相关文章,并参照本文前面的说明自行设计搭建。需要强调的是,要搞清模块的引脚排列,不同厂家的产品并不完全相同。另外要搞清模块是共阴的还是共阳的,这主要决定着地址译码器的选择。
图11.6 16×16点阵屏模块
本文中用到的这块板子使用的是共阳模块,就是当某列的引脚为高电位,而某行的引脚为低电位时,处于该行与该列交叉点的LED被点亮。74HC154译码器的输出为低电平有效,因此,当单片机端口B和D的某个引脚输出高电位即1时,此时74HC154译码器的某个引脚有效(输出低电平),则处于交叉点的LED被点亮。
3.系统搭建
图11.7 系统搭建方法
系统搭建非常简单,如图11.7所示。使用两根8线排缆将单片机主控板的D端口和B端口分别与16×16点阵屏的对应端口插接,用一组4线杜邦头的跳线将单片机主控板C端口的0~3 与16×16点阵屏的4位地址线接插,另用一根电源引线通过单片机主控板C端口任意一组VCC、GND插针引出接入16×16点阵屏,即可完成系统搭建。
程序
所谓程序就是数据+算法。首先设计一个有效的数据结构,再根据硬件电路的寻址方式,有序地将数据送达正确的点位(算法),我们要求的图案就显示出来了。
笔者选取了几个例子与爱好者朋友分享,作为抛砖引玉,相信朋友们会设计出更丰富多彩的程序。
一个汉字垂直向上移动例程序
#include
#include
#include
#pragma data:eeprom
//中国象棋中的帅字点阵,存储在EEPROM中
char table[]={
0x0F,0xF0,0x30,0x0C,0x44,0x22,0x44,0x22, 0x95,0xFD,0x95,0x25,0x95,0x25,0x95,0x25, 0x95,0x25,0x95,0x25,0x85,0x25,0x89,0x2D, 0x50,0x22,0x40,0x22,0x30,0x0C,0x0F,0xF0};
#pragma data:data
//一个粗略的延时子程
void delay_1ms(void)
{
unsigned int i;
for (i=1;i < 1000;i++) ;
}
//端口初始化函数
void port_init(void)
{
PORTB=0x00;
DDRB=0xFF;
PORTC=0x00;
DDRC=0x0F;
PORTD=0x00;
DDRD=0xFF;
}
void main(void)
{
char i,K,L;
char B_port[32];
port_init();//数据准备
for (i=0;i <32;i++)
{//从EEPROM 读出数据,初始化数组B_port。
EEPROM_READ(i, B_port[i]);
}
K=0;//初始化计数变量K
while(1)//无限循环
{
for(L=0;L<10;L++)//滚屏速度控制
{
for(i=0;i<16;i++)//点阵屏刷新
{
PORTD=B_port[i*2];//送端口D
PORTB=B_port[i*2+1];//送端口B
PORTC=i;//行寻址
delay_1ms();
}
}
//将数组中的数据都顺序向前移动一排
for (i=0;i < 29;i+=2)
{
B_port[i]=B_port[i+2];
B_port[i+1]=B_port[i+3];
}
//从EEPROM中取出两个字节,填充到数组最后两个单元中
EEPROM_READ(K, B_port[30]);
K++;
EEPROM_READ(K, B_port[31]);
K++;
if (K >=32)//行更新计数
K=0;
}
}
1.数据准备
从本文前述关于16×16点阵汉字信息的提取,结合实例中的硬件寻址方式,大家不难想象,只要将这32个字节顺序存入一个数组,然后每两个字节为一组送往D端口和B端口形成列地址,再通过C端口给出行地址,对应行的LED将被选中,位于D、B端口字节中高电位的LED被点亮,其他的不亮,该行的点阵就形成了。如此动作16次,将32个字节依次送出,一帧(16×16点阵)的图案就显示出来了。我们只要以小于1ms的时间间隔循环做这组动作,一个汉字(或图案)就能稳定地显示在点阵屏上。
2.文字上下滚动
让汉字在16×16点阵屏上、下滚动(垂直移动)是最为简单的动作。
向右水平移动汉字例程序
#include
#include
//中国象棋中的帅字点阵,以数组形式存储在RAM中
char table[]={
0x0F,0xF0,0x30,0x0C,0x44,0x22,0x44,0x 22,
0x95,0xFD,0x95,0x25,0x95,0x25,0x95,0x 25,
0x95,0x25,0x95,0x25,0x85,0x25,0x89,0x 2D,
0x50,0x22,0x40,0x22,0x30,0x0C,0x0F,0x F0};
//工作数组
char A_array[16][4];
//一个粗略的延时子程
void delay_1ms(void)
{
unsigned int i;
for (i=1;i < 1000;i++) ;
}
//端口初始化函数
void port_init(void)
{
PORTB=0x00;
DDRB=0xFF;
PORTC=0x00;
DDRC=0x0F;
PORTD=0x00;
DDRD=0xFF;
}
//数据准备函数
void A_arr_prepare(void)
{
char i,j;
for (i=0;i < 16;i++)
{
j=i*2;
A_array[i][3]=table[j];
A_array[i][2]=table[j+1];
A_array[i][1]=0;
A_array[i][0]=0;
}
}
void main(void)
{
char i,L;
char m0,m1,m2,m3;
//用于存储移出位的变量
port_init();
//数据准备
A_arr_prepare();
while(1)
{
for(L=0;L < 10;L++)//滚屏速度控制
{
for(i=0;i<16;i++)//点阵屏刷新
{
PORTD=A_array[i][1];
PORTB=A_array[i][0];
PORTC=i;
delay_1ms();
}
}
//整屏数据右移一列
for (i=0;i < 16;i++)
{
if (A_array[i][0] & 0x01==1)
//保留移出位
m0=0x80;//如果是1,保留在高位。
else
m0=0;
if (A_array[i][1] & 0x01==1)
m1=0x80;
else
m1=0;
if (A_array[i][2] & 0x01==1)
m2=0x80;
else
m2=0;
if (A_array[i][3] & 0x01==1)
m3=0x80;
else
m3=0;
A_array[i][3]=A_array[i][3]>>1;//字节右移一位
A_array[i][3]=A_array[i][3] | m0;//将前一字节的高位移入
A_array[i][2]=A_array[i][2]>>1;
A_array[i][2]=A_array[i][2] | m3;
A_array[i][1]=A_array[i][1]>>1;
A_array[i][1]=A_array[i][1] | m2;
A_array[i][0]=A_array[i][0]>>1;
A_array[i][0]=A_array[i][0] | m1;
}
}
}
向上滚动时的流程图如图11.8所示,其实现程序在ICC 7平台调试通过。这个小例程使用EEPROM存储汉字点阵信息,主要是作为练习,爱好者也可以使用RAM中的数组省去EEPROM的读动作。
3. 文字左右移动
左右移动(水平横向移动)稍微复杂一些,因为要进行数据位的循环移动。在下面的例子中,我们使用一个二维数组A_array[16][4],目的是在汉字水平移动时有一个字的空格,当然你也可以试着只留半个空格或不留空格。此例程没有使用EEPROM,而是在RAM中建立一个存放点阵数据的数组table[ ]。在数据准备阶段,将数组table[ ]中的数据导入数组A_array[16][4]的后两列,即A_array[16][3]和A_array[16][2]。显示完一帧后,再对这16组4个字节向右移位,实现整帧的右移。数组A_array[16][4]的移动动作顺序如图11.9所示,该例程的流程图如图11.10所示。
图11.8 文字向上滚动的流程图
图11.9 数组A_array[16][4]的移动动作顺序
图11.10 文字向右移动的流程图
拓展练习
本文仅对16×16点阵屏做一浅显介绍,相信单片机爱好者可以借助这个小平台玩出许多花样,例如对角移动、中心开花、中心会聚、对称分开或合拢,以及多字连续移动等。文中例程序是用C语言写的,也可以使用BASIC语言,里面的一些函数可以改成汇编语言的,将会显著提高效率。现在,很多爱好者玩起了Arduino,同样可以驱动这个16×16点阵屏,只是由于Arduino端口开放得不全,所以要加锁存器,并分步传送数据,程序会稍微复杂些,但基本思路是相似的。
实验分享——单片机控制LED点阵实验
一、设计目的
设计一个单片机控制的LED点阵显示系统,基本要求为:LED点阵能够“心型”图形。然后在此基础上,可以自行增加功能,例如但不限于:交替显示“心型”一个自定义图形。(自定义图形可选但不限于下列图形:Δ、▲、△、◆、◇、★、☆、♀、♂等)。所谓交替显示是指点阵中依次显示A、B、C三种文字或图形(每个图形点亮若干时间)并循环往复。
二、设计任务及要求
1.学习课程资料中附上的“普中51单片机开发攻略--A5(V5.5).pdf” 其中的第16 章LED 点阵实验。
2.学习完该内容后,设计一个单片机控制的LED点阵显示系统,基本要求为:LED点阵能够“心型”图形。然后在此基础上,同学们可以自行增加功能,例如但不限于:交替显示“心型”一个自定义图形。(自定义图形可选但不限于下列图形:Δ、▲、△、◆、◇、★、☆、♀、♂等)。所谓交替显示是指点阵中依次显示A、B、C三种文字或图形(每个图形点亮若干时间)并循环往复。
3.使用单片机开发板可能需要用到的知识及软件:
详见“普中51单片机开发攻略--A5(V5.5).pdf” --2.2 开发板使用方法(18到25页内容)
三、方案设计
首先将符号进行字模提取,并且编写程序,将单片机的2口和3口作为输出口,分别接入LED点阵的上下两排引脚。使用扫描的方式,使LED点阵可以正常的显示。进一步设计,增加延时函数,使得在一个图形显示完后,能够紧接着显示另一个图像,并循环往复,最终完成设计。
(一)前期准备
心形点阵图
图片
图片
图片
(二)软件设计
#include<reg52.h>
char code hang0[]={0x18,0x24,0x42,0x84,0x84,0x42,0x24,0x18};
char code hang1[]={0x18,0x24,0x42,0x81,0x81,0x42,0x24,0x18};
char code hang2[]={0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x3C,0x18};
char code lie1[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
char code lie0[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE};
int i;
int num;
int m;
int n;
int c;
void delay(int a)
{
while(a--);
}
void main(){
int t;
t=6;
n=0;
while(1){
n++;
c=n%2;
for(i=0;i<1500;i++){
if(i<500)
{
for(num=0;num<8;num++){
if(c==0){
P1=lie0[num];
}else{
P3=lie0[num];
}
P2=hang0[num];
delay(t);
}
}
if(i>=500&&i<1000)
{
for(num=0;num<8;num++){
if(c==0){
P1=lie0[num];
}else{
P3=lie0[num];
}
P2=hang1[num];
delay(t);
}
}
if(i>=1000)
{
for(num=0;num<8;num++){
if(c==0){
P1=lie0[num];
}else{
P3=lie0[num];
}
P2=hang2[num];
delay(t);
}
}
}
}
}
四、调试及结果
实物图1
实物图2
五、设计总结
单片机控制LED点阵的实验设计总结如下:
1. 材料准备:准备LED点阵、单片机开发板(如Arduino、Raspberry Pi等)、面包板、导线等。
2. 连接电路:将LED点阵与单片机开发板连接起来,确保正确的极性和接线。通常需要使用导线和电阻来连接。
3. 编程:编写控制LED点阵的程序,包括控制LED灯的亮灭、行列扫描和显示图案等功能。具体的编程语言和代码逻辑根据使用的单片机和开发板而有所不同。
4. 上传程序:将编写的程序上传到单片机开发板上。
5. 测试:开启单片机开发板,观察LED点阵是否按照预期的方式显示。可以测试不同的图案、动画或文字,并确保LED点阵能够正确显示。
6. 调整和改进:根据测试结果进行调整和改进,确保LED点阵能够准确显示设计好的图案。
总的来说,单片机控制LED点阵的实验设计需要包括硬件连接和软件编程,通过这个实验可以更好地理解单片机控制外围设备的原理,并且锻炼了编程能力和电路连接能力。
相关问答
英语翻译基于 单片机 的 LED显示屏 是由多个独立的 LED 发光二极管...[最佳回答]IsbecomesbasedonthemonolithicintegratedcircuitLEDdisplaymonitorbymanyindependentLEDli...
led点阵 具体点亮过程.要有8*8的点阵图来 显示 _作业帮[最佳回答]P2\P0.01234567.000000000//0X00.100010000//0X10.200110000//0X30.3...
LED显示屏 工作原理是什么? - 懂得LED显示屏是利用发光二极管点阵模块或像素单元组成的平面式显示屏幕。由于它具有发光率高、使用寿命长、组态灵活、色彩丰富以及对室内外环境适应能...
为什么 单片机点阵 模块亮不了?单片机点阵模块亮不了的原因可能有多种。首先,可能是电源供电不足或者接线不正确导致模块无法正常工作。其次,可能是程序编写错误或者单片机与点阵模块之间的...
51 单片机 8*8 点阵 由下向上 显示 0~9?P1口为行,P2口为列;numb[10][8];//0~9的点阵数据由下向上显示,即从P1.7开始驱动行,然后是P1.6,,,P1.0;for(i=0;i<10;i++){a=0x80;for(...
谁有 led显示 系统设计方案?-设计本有问必答1、单元箱1)箱体尺寸:(宽)1024mm×(高)768mm2)箱体分辨率:(宽)64点×(高)48点3)箱体密度:3072点/箱4)箱体重量:防水密封箱≤65kg/m22、.....
LED点阵显示器 一般要怎样控制?针对 LED 单元,8x8那种。选通用7...针对LED单元,8x8那种。选通用74HC138、数据STB和ABCD信号那种。举报手机HTCHTC8X4人讨论8464次围观关注问题写回答讨论回答(4)zengcanqiang...
51 单片机点阵 线路接法?51单片机点阵接法具体看所使用的点阵型号和具体电路设计。一般来说,点阵的接法通常涉及以下几个方面:1.供电接法:点阵需要一个合适的电源供电。通常情况下,...
12864 点阵 液晶屏不 显示 ?1、这种情况是新手最常碰到的问题。首先,对应硬件PDF文档确定你的接线没有任何问题,如果是51单片机,用P0口一定要加10K的上拉电阻,不然就算程序正常,也无法...
如何利用 单片机 设计八路抢答器?用单片机来设计八路抢答器是一个常见的小课题,本人之前在大学期间就设计过八路抢答器的课程设计,也正是这个课程设计,让我喜欢上了单片机,以后也是从事的嵌入...