基于51单片机的流水灯及点阵设计报告.docx

上传人:b****6 文档编号:7694408 上传时间:2023-05-11 格式:DOCX 页数:27 大小:851.59KB
下载 相关 举报
基于51单片机的流水灯及点阵设计报告.docx_第1页
第1页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第2页
第2页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第3页
第3页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第4页
第4页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第5页
第5页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第6页
第6页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第7页
第7页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第8页
第8页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第9页
第9页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第10页
第10页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第11页
第11页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第12页
第12页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第13页
第13页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第14页
第14页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第15页
第15页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第16页
第16页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第17页
第17页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第18页
第18页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第19页
第19页 / 共27页
基于51单片机的流水灯及点阵设计报告.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于51单片机的流水灯及点阵设计报告.docx

《基于51单片机的流水灯及点阵设计报告.docx》由会员分享,可在线阅读,更多相关《基于51单片机的流水灯及点阵设计报告.docx(27页珍藏版)》请在冰点文库上搜索。

基于51单片机的流水灯及点阵设计报告.docx

基于51单片机的流水灯及点阵设计报告

目录

1.引言2

1.1背景2

1.2设计目的2

1.3参考资料2

2.方案设计与比较论证

2.1设计任务2

2.2设计要求2

2.3方案的选择3

3.总体设计3

3.1开发与运行环境3

3.2系统软件工作流程图3

3.3硬件结构4

4.系统功能测试与整体指标6

4.1系统各模块功能的性能测试6

4.1.1LED小灯模块6

4.1.2点阵模块9

4.1.3按键模块10

4.2系统功能测试12

4.3系统误差与问题分析12

5.总结13

附录1;详细程序14

 

1.引言

1.1背景

随着电子技术的飞速发展,电子行业和社会上的各行各业息息相关,从家用电器到航空航天,无一不与电子产业的发展密切相关。

当我们看到大街小巷都是变幻多彩的霓虹灯时,心中是否会感到很新奇?

当我们看到绚丽多彩的广告牌时,心中是否会觉得很神奇?

这些神奇的流水灯只是电子产业的冰山一角,更多的知识需要我们在以后的道路上慢慢探索。

在单片机上实现流水灯很简单,只需要几条指令就可以完成,大部分学生都可以完成任务。

于是我们就思考一个新的问题,能不能实现一个亮度渐变的、按规律移动的超酷流水灯?

这就是本次设计的背景及意义。

1.2设计目的

本次基于51单片机的流水灯设计主要是为了让我们增进对80C51单片机电路的感性认识,加深对理论方面的理解。

了解软硬件的有关知识,并掌握软硬件设计过程、方法及实现,为以后设计和实现应用系统打下良好基础。

虽然本次设计较为简单,但是涵盖的内容较为丰富,运用了单片机的动态扫描、定时器、中断,用for循环来实现彗星灯的效果,PWM波控制LED的亮灭程度,独立按键的应用等等,另外,通过简单课题的设计练习,使我们了解必须提交的各项工程文件,达到巩固、充实和综合运用所学知识解决实际问题的目的。

1.3参考资料

【1】单片机原理及应用·马永杰主编·清华大学出版社2011.8

【2】51单片机C语言教程·郭天祥主编·电子工业出版社2009.12

【3】模拟电子技术基础·康华光主编·高等教育出版社2006.01

2.方案设计与比较论证

2.1设计任务

(1)基于51单片机实现一个亮度渐变的、按规律移动的超酷流水灯;

(2)基于51单片机实现在点阵上动态显示“心”型和依次显示“西北师大”;

(3)通过独立按键实现流水灯和点阵显示的切换。

2.2设计要求

(1)应用STC89C51单片机;

(2)将LED亮度渐变和按规律移动相结合;

(3)通过独立按键实现流水灯和点阵的切换;

2.3方案的选择

本系统以STC89C51单片机为核心,通过独立按键来实现LED小灯和点阵显示的切换,所以整个系统可以包括以下的几个模块:

点阵模块;键盘模块;LED小灯点亮模块。

下面一一来说明三种模块的选择。

点阵模块:

点阵模块我选择的是51单片机上自带的8×8点阵,用动态扫描技术可以很好的在点阵上显示出“心”型和文字;

键盘模块:

方案一、利用矩阵键盘,矩阵键盘可以很好的实现LED小灯和点阵显示的切换,但利用的单片机的资源太多;

方案二、利用独立键盘,独立键盘在本系统中是物尽其才,在本系统中,按键少,独立键盘原理简单,所以本系统选择了独立键盘;

LED点亮模块:

LED点亮模块我是用PWM波控制LED小灯的明暗程度,用定时器、中断技术以及动态扫描实现按一定的规律移动。

3.总体设计

3.1开发与运行环境

本设计采用的是STC89C51单片机,该单片机采用的MCU51内核,因此具有很好的兼容性,内部带有8KB的ROM,能够存储大量的程序,在KeiluVision4上编写程序,通过STC_ISP_V483烧录到STC89C51芯片里,KeiluVision4支持汇编和C语言平台,最突出特点是具有ISP在系统烧写功能,使得烧写程序更加方便。

3.2系统软件工作流程图

本次设计是通过按不同按键来实现流水灯和点阵显示的,当按下按键1时,单片机执行超级流水灯的程序;当按下按键2时,单片机执行第二套程序,点阵中依次显示“西北师大”的静态字样;当按下按键3时,单片机执行第三套程序,点阵中动态的画出“心”型。

系统软件工作流程图如下所示:

 

 

3.3硬件结构

STC89C51单片机LED灯模块、点阵模块、独立按键模块电路图分别如下:

 

 

8×8LED点阵模块

 

独立按键模块

STC89C52单片机实物图如下:

 

 

4.系统功能测试与整体指标

4.1系统各模块功能的性能测试

4.1.1LED小灯模块

本次设计的超级流水灯是用PWM波调光和流水灯行走花案相结合,在实现LED灯光移动中同时实现灯光的逐渐变亮的过程,在这个过程中用到了for循环,子程序调用,中断和定时器的使用等等,演示效果较好。

以下是超级流水灯的部分程序,我将以备注的形式分析整个过程。

//定时器0中断过程实现PWM调光

voidLedLum_isr(void)interrupt1//125HzPWM

{

staticuchari=0;

if(LedLum[0]>i)Led1=1;

elseLed1=0;

if(LedLum[1]>i)Led2=1;

elseLed2=0;

if(LedLum[2]>i)Led3=1;

elseLed3=0;

if(LedLum[3]>i)Led4=1;

elseLed4=0;

if(LedLum[4]>i)Led5=1;

elseLed5=0;

if(LedLum[5]>i)Led6=1;

elseLed6=0;

if(LedLum[6]>i)Led7=1;

elseLed7=0;

if(LedLum[7]>i)Led8=1;

elseLed8=0;

i++;

if(i==64)i=0;

Time_1ms_Count++;

if(Time_1ms_Count>=8)

{

Time_1ms_Flag=1;

Time_1ms_Count=0;

}

}

//延时程序

voidDelayNms(uintTick)

{

Time_1ms_Count=0;

for(;Tick>0;Tick--)

{

Time_1ms_Flag=0;

while(Time_1ms_Flag==0);

}

}

//==========================================

//

(1)第1,3,5,7个灯半亮,其余的全亮。

voidJob1(void)

{

LedLum[0]=LedLum[2]=LedLum[4]=LedLum[6]=32;

LedLum[1]=LedLum[3]=LedLum[5]=LedLum[7]=64;

DelayNms(1000);//保持1S

}

//==========================================

//

(2)第1个亮1/8,第2个亮2/8,第3个亮3/8,第4个亮4/8,

//第5个亮5/8,第6个亮6/8,第7个亮7/8,第8个全亮。

//这个就是彗星灯拖尾的程序

voidJob2(void)

{

uchari;

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

LedLum[i]=(i+1)*8;

DelayNms(1000);

}

//==========================================

//(3)所有的灯逐渐从暗到全亮,再由全亮到暗。

voidJob3(void)

{

uchari,j;

for(i=0;i<8;i++)//所有的灯全暗

LedLum[i]=0;

for(j=0;j<64;j++)//所有的灯逐渐从暗到全亮

{

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

LedLum[i]=j+1;

DelayNms(50);//延时

}

for(j=64;j>0;j--)//再由全亮到暗

{

for(i=8;i>0;i--)

LedLum[i-1]=j-1;

DelayNms(20);

}

}

//==========================================

//(4)8个灯从第一个开始依次渐亮,直到最后一个。

//再从最后一个起渐暗,直到第一个。

voidJob4(void)

{

uchari,j;

for(i=0;i<8;i++)//8个灯从第一个开始依次渐亮,直到最后一个。

{

for(j=0;j<64;j++)

{

LedLum[i]=j+1;

DelayNms(10);

}

//LedLum[i]=0;

}

for(i=8;i>0;i--)//再从最后一个起渐暗,直到第一个。

{

for(j=64;j>0;j--)

{

LedLum[i-1]=j-1;

//LedLum[i-1]=j;

DelayNms(10);

}

//LedLum[i-1]=0;

}

}

4.1.2点阵模块

点阵显示分为两部分,一部分是依次显示“西北师大”静态字样,另一部分是动态显示“心”型图案。

“西北师大”每个字在点阵中显示的原理相同,所以我就拿“西”字显示的原理来讲解。

显示“西”的程序如下:

ucharcodeseg1[]={0xfe,0x82,0xce,0xaa,0xaa,0xfe,0x28,0xfe};//点阵显示"西"字

ucharcodewei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//分别对应相应的段亮位选选中为0

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

{

P0=0xff;

LATCH1=1;LATCH1=0;

P0=wei[i];//取显示数据

LATCH2=1;LATCH2=0;

P1=seg1[i];//取段码

//LATCH2=1;LATCH2=0;

delayus(200);//扫描间隙延时

}

在整个过程中,单片机就是在不断的对程序进行扫描,在很短的时间内,人眼无法感觉到LED在闪烁,所以觉得LED一直亮着,从而在点阵上形成一个字。

再在这个循环外加个外循环,加上延时,从而实现文字的不断更换。

在点阵上动态显示“心”型原理和静态显示文字的原理差不多,只不多把文字的更换变成了“心”型下一步要出现的图案,外循环延时缩短一点,人眼看上去就觉得“心”型是动态出现的。

具体程序见附录1.

4.1.3按键模块

按键模块选择是四个独立按键中的其中三个,它操作简单、方便,利用的资源少,我是通过按键扫描函数,通过对返回值的判断从而决定执行哪套程序,需要注意的是,在按键扫描函数中要加延时实现去抖,否则有时会检测错误。

键盘扫描函数程序如下,我以备注的形式详细分析:

unsignedcharKeyScan(void)

{

if(!

KEY1)//如果检测到低电平,说明按键按下

{

delayms(10);//延时去抖,一般10-20ms

if(!

KEY1)//再次确认按键是否按下,没有按下则退出

{

while(!

KEY1);//如果确认按下按键等待按键释放,没有则退出

{

return1;

}

}

}

elseif(!

KEY2)//如果检测到低电平,说明按键按下

{

delayms(10);//延时去抖,一般10-20ms

if(!

KEY2)//再次确认按键是否按下,没有按下则退出

{

while(!

KEY2);//如果确认按下按键等待按键释放,没有则退出

{

return2;

}

}

}

elseif(!

KEY3)//如果检测到低电平,说明按键按下

{

delayms(10);//延时去抖,一般10-20ms

if(!

KEY3)//再次确认按键是否按下,没有按下则退出

{

while(!

KEY3);//如果确认按下按键等待按键释放,没有则退出

{

return3;

}

}

}

elseif(!

KEY4)//如果检测到低电平,说明按键按下

{

delayms(10);//延时去抖,一般10-20ms

if(!

KEY4)//再次确认按键是否按下,没有按下则退出

{

while(!

KEY4);//如果确认按下按键等待按键释放,没有则退出

{

return4;

}

}

}

else

return0;

}

4.2系统功能测试

启动系统,按下按键1,执行第一套程序,超级流水灯启动,运行正常;按下按键2,执行第二套程序,点阵中依次显示“西北师大”四个字样,运行正常;按下按键3,执行第三套程序,点阵中动态显示“心”型图案,运行正常。

通过测试,本设计的功能基本都能达到。

4.3系统误差与问题分析

我在调试本系统的时候出现了一下几点问题。

错误1:

当我按下独立键盘后,再去按另一个按键,单片机不执行后面按键的程序;

原因:

只有当前一个程序完整的执行完之后,再按下按键,系统才会去执行后面的程序;

错误2:

当我按下按键1后,LED灯一直亮着,没有想预想的那样显示出来;

原因:

延时时间太短,肉眼无法识别它的闪烁,将延时调长一点就好了。

错误3:

当一套程序执行完之后我再按其他的键,希望它执行另一套程序,但是没有实现,系统一直在执行前一套程序。

原因:

在内循环上出现错误,变成了死循环,无法跳出内循环。

错误4:

我想在按键按下去之后,如果不按其他键了,系统能一直执行循环执行前一套程序,比如,我按下按键1,如果我不再按按键2或3的话,系统能一直执行第一套程序,执行完之后再循环,所以我在里面加了一个while

(1),希望它能一直循环下去,因为它的外循环已经判断了按键的值,所以我想当改变按键值时这个循环还是跳出来的,但是确实跳不出这个死循环,这个问题我始终没有解决。

最后,保险起见,我选择了按键后只执行一次程序。

错误5:

在我调试过程中,单独调试点阵显示的时候,点阵中的LED特别亮,但是将这个程序和按键模块、流水灯模块加到一起时,运行起来,点阵中的LED显示就特别暗,这个问题始终没有解决。

5.总结

这次课程设计使我掌握了很多实践知识,对单片机有了进一步的了解。

通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,进而提高自己的实际动手能力和独立思考的能力。

这次设计也使我学会了方案的选择,对于实现同一种效果的方案可能会很多很多,我们要学会选择最优方案,比如同样的效果哪个程序所占的存储空间最少,运行速度最快等等,都是需要我们考虑的。

此外,对于书本上的知识,我们不能死守教条,要学会变通,这样更有利于我们学习和创新。

整个设计过程可以说不是很顺利,因为有很多知识已经淡忘,还有很多新的东西没有掌握,所以这次设计在不断的复习、学习中度过,使我受益匪浅,也使我对单片机的运用有了进一步的了解和掌握,也为今后的学习生活和工作打下良好的基础。

 

附录1;详细程序

#include

#defineuintunsignedint

#defineucharunsignedchar

#defineTime_125us(0x100-125)//Fosc=12M

sbitKEY1=P3^2;

sbitKEY2=P3^3;

sbitKEY3=P3^4;

sbitKEY4=P3^5;

sbitLed1=P1^0;

sbitLed2=P1^1;

sbitLed3=P1^2;

sbitLed4=P1^3;

sbitLed5=P1^4;

sbitLed6=P1^5;

sbitLed7=P1^6;

sbitLed8=P1^7;

sbitLATCH1=P2^6;

sbitLATCH2=P2^7;

ucharcodeseg1[]={0xfe,0x82,0xce,0xaa,0xaa,0xfe,0x28,0xfe};//点阵显示"西"字

ucharcodeseg2[]={0x2e,0xaa,0x6a,0x28,0x2c,0xea,0x28,0x28};//点阵显示"北"字

ucharcodeseg3[]={0x84,0x44,0x55,0xd7,0xd5,0xdf,0x44,0x5f};//点阵显示"师"字

ucharcodeseg4[]={0x82,0x44,0x28,0x10,0x10,0xfe,0x10,0x10};//点阵显示"大"字

ucharcodewei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

ucharcodeseg11[]={0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00};

ucharcodeseg12[]={0x00,0x00,0x00,0x00,0x00,0x10,0x24,0x00};

ucharcodeseg13[]={0x00,0x00,0x00,0x00,0x00,0x10,0x6c,0x00};

ucharcodeseg14[]={0x00,0x00,0x00,0x00,0x00,0x92,0x6c,0x00};

ucharcodeseg15[]={0x00,0x00,0x00,0x00,0x82,0x92,0x6c,0x00};

ucharcodeseg16[]={0x00,0x00,0x00,0x44,0x82,0x92,0x6c,0x00};

ucharcodeseg17[]={0x00,0x00,0x28,0x44,0x82,0x92,0x6C,0x00};

ucharcodeseg18[]={0x00,0x10,0x28,0x44,0x82,0x92,0x6C,0x00};//心的形状

voiddelayus(uintt);//us级延时函数声明

voiddelayms(uintt);//ms级延时函数声明

ucharKeyScan(void);//键盘扫描

voidDelayNms(uintTick);

bitTime_1ms_Flag;

ucharTime_1ms_Count=0,LedLum[8]={0,0,0,0,0,0,0,0};

voidLedLum_isr(void)interrupt1//125HzPWM

{

staticuchari=0;

if(LedLum[0]>i)Led1=1;

elseLed1=0;

if(LedLum[1]>i)Led2=1;

elseLed2=0;

if(LedLum[2]>i)Led3=1;

elseLed3=0;

if(LedLum[3]>i)Led4=1;

elseLed4=0;

if(LedLum[4]>i)Led5=1;

elseLed5=0;

if(LedLum[5]>i)Led6=1;

elseLed6=0;

if(LedLum[6]>i)Led7=1;

elseLed7=0;

if(LedLum[7]>i)Led8=1;

elseLed8=0;

i++;

if(i==64)i=0;

Time_1ms_Count++;

if(Time_1ms_Count>=8)

{

Time_1ms_Flag=1;

Time_1ms_Count=0;

}

}

voidDelayNms(uintTick)

{

Time_1ms_Count=0;

for(;Tick>0;Tick--)

{

Time_1ms_Flag=0;

while(Time_1ms_Flag==0);

}

}

//

(1)第1,3,5,7个灯半亮,其余的全亮。

voidJob1(void)

{LedLum[0]=LedLum[2]=LedLum[4]=LedLum[6]=32;

LedLum[1]=LedLum[3]=LedLum[5]=LedLum[7]=64;

DelayNms(1000);//保持3S

}

//

(2)第1个亮1/8,第2个亮2/8,第3个亮3/8,第4个亮4/8,

//第5个亮5/8,第6个亮6/8,第7个亮7/8,第8个全亮。

voidJob2(void)

{

uchari;

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

LedLum[i]=(i+1)*8;

DelayNms(1000);

}

//(3)所有的灯逐渐从暗到全亮,再由全亮到暗。

voidJob3(void)

{

uchari,j;

for(i=0;i<8;i++)//所有的灯全暗

LedLum[i]=0;

for(j=0;j<64;j++)//所有的灯逐渐从暗到全亮

{

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

LedLum[i]=j+1;

DelayNms(50);//延时

}

for(j=64;j>0;j--)//再由全亮到暗

{

for(i=8;i>0;i--)

LedLum[i-1]=j-1;

DelayNms(20);

}

}

//(4)8个灯从第一个开始依次渐亮,直到最后一个。

//再从最后一个起渐暗,直到第一个。

voidJob4(void)

{

uchari,j;

for(i=0;i<8;i++)//8个灯从第一个开始依次渐亮,直到最后一个。

{

for(j=0;j<64;j++)

{

LedLum[i]=j+1;

DelayNms(10);

}

//LedLum[i]=0;

}

for(i=8;i>0;i--)//再从最后一个起渐暗,直到第一个。

{

for(j=64;j>0;j--)

{

LedLum[i-1]=j-1;

//LedLum[i-1]=j;

DelayNms(10);

}

//LedLum[i-1]=0;

}

}

voidmain(void)

{TMOD|=0x02;

TMOD&=0x52;

TH0=Time_125us;

TR0=1;

EA=1;

ET0=1;//定时器开关打开

while

(1)

{uchari,j,num;

num=KeyScan();

if(num==1)

{

Job1();

Job2();

Job3();

Job4();

}

if(num==2)

{

for(j=0;j<100;j++)

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

{

P0

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2