电子技术综合设计报告3Dcube8设计完整报告.doc
电子技术综合设计总结报告姓 名: 赵1880黄1877邢1879 专业班级: 信电 设计题目: CUBE8光立方 时 间: 2012 2013 学年第(1)学期 指导教师: 成 绩: 日 期: 一:课题任务 3Dcube8(光立方) 是一个由LED组成的3D显示器,是一个集实际型 、经济型、性价比高的艺术品, 它不仅仅局限于装饰,更是能够帮助更好的学习 c语言实际应用、满足单片机爱好者对单片机的研究的个好工具。 3Dcube8有多种规格,常见的有单色4*4*4、单色8*8*8、RGB全彩光立方等。其中前者是这之中最简单的,制作难度和成本最高的是采用RGB的全彩光立方,综合成本和自身能力的考虑,选择制作单色8*8*8作为自己的课题。 二:方案比较与选择光立方的显示屏是由8片8*8的led点阵屏组成,通常的搭建方案有两种,层共阳与层共阴。两种方案实际操作没有太大区别,为了后期的成品效果外观美观,在这里我们选择层共阳。Led的选择:市面上有很多种发光二极管,按形状分方形和圆形草帽状、按效果又有高亮雾面等区别。考虑到美观和降低制作难度,我们选择了3mm长脚高亮雾面草帽型发光二级管,长脚的最大优势就是可以作为支架,省时省力。驱动方式利用人眼视觉暂留特性,利用逐层扫描的方式,来达到显示各种图案的目的。常见的coms锁存器(cmos发热低,优先选择)有74hc573和74hc595,前者为并入,后者串入。因为不需要光立方的级联设计,所以采用573锁存器。主控芯片选择较多,有常见的AVR、STC、ARDUINO 等。根据之前学过的课程,我们决定采用stc系列的STC89c5A60S2增强型单片机作为主控芯片。之所以不选89C52等芯片,不是因为他们的运算速度不够,主要原因是它们的片上flash太小,难以满足需求,其次是因为自己有闲置的STC89C5A60S2,片上内存大,运算速度1T,即充分利用资源节省成本,又可以实现所需要的功能需求。最后就是附属配件 usb转ttl串口的stc下载线。,选择采用cp2102作为usb转串口芯片方案,下载STC单片机完胜PL2303方案,最高下载速度可达115200波特率。三:电路设计 实验前准备实验环境:protues7.7,keil4.0,STC-ISPv4.80实验工具:恒温电烙铁,无铅锡丝,尖嘴钳,万用版,万能表等。主要分为三个模块分别是主控模块 驱动模块 显示模块控制模块单片机最小系统图1主控电路(单片机最小系统)2、驱动电路p口接8片573le端图2驱动电路在驱动电路上,图中的电阻都是150r的限流电阻,限流电阻130r为理论值.大于这个小于这个都可以。限流电阻r=(vcc-vf)/i,Vcc电源电压,Vf为led的正向电压降,I为led的工作电流,I大了,就亮,小了,就暗。3、显示电路 led点阵屏的制作图3 显示电路 图4 点阵屏实物图四:程序设计1初始化部分,主要是设置对应的中断,定时工作方式。2 显示部分l 把立方体看作8位数码管,每个面即为一个数码管l 每个面的显示原理是和8X8点阵是完全一样的,保证这段程序正确的,可以直接调用l 查表的方式是自0起递增的,每次加1,每个画面查表64次。当然,实际的情况是要小于65536的,控制程序的代码也会占用rom空间,就会导致了画面次数减少,所以,要想在有限的空间内显示更多的画面,就得尽量把程序写的简短。c语言可以直接定义16位变量。3中断部分,为了达到动画效果切换时间可准确调节性,画面的切换用中断方式。把时间通过一个变量来表示,这样每次只需修改一个变量,就可以设置动画的速度了。每次发送中断后,查表的变量就加64(i=i+64),然后返回显示程序继续显示,中断程序只做变量的计算,改变的是查表的地址。4循环l 程序循环,循环的条件是i变量不满足动画显示的上限值。比如做八个画面,那么i的的值不满足8X64时,就继续显示,满足就清零从新开始。l 显示循环主题的显示程序,应该是一个死循环,一直在显示一个画面,只有中断产生的时候,改变了查表的变量,才切换一次动画,每个画面都显示后,注意修正变量,能使其显示同一个画面,不管是查表的变量还是Z轴,Y轴的控制变量,都要进行初始化,直到中断的产生才改变查表的变量数值。.五、测试方案1、在8片点阵屏搭建完成之后采用点阵屏整面点亮方式检查每一面LED的通电情况,有过亮、过暗或者完全不亮的及时拆换。2、检查电路板的焊点和飞线是否有虚焊或者漏焊情况,元件正负极有无颠倒情况。3,、电路组装采用整体组装整体测试方式。4、烧录测试程序,检查光立方的全亮状态下有没坏点。六、系统调试光立方测试程序#include<reg51.h>#define layer P2#define oe P1#define led P0#define uchar unsigned char #define uint unsigned int#define PWM_MAX 100#define LED P2 /呼吸灯控制uchar PWM = 1;uchar PWM_Match = 0;uint Breath_Speed = 500;uint Breath_Count = 0; uint Breath_Direction = 0;uint oe1, layer1, led1;uchar code t1=0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ;uchar code t0=0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ;uchar code t2=0x66, 0xE7, 0x99, 0x99, 0x99, 0x99, 0x42, 0x00, ;/3uchar code t3=0x00, 0x3C, 0x42, 0x81, 0x81, 0x81, 0xFF, 0xFF, ;/Duchar code t4=0x00, 0x6E, 0x91, 0x91, 0x91, 0x91, 0x6E, 0x00,;/8uchar code t5=0x00, 0x42, 0x81, 0x81, 0x81, 0x42, 0x3C, 0x00,;/c uchar code t6=0xFC, 0xFE, 0x03, 0x03, 0x03, 0x03, 0xFE, 0xFC,;/uuchar code t7=0x00, 0x66, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF,;/buchar code t8=0x00, 0xC3, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF,;/euchar code t9=0x38, 0x7C, 0xFE, 0x7F, 0x7F, 0xFE, 0x7C, 0x38,;/心void delay(int t)char i;while(t-)for(i=0;i<100;i+)void timerinit(void)TMOD = 0x02; /设置定时器0工作方式为16位定时器TH0 = TL0 = 156; /设定初值ET0 = 1; /使能定时器TR0 = 1; /使能定时器中断EA = 1;void testled(void) int i, speed ;speed = 300;oe1=0x01;/测试oe移动是否正确led=0xff;layer=0xff;for(i=0;i<8;i+)oe=oe1 ;delay(speed);oe1<<=1; oe=0;led=0xff;layer1=0x01;/测试层移动是否正确for(i=0;i<8;i+)layer=layer1;delay(speed);layer1<<=1;layer=0xff;oe=0;led1=0x01;/测试led数据段移动是否正确for(i=0;i<8;i+)led=led1;delay(speed);led1<<=1;void main(void)uchar z;uchar i;timerinit();while(1)if(EA=0) oe=0x80;yidongzi(20,t2);yidongzi(20,t3);yidongzi(20,t4);yidongzi(20,t5);yidongzi(20,t6);yidongzi(20,t7); yidongzi(20,t8);yidongzi(120,t9);yizi(t2);yizi(t3);yizi(t4);yizi(t5);yizi(t6);yizi(t7);yizi(t8);dot();for(z=0;z<200;z+)kuang();for(z=0;z<5;z+)testled();/full(t1);void time_int0() interrupt 1static uint i;oe=0;layer=0xff; PWM_Match+;/让PWM对比值自加1 if(PWM_Match > PWM_MAX) PWM_Match = 0;/判断是否超出, if(PWM > PWM_Match) LED = 0;/如果PWM大于PWM对比值,则点亮LED else LED=0xff; if(Breath_Count = Breath_Speed) i+; Breath_Count = 0; if(Breath_Direction = 0) PWM+; if(PWM > PWM_MAX) Breath_Direction = 1; else PWM-; if(PWM = 0) Breath_Direction = 0; Breath_Count+; if(i=1000) i=0;EA=0; 七、注意事项1 搭建LED一定要主要,焊接温度和静电问题!以上情况,会照成LED损坏,和LED微亮的情况。( 距离LED灯头 3mm左右 电烙铁 放在上面加锡。5-10秒LED就会坏的,尽量焊接一个点在3秒左右,就算一次不成功也没事等他冷却了,在焊接)。静电 处理:电烙铁接地处理里没有地的,在电烙铁头铁壳上绑一根电线,脚才在 水泥地板上 线踩在脚下。2 LED的间距 LED间距为20M,就是刚刚好标准洞洞板9个孔间距。3 光立方LED搭建的极性 层为阳(+)列为阴(-)八、总结自己总结九:参考文献1.模拟集成电路原理与实用电路,邮电出版社;2.模拟集成电路应用,西北工大出版社3.C程序设计,清华大学出版社。4.新概念51单片机c语言教程,电子工业出版社。附录A:PCB板元件布局图附录B:实物图附录c:完整效果程序#include<reg51.h>#define layer P2#define oe P1#define led P0#define uchar unsigned char #define uint unsigned int#define PWM_MAX 100#define LED P2 /呼吸灯控制uchar PWM = 1;uchar PWM_Match = 0;uint Breath_Speed = 500;uint Breath_Count = 0; uint Breath_Direction = 0;uint oe1, layer1, led1;uchar code t1=0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ;uchar code t0=0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ;uchar code t2=0x66, 0xE7, 0x99, 0x99, 0x99, 0x99, 0x42, 0x00, ;/3uchar code t3=0x00, 0x3C, 0x42, 0x81, 0x81, 0x81, 0xFF, 0xFF, ;/Duchar code t4=0x00, 0x6E, 0x91, 0x91, 0x91, 0x91, 0x6E, 0x00,;/8uchar code t5=0x00, 0x42, 0x81, 0x81, 0x81, 0x42, 0x3C, 0x00,;/c uchar code t6=0xFC, 0xFE, 0x03, 0x03, 0x03, 0x03, 0xFE, 0xFC,;/uuchar code t7=0x00, 0x66, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF,;/buchar code t8=0x00, 0xC3, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF,;/euchar code t9=0x38, 0x7C, 0xFE, 0x7F, 0x7F, 0xFE, 0x7C, 0x38,;/心void delay(int t)char i;while(t-)for(i=0;i<100;i+)void timerinit(void)TMOD = 0x02; /设置定时器0工作方式为16位定时器TH0 = TL0 = 156; /设定初值ET0 = 1; /使能定时器TR0 = 1; /使能定时器中断EA = 1;void testled(void) int i, speed ;speed = 300;oe1=0x01;/测试oe移动是否正确led=0xff;layer=0xff;for(i=0;i<8;i+)oe=oe1 ;delay(speed);oe1<<=1; oe=0;led=0xff;layer1=0x01;/测试层移动是否正确for(i=0;i<8;i+)layer=layer1;delay(speed);layer1<<=1;layer=0xff;oe=0;led1=0x01;/测试led数据段移动是否正确for(i=0;i<8;i+)led=led1;delay(speed);led1<<=1;/*此函数和下边的函函数连用,达到向上卷起的效果*/void layerup()char i;for(i=0;i<8;i+) /一边都亮了,然后向上拉起一面layer=layer1;delay(400);layer1<<=1;layer1|=1;void dot(void)uchar i;int speed;speed=800;oe1=0x01;led=0x01;layer=0x01;for(i=0;i<8;i+) /从里边向外边来,oe左移oe=oe1;delay(speed);oe1<<=1;oe1|=1;layer1=0x01;layerup();layer=0x01;led1=0x01;oe=0x7f;for(i=0;i<8;i+) /从左边向右边,led左移.led=led1;delay(speed);led1<<=1;led1|=1;layer1=0x01;layerup();layer=0x01;led=0x80;oe1=0x80;for(i=0;i<8;i+)/向里边移动,oe右移oe=oe1;delay(speed);oe1>>=1;oe1|=0x80;led=0x80;layer1=0x01;oe=0;layerup();layer=0x01;oe=0xfe;led1=0x80;for(i=0;i<8;i+)led=led1;delay(speed);led1>>=1;led1|=0x80;layer1=0x01;layerup();void kuang()char i;i =20;/显示y横条layer =0x81;oe=0x00;led=0x81;delay(i);/显示 x横条layer=0x81;oe=0x7e;led=0xff;delay(i);layer=0xff;oe=0x81;led=0x81;delay(i);/*本函数实现的功能是吧一个字在一个z面显示出来,显示的长短阿时间 j要现实的数据 p */ /*本函数单独是不能用的 因为 没有设置oe的值 */void yidongzi(uint j ,uchar p) /本函数实现一个 把字从里边移动到外边的效果 显示的时间长短为juchar i ,k, z ;while(j-)/每一个字刷新j次k=50;while(k-)/每一个字刷新j次led1=0x80;for(i=0;i<8;i+)led=led1;layer=pi;z=80;while(z-); /z体现亮度,因为每个led点亮的时间为zled1>>=1;layer=0;/消隐 void full(uchar array)uchar i, k, a, z,m ;/time为刷新的次数,即刷新的z面oe1=0x01; for(m=0;m<8;m+) /八个面的扫描 oe=oe1;k=100;while(k-)/每一个字刷新j次 /把一个z面刷新3000次led1=0x80;for(i=0;i<8;i+)/刷新一面的函数led=led1;layer=arrayi+a;z=100;while(z-);/*z体现亮度,因为每个led点亮的时间为z */led1>>=1;layer=0;/消隐 a+=8; oe1<<=1; /*/本函数实现 把一个字 从0按照y轴移动 /*/void yizi(uchar array)uchar i; oe1=0x01;oe=oe1; yidongzi(20,array);for(i=0;i<7;i+)oe=oe1;yidongzi(1,array);oe1<<=1;oe=0x80;yidongzi(20,array);void main(void)uchar z;uchar i;timerinit();while(1)if(EA=0) oe=0x80;yidongzi(20,t2);yidongzi(20,t3);yidongzi(20,t4);yidongzi(20,t5);yidongzi(20,t6);yidongzi(20,t7); yidongzi(20,t8);yidongzi(120,t9);yizi(t2);yizi(t3);yizi(t4);yizi(t5);yizi(t6);yizi(t7);yizi(t8);dot();for(z=0;z<200;z+)kuang();for(z=0;z<5;z+)testled();/full(t1);void time_int0() interrupt 1static uint i;oe=0;layer=0xff; PWM_Match+;/让PWM对比值自加1 if(PWM_Match > PWM_MAX) PWM_Match = 0;/判断是否超出, if(PWM > PWM_Match) LED = 0;/如果PWM大于PWM对比值,则点亮LED else LED=0xff; if(Breath_Count = Breath_Speed) i+; Breath_Count = 0; if(Breath_Direction = 0) PWM+; if(PWM > PWM_MAX) Breath_Direction = 1; else PWM-; if(PWM = 0) Breath_Direction = 0; Breath_Count+; if(i=1000) i=0;EA=0;