热门搜索 :
考研考公
您的当前位置:首页正文

基于51单片机的电子画板的设计

来源:伴沃教育


基于单片机的电子画板设计

摘 要

电子画板是一个非常有趣的电子产品,在各个场合都非常实用。

电子画板是采用单片机通过编写C语言程序控制的。其显示主体是一个8X8的LED点阵。控制器是51单片机。整个装置由按键控制。

在键盘上有四个键方向控制一个动点(画笔)上下左右移动。当移动到某一 点后如果我们要画下这一点,就按下一个“确认键”让这一点始终在画板上显示(让对应的的LED常亮)。如果某一点画错了,再通过一个“取消键”来删除上一次确定的点,让其对应的LED熄灭。当我们想要重新画,或者画完了一幅画想要再来画一幅的时候我们就可以按下一个“重画键”让系统复位到最初状态。

武汉理工大学华夏学院《单片机原理与应用》课程设计

目录

前言…………………………………………………………………………………………… 4

第一章 电子画板系统的设计要求与设计方案……………………… 5

1.1 电子画板的功能与要求…………………………………………………………5

1.2 电子画板设计方案的确定………………………………………………………5

第二章 电子画板系统的硬件设计………………………………………… 6

2.1 电子画板的硬件介绍及硬件框图…………………………………………… 6 2.2 电子画板的硬件方案…………………………………………………… 8 2.3 硬件框图……………………………………………………………………………8

第三章 电子画板系统的软件设计………………………………………… 9

3.1 主程序流程图…………………………………………………………………… 9 3.2 键盘扫描程序设计…………………………………………………………… 10

第四章 电子画板系统的安装与调试………………………………………11

4.1 硬件调试……………………………………………………………………………11 4.2 软件调试……………………………………………………………………………11

第五章 设计体会与小结…………………………………………………………16 5.1 总结设计体会与心得…………………………………………………………16

附录……………………………………………………………………………………………17

参考文献……………………………………………………………………………………17

- 1 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

前言

单片机程设计是计算机学习中非常重要的一个环节,是将理论知识和实践能力相统一的一个环节,是真正锻炼学生能力的一个环节。电子画板是一个非常有趣的电子产品,在各个场合都非常实用。

电子画板是采用单片机通过编写C语言程序控制的。其显示主体是一个8X8的LED点阵。控制器是51单片机。

在键盘上有四个键方向控制一个动点(画笔)上下左右移动。当移动到某一点后,如果我们要画下这一点,就按下一个“确认键”让这一点始终在画板上显示(让对应的的LED常亮)。如果某一点画错了,再通过一个“取消键”来删除上一次确定的点,让其对应的LED熄灭。当我们想要重新画,或者画完了一幅画想要再来画一幅的时候我们就可以按下一个“重画键”让系统复位到最初状态。

- 2 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

第一章 电子画板系统的设计要求与设计方案

1.1 电子画板的功能与要求

电子画板要求在一块8X8LED点阵上可以画出各种形状的图形。同时要求可以擦除画错的点,可以全盘复位重新作画。

1.2 电子画板的方案确定

课题要求我们设计一块电子画板,而所谓的画板实际上是一块8X8的LED点阵,那么我们的“作画”这一动作实际上就是在LED点阵上去点亮一个个的点,通过这样一种方式来实现最终的绘画动作。

画板是一个点阵,那么这就决定了我们的“画笔”只能有四个动作方向,即上、下、左、右四个方向。这四个方向的动作我们可以通过四个方向键来方便的控制。

这四个方向键的作用仅仅只是为了控制“画笔”的方向,然而要让画笔最终落在“纸张”上作画,这就需要用另一个键来实现“画”这个动作。因此我们在这里用按下一个确认键的方法来实现画。

在作画的过程中我们有画错的可能,所以在画错这后必须要有一个取消上一个动作的操作,我再设一个取消键来实现这一功能。

以上的方案就基本上实现了一个电子画板的功能。考虑难到在每次作画完毕,需要下一次作画时,在上述功能下必须一个个点的取消,所以作为扩展功能我们在此还要设置一个全盘取消的控制键,实现“换纸”的功能。

综上所诉,总体方案就是:在键盘上有四个键方向控制一个动点(画笔)上下左右移动。当移动到某一点后,如果我们要画下这一点,就按下一个“确认键”让这一点始终在画板上显示(让对应的的LED常亮)。如果某一点画错了,再通过一个“取消键”来删除上一次确定的点,让其对应的LED熄灭。当我们想要重新画,或者画完了一幅画想要再来画一幅的时候我们就可以按下一个“重画键”让系统复位到最初状态。

- 3 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

第二 电子画板系统的硬件设计

2.1 电子画板的硬件

系统硬件部分主要是:控制器(单片机),键盘,8X8LED点阵。 单片机我们选用的是STC89C51单片机。STC89C51单片机简介:

STC89C51系列单片机是宏晶科技推出的新一代超强抗干扰/高速/低功耗的单片机,是MCS-51系列单片机的派生产品; STC89C51单片机具有增强型12时钟/机器周期、6时钟机器/周期任意选择,工作电压为5.5V-3.4V(5V单片机)/3.8V-2.0V(5V单片机);工作频率范围:0-40MHZ,相当于普通8051的0-80MHZ。实际频率可达48MHZ。用户应用程序空间为4K/8K/13K/16K/20K/32K/64K字节 ;片上集成1280字节/512字节RAM;有32/36个通用I/O口,P1/P2/P3/P4是准双向口;集成ISP(在系统可编程)/IPA(在应用可编程),无需专用的编程器/仿真器,可通过串行口(P3.0/P3.1)直接下载用户程序,built-in drive,8K程序3秒就可以完成一片,具备EEPROM功能,共有3个16位定时器/计数器,其中定时器T0还可以当成2个8位定时器使用。

基准频率源 脉冲计数输入 振荡器及 定时电路 4KB/8KB 程序存储器 128/256字节 数据存储器 2/3个16位 定时器/计数器 CPU 内部 中断 64KB总线扩展控制器 可编程I/O口 可编程串行口 外部中断 控制 并行I/O口 穿行输入 串行输出 图1 51系列单片机内部结构图

- 4 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

键盘。由于本次设计在已经连接好的开发板上进行,所以我们使用的键盘是一个4X4的矩阵键盘。如图2

P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7 图2 4X4矩阵键盘

8X8的LED点阵是由64个LED以矩阵方式连接的,由于手工绘画复杂,绘画具体的电路连接图形参考附图的开发板资料。

- 5 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

2.2 电子画板的硬件方案

由于这个系统的硬件构成比较简单,加之所驱动的LED点阵的功率很小,故不用单独外加驱动设备。在总体构成上我们在这个矩阵键盘上定义自己所需要的按键,通过这些按键向单片机发出控制指令。然后单片机通过运算处理将LED点阵上的对应点点亮,完成我们的设计要求。

2.3 硬件框图

89C51 8X8 LED 点阵 单 片 键 盘 机 电 路 图3 硬件框图

- 6 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

第三章 电子画板系统的软件设计

3.1 主程序流程图

开始 点亮左上角第一个灯,将端口值分保存在数组C【】,D【】中 扫描键盘,读键值 灯左移 D【0】循环右移 灯右移 D【0】循环右移 灯上移 C【0】循环右移 灯下移 C【0】循环左移 确认 C【】 D【】 送至AB 取消 将上次送AB的值还原 将AB数组的值全部还原 C【】D【】数组中的值 送入AB的相应位置 将AB【】【】中的值依次送至端口现实 N 送完 Y

- 7 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

3.2 键盘扫描程序设计 键盘扫描程序:

unsigned char keyscan(void) { int a=0;

unsigned char cord_h,cord_l; P3=0xf0; cord_h=P3&0xf0;

if(cord_h!=0xf0) //判断是否有键按下 {

for(a=0;a<=2;a++) // 扫描数组AB,去抖动 {for(i=0;i<=64;i++) {P0=AB[i][0];

P2=AB[i][1];

for(j=0;j<50;j++){;}

}

}

P3=0xf0; cord_h=P3&0xf0;

if(cord_h!=0xf0) //再次读键盘,并返回键值 {

cord_h=P3&0xf0; P3=cord_h|0x0f; cord_l=P3&0x0f; return(cord_h+cord_l); } } }

- 8 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

第四章 电子画板系统的安装与调试

1.1 硬件调试

硬件部分比较简单,但在调试过程中还是发生了而一些问题。在这个键盘中有有一些键的接触不是特别好,因此中有一些键不能正常工作。

最初,我们认为是键盘的去抖动延时设置的不够合理,进过反复的修改延时的去抖动延时时间,这个现象依然不能消除,这说明问题并不在软件。然后将不能用的键舍弃,换用其他的键便解决了这个问题。

1.2 软件调试

软件部分的设计与调试是此次课程是设计的一个重要环节。

1、在软件的设计部分,我碰到的第一个问题是,我希望当动点移动到画板的右边界时,若继续按下右移按键,动点能自动调回左边。这一过程对应以程序上的语句就是一个循环语句。但我们知道在C语言中没有循环移位的语句,为了实现这一功能我需要用现有的移位语句来实现循环移位功能。具体实现做法如下:

D[0]=(D[0]<<(8-1))|(D[0]>>1)

这里要实现一个八位数(51系列为八位)的循环右移,先将此数右移一位,让后再将原数左移7位,接着将两个数做“或”运算。这样我们就用移位指令实现了循环移位功能。

2、主程序中我将临时点(即可以移动的点,我们可以将其成为“笔尖”)报存在一个临时数组中,而将确定的点存放在意一个64X2的大数组中。我将这个数组定义为 char AB[][]。但是,在编译的时候,系统提示“auto segment too large”。这是因为,我们定义的数组存放在单片机的内部数据存储区内,这部分存储区只有128个字节,显然如果定义这样一个大数组在内部数据存储器是不行的。我们因该将其定义在尾部数据存储区,定义如下:

xdata char AB[][]

3、在扫描显示输出部分,有两种扫描方式。

我的设计中,每按下一次确认键就会有一对数据存入AB这个二维数组中。再依次将这个数组的数据送到I\O口,两个数据配合就会点亮一个相应的LED

- 9 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

灯,如此实现画图的动作。

这里有有两种方式来送数据到IO口显示。第一种,只扫描确认的点,即每个循环中只将那些存进数组AB[][]的输出到IO口显示。程序段如下:

for(i=0;i<=M;i++) // 扫描数组AB

{P0=AB[i][0]; P2=AB[i][1];

for(j=0;j<50;j++){;}

}

程序中M为存入的点的个数。

第二种方法是全盘扫描。即不论数组中存放了多少对点的坐标,在每一次的扫描中都将整个数组扫描一遍。程序段如下:

for(i=0;i<=64;i++) // 扫描数组AB

{P0=AB[i][0]; P2=AB[i][1];

for(j=0;j<50;j++){;}

}

这两种扫描方式看起来没有太大的区别,但在实际的运用中会出项的现象是不一样。在实际的程序运行中,若采用第一种扫描方式,我们会看到,随着扫描点数的增多,动点的闪烁频率会越来越低(动点是闪烁的,以便于区别于已经确定的点)。这是因为,数组AB[][]的点越多,扫描需要用的时间也就越多。这样一来主程序每循环一次所用的时间也就越长。说以动点亮灭的时间间隔也就越长,故频率会越来越低。

第二种扫描方式不会出现第一种扫描方式带来的现象。但会出现另外的问题:被点亮的点的亮度会降低。这是因为,我们让确定点常亮是采用不断去点亮这个点的动态方式实现的。采用全盘扫描的方式保证了每执行主程序一次所用的时间是相等的,但这会使每个确定点被点亮的时间间隔增大,故视觉上就会感觉到LED灯的亮度变暗了。

总体看来,两中方法各有优劣。在我的这课题中,第二种全盘扫描的方式在整体上考虑来更好,所以在最终确定的程序中,我采用的是这种扫描方式。

- 10 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

4、关于子程序的调试。子程序是用来扫描键盘并返回键值的。在子程序中有一个关键就是要解决好键盘去抖动的问题。常见的的去抖动的方式有两种,一种是延时去抖动,另一种是硬件去抖动。由于硬件条件的限制,我们无法采用这种方式所以只有用软件方式解决这个问题。

但如果我们在子程序中用一段延时(空循环)来“躲过”键盘抖动,那么没按一次键就会延长扫描主程序的是时间间隔。而且这段延时相对于主程序被扫描一次的时间是很长的。直观的想现象就是,每按一次键盘上的键,整个画板上的画面就会闪动一次。这样整个画板看起来就不完美了。为了避免这个现象,我们就必须解决这个问题。程序段如下:

/***********延时去抖动程序***************/ void ys(void) { unsigned int k; for(k=12500;k>0;k--); }

/************键盘扫描程序****************/ unsigned char keyscan(void) {

unsigned char cord_h,cord_l; P3=0xf0;

cord_h=P3&0xf0; if(cord_h!=0xf0) { ys(); P3=0xf0;

cord_h=P3&0xf0;

if(cord_h!=0xf0) {

cord_h=P3&0xf0;

P3=cord_h|0x0f;

cord_l=P3&0x0f;

- 11 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

return(cord_h+cord_l); } } }

不用延时(空循环)程序,但仍然要让程序在有键按下后个一段时间再读键值,这个问题该怎么解决呢?我们可换一种思维方式。延时不一定要用空循环语句来写。我们可以利用躲避抖动的这段时间间隔内去干其他的事情啊。这样我很容易想到,既然这段时间会带来画面的闪动,即在这段时间内程序没有去扫描数组AB[][],那么我们就将扫描数组AB[][]的程序段再次在子程序中走一遍。这样问题便很好的解决了。程序段如下:

unsigned char keyscan(void) { int a=0;

unsigned char cord_h,cord_l; P3=0xf0; cord_h=P3&0xf0; if(cord_h!=0xf0) {

for(a=0;a<=2;a++) // 扫描数组AB

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

{P0=AB[i][0]; P2=AB[i][1];

for(j=0;j<50;j++){;}

}

}

P3=0xf0; cord_h=P3&0xf0; if(cord_h!=0xf0) {

- 12 -

武汉理工大学华夏学院《单片机原理与应用》课程设计

cord_h=P3&0xf0; P3=cord_h|0x0f; cord_l=P3&0x0f; return(cord_h+cord_l); } } }

在这个地方要注意,如果我们在主程序和子程序都用到了数组AB[][],那么该数组必须定义为全局变量。

当然,我们这样做其实是并不妥善的。这样做会有一定的局限性。因为在去抖动的这段时间内,系统是出于失控状态的,主程序在这段时间内不能干任何事情。如果系统在这段时间内有其请求,如其他的外部中断请求,这样一来单片机内的程序时无法知道的。所以最好的解决办法是在子程序扫描到有按键按下后让

程序跳出子程序,继续执行主程序,以执行主程序的这段时间来代替延时。

- 13 -

第五章 设计体会与小结

5.1 总结设计体会与心得

为期两周的单片机课程设计告一段落。通过两周的努力,我也终于按时保质的完成了预定任务。收获非常之大。

首先,通过这次单片机课程设计,我收获了信心。原来的我总是在接到一个任务之后就换衣自己是否能够把它完成,对自己完全没有信心。通过这次成功的解决一个个问题,我在自信心上有了很大的提升。

其次,我收获了解决问题的办法。但我们拿到一个任务之后,我懂得了应该从哪里下手。以这次电子画板的题目为例。在接到任务后,首先我仔细研究在这次设计过程中我要用到的电子器件,51单片机,8X8LED点阵,4X4矩阵键盘。然后我分析了画板要实现的功能,接着画程序的流程图并依据流程图写出程序,最后一步一步的调试程序,解决遇到的问题,最终直至成功完成任务。

第三,通过这次课程设计,我收提升了自己解决问题的能力。从点阵的点亮,键盘的扫描,去抖动,画面质量的优化等等这些问题我们原来都没有具体去解决过,知识只停留在理论方面,而这次我自己在老师的指导之下一个一个的问题都解决了。

所谓一分耕耘一分收获,付出的努力换来了成果。这些成果的得来离不开其他人的帮助,在这次课程设计中得到了李波老师的精心指导,在此真心的表示感谢。还有指导老师黄竹君老师,熊薇薇师都给予了很多帮助,在次也一并说声感谢。

武汉理工大学华夏学院《单片机原理与应用》课程设计

附录

一.部分源程序 #include int i,j;

xdata char AB[65][2]={

0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,

0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF, 0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF, 0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF, 0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF, 0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF, 0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF, 0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF,0,0xFF};

/************键盘扫描程序****************/ unsigned char keyscan(void) { int a=0;

unsigned char cord_h,cord_l; P3=0xf0; cord_h=P3&0xf0; if(cord_h!=0xf0)

15

武汉理工大学华夏学院《单片机原理与应用》课程设计

{

for(a=0;a<=2;a++) // 扫描数组AB {for(i=0;i<=64;i++) {P0=AB[i][0]; P2=AB[i][1];

for(j=0;j<50;j++){;} } }

P3=0xf0; cord_h=P3&0xf0; if(cord_h!=0xf0) {

cord_h=P3&0xf0; P3=cord_h|0x0f; cord_l=P3&0x0f; return(cord_h+cord_l); } } }

16

武汉理工大学华夏学院《单片机原理与应用》课程设计

/*************主程序********************/ void main(void) {

unsigned char key;

unsigned char C[1];//存当前动点P0口(列)值 unsigned char D[1];//存当前动点P2口(行)值 int m=1,n=0;

P0=0x01;

P2=0xFE; //点亮左上第一个灯 C[0]=P0;

D[0]=P2; //动点值存入临时数组 while(1)

{ key=keyscan(); switch(key)

{ case 0xBD:D[0]=(D[0]<<(8-1))|(D[0]>>1); break; case 0xED:D[0]=(D[0]>>(8-1))|(D[0]<<1);break; case 0xDE:C[0]=(C[0]<<(8-1))|(C[0]>>1);break

case 0xDB:C[0]=(C[0]>>(8-1))|(C[0]<<1);break;

case 0xDD:AB[m][0]=C[0];

AB[m][1]=D[0]; break;

17

武汉理工大学华夏学院《单片机原理与应用》课程设计

case 0xE7:AB[m][0]=0;

AB[m][1]=0xFF;

m--; break;

case 0xD7:for(m=0;m<=64;m++) {AB[m][0]=0; AB[m][1]=0xFF; } P0=0x01; P2=0xFE; C[0]=P0; D[0]=P2; m=0; break; default: break; }

if(n<=10) {AB[0][0]=C[0]; AB[0][1]=D[0];} else if(n<200) {AB[0][0]=0;

18

武汉理工大学华夏学院《单片机原理与应用》课程设计

AB[0][1]=0xFF;} n++; if(n==20) n=0;

for(i=0;i<=64;i++) // 扫描数组AB {P0=AB[i][0]; P2=AB[i][1];

for(j=0;j<50;j++){;} } } }

19

武汉理工大学华夏学院《单片机原理与应用》课程设计

二. 系统硬件原理图

20

武汉理工大学华夏学院《单片机原理与应用》课程设计

参考文献

1.《单片微型计算机与接口技术》(第3版) 李群芳 张士军 黄建 电子工业出版社

2.《C语言程序设计教程》(第2版) 杨路明

北京邮电大学出版社

3.《单片机余力与应用试验指导书》 武汉理工大学华夏学院

4.《Protel DXP使用教程(修订版)》 清华大学出版社 北京交通大学出版社5.《STC89C51RC/RD+系列单片机器件手册》 宏晶科技

廖传书

赵志刚 吴海彬 21

武汉理工大学华夏学院《单片机原理与应用》课程设计

年 月 日

22

因篇幅问题不能全部显示,请点此查看更多更全内容

Top