“摇摇棒”是基于人眼视觉暂留原理而产生的, 当进行摇动时,由于人的视觉暂留会在发光二极管摇动区域产生一个视觉平面,从而达到在该视觉平面上传达信息的作用。本文介绍了以STC89C52单片机控制为主控芯片、配合高亮度LED二极管以及水银开关构成简易摇摇棒的设计过程,通过分时刷新20个发光二极管来显示输出文字或图案等信息。并在此基础上,利用DS1302时钟芯片显示当前时间,可通过按键对时间进行设置
第一章 基本原理
1.1视觉暂留现象
(Visual staying phenomenon,duration of vision)
人眼在观察景物时,光信号传入大脑神经,需经过一段短暂的时间,光的作用结束后,视觉形象并不立即消失,这种残留的视觉称“后像”,视觉的这一现象则被称为“视觉暂留”。
是光对视网膜所产生的视觉在光停止作用后,仍保留一段时间的现象,其具体应用是电影的拍摄和放映。原因是由视神经的反应速度造成的.其时值是二十四分之一秒。是动画、电影等视觉媒体形成和传播的根据。
视觉实际上是靠眼睛的晶状体成像,感光细胞感光,并且将光信号转换为神经电流,传回大脑引起人体视觉。感光细胞的感光是靠一些感光色素,感光色素的形成是需要一定时间的,这就形成了视觉暂停的机理。
物体在快速运动时, 当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1-0.4秒左右的图像,这种现象被称为视觉暂留现象。是人眼具有的一种性质。人眼观看物体时,成像于视网膜上,并由视神经输入人脑,感觉到物体的像。但当物体移去时,视神经对物体的印象不会立即消失,而要延续0.1 -0.4秒的时间,人眼的这种性质被称为“眼睛的视觉暂留”。
1.2 STC单片机简介
STC单片机是一款增强型51单片机,完全兼容MCS-51,还增加了新的功能,比如新增两级中断优先级,多一个外中断,内置EEPROM,硬件看门狗,具有掉电模式,512B内存等。还支持ISP下载,不用编程器,只要一个MAX232和一些廉价的元件就能写程可擦写10万次。
单片机最小系统:2
图(1) 单片机最小系统电路图
1.3 水银开关
摇摇棒在摇动时,只能在朝某一方向摇动时显示,否则会出现镜像字或镜像画面。所以通过接一个水银开关来控制,使摇摇棒从左向右摇动时将内容正确显示出来。
图(2) 水银开关结构图
图(3)水银开关实物图1
水银开关里的水银柱很活跃,导致在接通时容易产生抖动。所以将水银开关斜向上放置(尖端朝斜上方45°角),靠水银自身重力的作用减少抖动。
因为重力的关系,水银水珠会随容器中较低的地方流去,如果同时接触到两个电极的话,开关便会将电路闭合,开启开关。
主要作用:
1. 触发EXT1中断,在中断程序中显示画面。
2. 水银开关断开时,进入设置状态。(
1.4 时钟芯片
DS1302是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.5~5.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后备电源进行涓细电流充电的能力。
图(4) DS1302引脚分配图)
各引脚的功能为:
8、Vcc1:备用电池端;
1、Vcc2:5V电源。当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。
7、SCLK:串行时钟,输入;
6、I/O:数据输入输出口;
5、CE/RST:复位脚
2、3、X1、X2 是外接晶振脚 (32.768KHZ的晶振)
4、地(GND)
基本电路:
:
图(5) DS1302电路图
1.5 按键
图(6)按键外观/
主要作用:切换画面以及时间设置。
1.6 LED
LED是发光二极管(Light Emitting Diode,LED)的简称,也称作发光二极管。这种半导体组件可以作为指示灯、显示板,它不但能够高效率地直接讲点能转化为光能,而且拥有最长达数万小时的使用寿命,同时具备不如传统灯泡易碎,节能省电等优点。
在设计中的作用:作为此设计的显示模块,进行字符的显示。
图(7) LED结构图
第二章 原理图;
图(8)总原理图
第三章 实物说明图
图(9)总体实物图
1. 水银开关:传感器
2. 20位LED:显示器
3. DS1302: 时钟芯片
4. STC89C52单片机:主控芯片
5. 电源开关:供电
6. 功能按键(四个):○1切换画面。○2设置时间。 ○3时间加。 ○4时间减。
7. 时钟芯片备用电池:当电源关闭时为时钟芯片供电,保证时间的实时性。
图(10) IC座里隐藏元件
IC座里隐藏元件,这样做既美观又能节省空间,还可以保护元件。
第四章 使用说明
步骤一:将电源连接好。
图(11)电源开关及按键
步骤二:将电源开关打开。
此时20位LED开始闪烁,摇动摇摇棒将会看到如下效果:
图(12)初始效果图
步骤三:进入按键功能状态。
方法如下:
将摇摇棒LED一侧向下放置,即使水银开关两个引脚不导通(如图13)。(此状态是实现所有按键功能的通用状态。若不在此状态,按键将都不可用。时间设置同样是在此状态下进行的)。
图(13)按键功能状态
此时按下【换字】键,再摇动摇摇棒,画面会切换,将会看到如下效果(如图14):
图(14)切换画面
本摇摇棒系统共存储5个画面,通过【换字】按键进行循环切换。其中第五个换面显示的是实时时间,时间信息由时钟芯片提供。
步骤四:设置时间
首先进入按键功能状态。【将摇摇棒LED一侧向下放置,即使水银开关两个引脚不导通(如图13)】。
设置状态下LED显示说明:
如下图所示,从右至左四个LED分别表示:调秒标志位、调分标志位、调时标志位、设置状态标志位。时间信息的个位和十位分别由四个LED以二进制码的形式显示。
图(15)设置状态下LED显示说明图
按下【设置】按键,设置状态标志位点亮,调时标志位点亮,对小时设置。按【加】按键或【减】按键可以对小时进行设置,时间信息以二进制形式显示。
再按下【设置】按键,设置状态标志位点亮,调分标志位点亮,对分钟设置。设置方法同上。
再按下【设置】按键,设置状态标志位点亮,调秒标志位点亮,对秒设置。设置方法同上。
图(16)设置小时
图(17)设置分钟
图(18)设置秒
步骤五:退出设置
设置完成后再按一下【设置】按键,退出设置状态,此时20个LED全灭。否则摇摇棒显示将不正确。(
第五章 软件设计3
5.1 设计思路-
由于摇摇棒在摇动时,只能在朝某一方向摇动时显示,否则会出现镜像字或镜像画面,所以通过接一个水银开关来控制。
在摇摇棒左向右摇动时,水银开关导通,触发单片机的外部中断,运行中断程显示预设画面。
在摇摇棒右向左摇动时,水银开关断开,运行主程检测按键,实现画面切换及时间设置。
5.2 系统工作流程
1.显示预设图形,并按键切换。
2.按键设置时间。
3.显示时间。,
5.3主程序流程图(
图(19)主程序流程图"
第六章 部分效果图
图(20)效果图 电信0802班
- /*************************************************************
- 旋转LED字体程序
- 单片机 STC89C52
- 字模软件用的PC2002
- 逐列取模方式
- ***************************************************************/
- #include "SYSTEM.H"
- #include <reg52.h>
- #include <DIG.h>
- #define uchar unsigned char
- #define uint unsigned int //宏定义
- uint i=0 ;
- uint j=0 ;
- sbit key=P3^7;
- sbit she=P2^7;
- sbit shi=P2^6;
- sbit fen=P2^5;
- sbit mia=P2^4;
- uchar h1;
- uchar h2;
- uchar m1;
- uchar m2;
- uchar s1;
- uchar s2;
- uchar K1J,K2J,K3J; //键值
- //char Set_Mode = 0;
- extern uchar k;
- extern uchar Set; //调整值
- unsigned char code Disp_Tab[] = {0xff,0x7f,0xbf,0x3f,0xdf,0x5f,0x9f,0x1f,0xef,0x6f}; //段码控制
- /*****n(us)延时子程序*****/
- void DelayUs(uint N)
- {
- uint x ;
- for(x=0;x<=N;x++);
- }
- /*--------------------------------------------------------------*/
- //键盘扫描
- void Keysan(void)
- {
- if(!key) //换字
- { DelayUs(7000);
- if(!key)
- {
- j++;
- }
- if(j==5) { j=0; }
- }
-
- if(~P2_3&K1J) { k++; }
- K1J=~(~P2_3);
- if(~P2_2&K2J) { Set=1; }
- K2J=~(~P2_2);
- if(~P2_1&K3J) { Set=-1; }
- K3J=~(~P2_1);
-
- if(k == 4) {k = 0; }
-
- switch(k)
- { //case 4: break;
- case 3: she=0;shi=1;fen=1;mia=0; DS1302_AddTime(DS1302_SECOND, Set);P1=Disp_Tab[s1];P0=Disp_Tab[s2];Set=0; break; //设置秒
- case 2: she=0;shi=1;fen=0;mia=1; DS1302_AddTime(DS1302_MINUTE, Set);P1=Disp_Tab[m1];P0=Disp_Tab[m2];Set=0; break; //设置分
- case 1: she=0;shi=0;fen=1;mia=1; DS1302_AddTime(DS1302_HOUR , Set);P1=Disp_Tab[h1];P0=Disp_Tab[h2];Set=0; break; //设置时
- case 0: P0=0xff;P1=0xff;P2=0xff;Set=0; break;
- default: break;
- }
- }
- /*****主函数*****/
- void main(void)
- { k=0;
- DS1302_Initial();//DS1302初始化
- while(1)
- {
- EA=1;//开总中断
- EX0=1;//开外部中断0
- //全灭
- P0=0xff;
- P1=0xff;
- P2=0xff;
- //读出时间
- h1=(Read1302(DS1302_HOUR)&0x70)>>4;
- h2=(Read1302(DS1302_HOUR)&0x0f);
- m1=(Read1302(DS1302_MINUTE)&0x70)>>4;
- m2=(Read1302(DS1302_MINUTE)&0x0f);
- s1=(Read1302(DS1302_SECOND)&0x70)>>4;
- s2=(Read1302(DS1302_SECOND)&0x0f);
- Keysan();
- }
- }
- /*************外部中断函数(显示)*******************/
- void exter0() interrupt 0
- {
- for(i=0;i<160;i++)
- {
- switch(j)
- {case 0: P0=love0[i*3];P1=love0[i*3+1];P2=love0[i*3+2];DelayUs(30);break;
- case 1: P0=love1[i*3];P1=love1[i*3+1];P2=love1[i*3+2];DelayUs(30);break;
- case 2: P0=love2[i*3];P1=love2[i*3+1];P2=love2[i*3+2];DelayUs(20);break;
- case 3: P0=love3[i*3];P1=love3[i*3+1];P2=love3[i*3+2];DelayUs(30);break;
- case 4: if(i<50){P0=0xFF;P1=0xFF;P2=0xFF;DelayUs(20);}
- if((i>49)&&(i<60)){P0=dig[h1][(i-50)*3];P1=dig[h1][(i-50)*3+1];P2=dig[h1][(i-50)*3+2];DelayUs(20);}
- if((i>59)&&(i<70)){P0=dig[h2][(i-60)*3];P1=dig[h2][(i-60)*3+1];P2=dig[h2][(i-60)*3+2];DelayUs(20);}
- if((i>69)&&(i<80)){P0=dig[10][(i-70)*3];P1=dig[10][(i-70)*3+1];P2=dig[10][(i-70)*3+2];DelayUs(20);}
- if((i>79)&&(i<90)){P0=dig[m1][(i-80)*3];P1=dig[m1][(i-80)*3+1];P2=dig[m1][(i-80)*3+2];DelayUs(20);}
- if((i>89)&&(i<100)){P0=dig[m2][(i-90)*3];P1=dig[m2][(i-90)*3+1];P2=dig[m2][(i-90)*3+2];DelayUs(20);}
- if((i>99)&&(i<110)){P0=dig[10][(i-100)*3];P1=dig[10][(i-100)*3+1];P2=dig[10][(i-100)*3+2];DelayUs(20);}
- if((i>109)&&(i<120)){P0=dig[s1][(i-110)*3];P1=dig[s1][(i-110)*3+1];P2=dig[s1][(i-110)*3+2];DelayUs(20);}
- if((i>119)&&(i<130)){P0=dig[s2][(i-120)*3];P1=dig[s2][(i-120)*3+1];P2=dig[s2][(i-120)*3+2];DelayUs(20);}
- if(i>129){P0=0xFF;P1=0xFF;P2=0xFF;DelayUs(20);}
- break;
- }
- }
- }
复制代码
代码下载(Keil2工程文件):
摇摇棒2.3软件版本3.1 时钟显示.7z
(16.53 KB, 下载次数: 305)
|