基于8051单片机16#16点阵设计报告及其代码实现.docx
《基于8051单片机16#16点阵设计报告及其代码实现.docx》由会员分享,可在线阅读,更多相关《基于8051单片机16#16点阵设计报告及其代码实现.docx(17页珍藏版)》请在冰豆网上搜索。
基于8051单片机16#16点阵设计报告及其代码实现
1、CDIO设计目的:
◆熟悉单片机的工作原理,以及其外围电路的连接。
◆熟练掌握利用C语言编程对单片机的操作。
◆掌握点阵显示的原理,通过编程使其显示相应汉字。
◆通过设计对单片机的最小系统以及利用的
2、CDIO设计正文
2.1设计简介
本次设计用16×16点阵LED显示“河北工程大学信电学院”十个汉字和一个小图形。
要求在目测条件下LED显示屏各点亮度均匀、充足,可显示图形和文字,显示图形或文字应稳定、清晰无串扰,图形或文字显示有静止、移入移出等显示方式。
2.2点阵显示原理
一般的点阵都是8*8的,即横竖都有8个发光二极管,如图1所示。
图18*8点阵示意图
观察二极管正负极,我们可以很容易发现,如果赋予P0=0xff;P2=0x00;那么所有的发光二极管将被点亮,从而点阵就可以实现全亮。
类似的,如果需要实现某一列或者某一行全亮,也可以进行类似的赋值。
比如,我们要实现第一列全亮,第一列全亮就要求P20=0;其他为1则代码为P0=0xff;P2=0xfe;但是如果需要让点阵显示一个字符的话,上述赋值则不能达到目的,需要通过动态扫描来实现。
扫描包括行扫描和列扫描,我们可以任意使用其中一种。
假设我们使用行扫描,就是首先令P07为1,即P00=0x80;然后观察在这一行上有哪些二极管被点亮,点亮的那一列所对应的端口就为0,不亮的就为1,记下此时P2数值,短暂延时过后,令P06=1,即P00=0x40;然后观察在这一行上有哪些二极管被点亮,点亮的那一列就为0,不亮的就为1,记下此时P2数值,同理如此重复下去,直到P00=0x01;那么所有的P0和P2的数值就构成了两个长度为8的数组,我们可以在程序中每个一段时间按顺序发送一组代码,只要时间段足够短,那么我们就可以在点阵上看到稳定的字符了。
2.3硬件设计
硬件设计总体框图如图2所示
图2总体设计框图
2.3.1列驱动电路
动态扫描的意思简单地说就是逐行轮流点亮,这样扫描驱动电路就可以实现多行(比如16行)的同名列共用一套列驱动器。
具体就16×16的点阵来说,我们把所有同一行的发光管的阳极连在一起,把所有同一列的发光管的阴极连在一起(共阳的接法),先送出对应第一行发光管亮灭的数据并锁存,然后选通第一行使其燃亮一定的时间,然后熄灭;再送出第二行的数据并锁存,然后选通第二行使其燃亮相同的时间,然后熄灭;……第十六行之后又重新燃亮第一行,这样反复轮回。
采用串行传输的方法,控制电路可以只用一根信号线,将列数据一位一位传往列驱动器,在硬件方面无疑是十分经济的。
但是,串行传输过程较长,数据按顺序一位一位地输出给列驱动器,只有当一行的各列数据都已传输到位之后,这一行的各列才能并行地进行显示。
这样,对于一行的显示过程就可以分解成列数据准备(传输)和列数据显示两个部分。
对于串行传输方式来说,列数据准备时间可能相当长,在行扫描周期确定的情况下,留给行显示的时间就太少了,以至影响到LED的亮度。
解决串行传输中列数据准备和列数据显示的时间矛盾问题,可以采用重叠处理的方法。
即在显示本行各列数据的同时,传送下一行的列数据。
为了达到重叠处理的目的,列数据的显示就需要具有锁存功能。
经过上述分析,可以归纳出列驱动器电路应具备的主要功能。
对于列数据准备来说,它应能实现串入并出的移位功能;对于列数据显示来说,应具有并行锁存的功能。
这样,本行已准备好的数据打入并行锁存器进行显示时,串并移位寄存器就可以准备下一行的列数据,而不会影响本行的显示。
经过上述分析最终采用具备上述功能的74HC595,它具有一个8位串入并出的移位寄存器和一个8位输出锁存器的结构,而且移位寄存器和输出锁存器的控制是各自独立的,可以实现在显示本行列数据的同时,传送下一行的列
数据,也能达到重叠处理的目的。
74HC595的外形及结构如图3所示。
图374HC595引脚图
它的输入侧有8个串行移位寄存器,每个移位寄存器的输出都连接一个输出锁存器。
引脚SI是串行数据的输入端。
引脚SCK是移位寄存器的移位时钟脉冲在其上升沿发生移位,并将SI的下一个数据打入最低位移位后的各位信号出现在各移位寄存器的输出端,也就是输出锁存器的输入端。
RCK是输出锁存器的打入信号,其上升沿将移位寄存器的输出打入输出锁存器。
引脚G是输出三态门的开放信号,只有当其为低时锁存器的输出才开放,否则为高组态。
SCLR信号是移位寄存器清零输入端,当其为低时移位寄存器的输出全部为零。
由于SCK和RCK两个信号是互相独立的,所以能够做到输入串行移位与输出锁存互不干扰。
芯片的输出端为QA~QH,最高位QH可作为多片74HC595级联应用时,向上一级的级联输出。
但因为QH受输出锁存器的打入控制,所以还从输出锁存器前引出QH,作为与移位寄存器完全同步的级联输出。
在电路图中的连接图4所示
图474HC595的电路连接图
2.3.2行驱动电路
本设计中采用两个74HC154译码器实现4线16线输出,来驱动点阵显示屏的行。
74HC154是一款高速CMOS器件,74HC154引脚兼容低功耗肖特基TTL(LSTTL)系列。
74HC154译码
器可接受4位二进制加权地址输入(A,B,C和D),并当使能时,提供8个互斥的低有效输出(X0至X15)。
74HC154特有2个使能输入端:
两个低有效E1和E2。
除非E1和E2置低,否则74HC154将保持所有输出为高。
ABCD四个输入端可分别从0000-1111时输出段可分别选中点阵的1至15行从而实现对个行的扫描控制。
74HC154的使能端E1受单片机P1.4引脚控制从而实现控制扫描的开始与结束。
74HC145在电路中的连接如图5所示
图574HC154的电路图
图6硬件总体电路图
3软件设计
3.1显示驱动程序
显示驱动程序在进入中断后首先要对定时器T0重新赋初值,以保证显示屏刷新率的稳定,1/16扫描显示屏的刷新率(帧频)计算公式如下:
刷频率(帧频)=1/16×T0溢出率
=1/16×f/12(65536-t)
其中f位晶振频率,t为定时器T0初值(工作在16位定时器模式)。
然后显示驱动程序查询当前燃亮的行号,从显示缓存区内读取下一行的显示数据,并通过串口发送给移位寄存器。
为消除在切换行显示数据的时候产生拖尾现象,驱动程序先要关闭显示屏,即消隐,等显示数据打入输出锁存器并锁存,然后再输出新的行号,重新打开显示。
本文设计的系统软件能使系统在目测条件下LED显示屏各点亮度均匀、充足,可显示图形和文字,显示图形和文字应稳定、清晰无串扰。
图形或文字显示有静止、移入移出等显示方式。
显示驱动程序(显示屏扫描函数)流程图如图6所示
图6显示驱动程序流程图
3.2系统的主程序
系统主程序开始以后,首先是对系统环境初始化,包括设置串口、定时器、中断和端口;然后以“卷帘出”效果显示图形,停留约1s;接着向上滚动显示“河北工程大学信电学院”这10个汉字及一个图形,然后以“卷帘入”效果隐去图形。
由于单片机没有停机指令,所以可以设置系统程序不断的循环执行上述显示效果。
单元显示屏可以接收来自控制器(主控制电路板)或上一级显示单元模块传输下来的数据信息和命令信息,并可将这些数据信息和命令信息不经任何变化地再传送到下一级显示模块单元中,因此显示板可扩展至更多的显示单元,用于显示更多的显示内容。
图7是系统主程序流程图。
图7主程序流程图
4、CDIO设计总结
本次CDIO设计主要是进行了点阵显示汉字的设计,对于点阵平时见到得很多,但是对其显示的真正原理并不是很清楚,正好通过此次设计吧点阵显示的基本原理弄清楚了,并且能能够自己设计,并变成实现一些简单的应用。
在这次设计的过程中我通过查阅大量的相关资料,了解了LED的现状,清楚地了解了LED显示屏与其它显示屏相比较有那些优点,明确了目标。
在设计过程中我对点阵如何显示汉字,并且如何滚动有了比较详细的了解,知道动态扫描实现的原理,并且熟练掌握了Proteus仿真软件的基本使用,与此同时也感到单片机的重要作用。
另外,由于刚开始时对C语言在单片机上的应用不是很了解,导致在程序的编程时逻辑上产生了很多错误,后来通过自己对别人的程序进行了解,通过自己的不断练习最终实现了想要的结果。
不仅如此,通过这次设计,从这次设计中,我们最重要的感受是:
做任何事都有耐心和毅力,否则将一事无成。
参考文献
[1]何立民.MCS-51系列单片机应用系统设计与接口技术.北京:
北京航空航天大学出版社,1990.23-25
[2]何立民.单片机应用技术选编.北京:
北京航空航天大学出版社,2000.30-33
[3]邬宽明.单片机外围器件实用手册.北京:
北京航空航天大学出版社,1998.70-73
[4]张毅刚等.MCS-51单片机应用设计.哈尔滨:
哈尔滨工业电子出版社,1996.55-56
[5]张新成,杨志邦.c语言程序设计.郑州:
河南科学技术出版社,2009.55-65
[6]余发山,王福忠.单片机原理及应用技术.徐州:
中国矿大出版社,2004.34-36
代码:
#include
#defineBLKN2//列锁存器数
sbitG=P1^4;//P1.4为显示允许控制信号端口
sbitRCLK=P1^6;//P1.6为输出锁存器时钟信号端
sbitSCLR=P1^5;//P1.5为移位寄存器清0端
voiddelay(unsignedint);//延时函数
unsignedchardatadispram[32];//显示缓存
/*------------------主函数---------------*/
voidmain(void)
{
unsignedcharcodeBmp[][32]={//字模表
{
0x40,0x04,0x3F,0xFE,0x10,0x08,0x00,0x08,0x80,0x48,0x67,0xE8,0x24,0x48,0x0C,0x48,
0x14,0x48,0x24,0x48,0xE7,0xC8,0x24,0x48,0x20,0x08,0x20,0x08,0x20,0x28,0x20,0x10
}
/*河*/,
{0x04,0x80,0x04,0x80,0x04,0x88,0x04,0x98,0x04,0xA0,0x7C,0xC0,0x04,0x80,0x04,0x80,
0x04,0x80,0x04,0x80,0x04,0x80,0x04,0x80,0x1C,0x82,0xE4,0x82,0x44,0x7E,0x00,0x00
}
/*北*/,
{0x00,0x00,0x00,0x08,0x7F,0xFC,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x04,0xFF,0xFE,0x00,0x00,0x00,0x00
}
/*工*/,
{
0x08,0x04,0x1D,0xFE,0xF1,0x04,0x11,0x04,0x11,0x04,0xFF,0x04,0x11,0xFC,0x38,0x00,
0x37,0xFE,0x54,0x20,0x50,0x28,0x91,0xFC,0x10,0x20,0x10,0x24,0x17,0xFE,0x10,0x00
}
/*程*/,
{
0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x04,0xFF,0xFE,0x01,0x00,0x02,0x80,
0x02,0x80,0x02,0x40,0x04,0x40,0x04,0x20,0x08,0x10,0x10,0x0E,0x60,0x04,0x00,0x00
}
/*大*/,
{0x22,0x08,0x11,0x08,0x11,0x10,0x00,0x20,0x7F,0xFE,0x40,0x02,0x80,0x04,0x1F,0xE0,
0x00,0x40,0x01,0x84,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00
}
/*学*/,
{0x08,0x80,0x08,0x44,0x0F,0xFE,0x10,0x00,0x10,0x08,0x37,0xFC,0x50,0x00,0x90,0x08,
0x17,0xFC,0x10,0x00,0x13,0xF8,0x12,0x08,0x12,0x08,0x12,0x08,0x13,0xF8,0x12,0x08,
}
/*信*/,
{0x02,0x00,0x02,0x00,0x02,0x10,0x7F,0xF8,0x42,0x10,0x42,0x10,0x7F,0xF0,0x42,0x10,
0x42,0x10,0x7F,0xF0,0x42,0x10,0x02,0x00,0x02,0x04,0x02,0x04,0x01,0xFC,0x00,0x00
}
/*电*/,
{0x22,0x08,0x11,0x08,0x11,0x10,0x00,0x20,0x7F,0xFE,0x40,0x02,0x80,0x04,0x1F,0xE0,
0x00,0x40,0x01,0x84,0xFF,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x05,0x00,0x02,0x00
}
/*学*/,
{0x00,0x80,0x78,0x40,0x4F,0xFE,0x54,0x02,0x58,0x14,0x63,0xF8,0x50,0x00,0x48,0x08,
0x4F,0xFC,0x48,0xA0,0x68,0xA0,0x50,0xA0,0x41,0x22,0x41,0x22,0x42,0x1E,0x4C,0x00
}
/*院*/,
{
0xF8,0x3F,0xE7,0xCF,0xDF,0xF7,0xBF,0xFB,0xB3,0x9B,0x73,0x9D,0x7F,0xFD,0x7F,0xFD,
0x6F,0xED,0x67,0xCD,0xB3,0x9B,0xB8,0x3B,0xDF,0xF7,0xE7,0xCF,0xF8,0x3F,0xFF,0xFF
}/*:
*/
};
unsignedinti,j,k,l;
SCON=0x00;//串口工作模式0:
移位寄存器方式
TMOD=0x01;//定时器T0工作方式1:
16位方式
TR0=1;//启动定时器T0
P1=0x3f;//P1端口初值:
允许接收、锁存、显示
IE=0x82;//允许定时器T0中断
while
(1)
{
delay(300);//延时2秒
for(i=0;i<32;i++)//显示效果:
卷帘出┓
{
dispram[i]=Bmp[10][i];
if(i%2)delay(100);
}//━━━━━━━━┛
delay(300);
for(i=0;i<11;i++)//显示效果:
上滚屏┓
{
for(j=0;j<16;j++)
{
for(k=0;k<15;k++)
{
dispram[k*BLKN]=dispram[(k+1)*BLKN];
dispram[k*BLKN+1]=dispram[(k+1)*BLKN+1];
}
dispram[30]=Bmp[i][j*BLKN];
dispram[31]=Bmp[i][j*BLKN+1];
delay(100);
}
}//━━━━━━━━┛
delay(5000);
for(i=0;i<11;i++)//显示效果:
左跑马┓
{
for(j=0;j<2;j++)
for(k=1;k<9;k++)
{
for(l=0;l<16;l++)
{
dispram[l*BLKN]=dispram[l*BLKN]<<1|dispram[l*BLKN+1]>>7;
dispram[l*BLKN+1]=dispram[l*BLKN+1]<<1|Bmp[i][l*BLKN+j]>>(8-k);
}
delay(100);
}//end(k=0;k<16;k++)
}//endfor(i=0;i<;i++)//━━━━━━━┛
delay(5000);
for(i=0;i<32;i++)//显示效果:
卷帘入┓
{
dispram[i]=0x00;
if(i%2)delay(100);
}//━━━━━━━━┛
}//endwhile
(1)
}
/**********延时函数***********/
voiddelay(unsignedintdt)
{
registerunsignedcharbt;
for(;dt;dt--)
for(bt=0;bt<255;bt++);
}
/*显示屏扫描(定时器T0中断)函数*/
voidleddisplay(void)interrupt1using1
{
unsignedchari,j=BLKN;
TH0=0xF8;//设定显示屏刷新率每秒62.5帧
TL0=0x30;
i=P1;//读取当前显示的行号
i=++i&0x0f;//行号加1,屏蔽高4位
do{
j--;
SBUF=dispram[i*BLKN+j];//送显示数据
while(!
TI);TI=0;
}while(j);//完成一行数据的发送
G=1;//消隐(关闭显示)
P1&=0xf0;//行号端口清○
RCLK=1;//显示数据打入输出锁存器
P1|=i;//写入行号
RCLK=0;//锁存显示数据
G=0;//打开显示
}
CDIO设计
评语
课程设计
成绩
指导教师
(签字)
年月日
.