大三的期末设计(大三好几个期末设计),当初感觉这个东西挺酷炫的,就去搞了一下,然而未曾料到,大三期末太多设计,同时51单片机的项目以前有做过,就没花很多时间在这个设计上,做了一周多,效果差强人意。
先来看看视频效果:链接:http://pan.baidu.com/s/1gfiESpX 密码:1f3w
本来可以更好的,还想在垂直面上加一排led做为显示的,结果就是学校的PCB板太重,加上去的话电机转速不够,所以就只有水平面的显示。下面给出制作方案,仅供参考:
(1)功能框架:
图1、整体框架
(2)使用器件:
①89C52单片机(由于51内部储存有限,选择52型号)、DS1302芯片;
②红外接收模块(一体化红外接收头、1.2K电阻);
③红外对管(接收与发射各一个);
④红LED灯16个、电容电阻若干;
⑤无线供电线圈一对;
⑥直流电机、底座硬件。
二、电路工作原理:
人眼具有视觉暂留的错觉,无法区分间隔小于0.1s的图像。
因此,我们所要设计的旋转时钟大体有两部分构成:单片机控制系统部分和电机转动部分。
单片机控制部分由一系列的二极管及单片机最小系统组成。主要用来控制各二极管的亮与灭、计时等,以正确显示相应时间所对应的数字。
电机转动部分是一个直流电机,带上负载后,转速有所下降,电机带动单片机系统板和外围LED板转动。
这样,旋转时钟的基本框架就已构成:通过单片机控制二极管的亮灭,利用电机的转动,使人眼产生视觉暂留的错觉,呈现出数字时钟的走动的图像。
三、编程流程图:
图2、编程流程图
四、制作过程:
(1)仿真原理图:
图3、仿真原理图
LED以共阳相接,无线供电模块包括整流电路。
(2)PCB制作:
图4.1、PCB制作
左边为单片机主控模块和DS1302数字芯片模块,左下为整流电路,右边为LED显示模块。由于提供的PCB为单面板,在背面会有几个跳线,最终只打印顶层(红色)。中间三块的铜片是轴心位置。后期又另外加上了两个模块的小板。
(3)硬件搭建:
①底座部分:
图5.1、底座部分
底座由两块塑料板构成,主要以平整、宽大来尽量保证旋转时能保持整体稳定,各支撑点使用胶枪加固。
②旋转部分:
图5.2.1、正面
图5.3、旋转部分反面
由于单面板的限制,有些电路连接需要通过跳线连接,轴心(即感应线圈)两侧重量基本一致,红外对管接收调节模块为了使信号更加灵敏。
③整体:
图6、整体
最后经过各种测试修改后,我们不得不重新制作新的PCB,模块大致相同,与图6.1相比少了侧面LED模块(由于太重,轴心太靠一边,如若要使得整体左右平衡需要添加更多的重物,从而使得电机无法带动这么重的板子)和放弃了74595芯片(由于放弃了侧面板,单片机引脚完全够用,所以没必要用595驱动)。
(4)调试以及问题解决:
①结构问题:
我们认为,整机的机械结构是决定作品成败的关键。经过试验,结构强度对稳定性影响很大,因此采用四个长螺丝为支架,以半径较大的厚塑料板板为底,同时对转盘进行平衡调节,基本解决了转动的稳定性问题。
②供电问题:
由于我们的电路板是随主框架一起高速旋转的,所以不可能使用导线进行供电,因为这样会把导线缠上。于是采用无线供电,用两个感应线圈在旋转中产生供应的电,再经过整流电路来产生稳定的5V电压以供单片机以及其他元件的供电。
③、信号传输问题
由于控制单片机是在旋转的支架上,从外部到单片机的数据传送也成了一个问题。数据的传输不能采用电刷来进行,因此采用了红外传输的方式。使用了带有放大和解调功能的接收模块,很好地解决了这一问题,但由于高速旋转,遥控信号的接收有时也不太灵敏。
④、同步问题
显示的图像或文字要稳定,同步是关键。要达到同步的目的,同步信号的取得是关键。最后使用了红外对管以及增加灵敏度的比较器模块来校准每一圈,达到很好的效果。
下面给出代码:
#include<reg52.h>
#include"HW.h"
#define ucharunsigned char
#define uintunsigned int
uchar yiwei=0; //移位
uchar KSZ=0; //默认从第0个字开始移动
uchar ZS; //控制显示字数
uchar ZQLC=0; // 逐圈亮参数
uchar ZQMC=0; // 逐圈灭参数
bit YW =0;
bit start =0;
bit done =0;
void show(ucharzishu,uchar lieshu,uchar a[][48],bit b);
void ZQL();
void ZQM();
void shownum(uchara[24]);
void init()
{
EX0=1;
EX1=1;
IT0=0;
IT1=0;
EA=1;
}
void delay(uint a)
{
uint b;
for(a;a>0;a--)
for(b=0;b<112;b++)
;
}
void delayus(uinta)
{
while(a--);
}
void main()
{
uint GNCST;
init();;
P2=0X7f;
P0=0Xff;
IRinit();
//Initial_DS1302();
while(1)
{
IRstart();
switch(GNCS)
{
case 0X01:show(ZS,24,zimo,YW);break;//0 显示相应的按键值
case 0x02:shownum(shuzi[1]);break;//1
case 0x03:shownum(shuzi[2]);break;//2
case 0X04:shownum(shuzi[3]);break;//3
case 0X05:shownum(shuzi[4]);break;//4
case 0X06:shownum(shuzi[5]);break;//5
case 0X07:shownum(shuzi[6]);break;//6
case 0X08:shownum(shuzi[7]);break;//7
case 0X09:shownum(shuzi[8]);break;//8
case 0X0a:shownum(shuzi[9]);break;//9
case0X0b:{ZS--;GNCS=GNCST;};break;//"-"
case 0X0c:{ZS++;GNCS=GNCST;};break;//+
case 0X0d:{YW=!YW;GNCS=GNCST;};break;// >||暂停
case 0X0e:ZQL();break;// |<<
case 0X0f:ZQM();break;// >>|
default:
{
P0=0X00;
P2=0X00;
};break;
}
if(ZS>8)ZS=8;
if(ZS<1)ZS=1;
GNCST=GNCS;
}
}
void DuiGuan(void)interrupt 0//红外对管
{
start =1;
}
void ZQL()//逐圈亮
{
if(start)
{
EX0=0;
if(ZQLC<8)
{
P0=(0x7f>>ZQLC);
P2=0xff;
}elseif((ZQLC>7)&&(ZQLC<16))
{
P2=(0x7f>>(ZQLC%8));
P0=0x00;
}
else
ZQLC=0;
ZQLC++;
delay(200);
start=0;
}
EX0=1;
}
void ZQM()//逐圈灭
{
if(start)
{
EX0=0;
if(ZQMC<8)
{
P0|=(0x80>>ZQMC);
P2=0x00;
}elseif((ZQMC>7)&&(ZQMC<16))
{
P2|=(0x7f>>(ZQMC%8));
P0=0xff;
}
else
ZQMC=0;
ZQMC++;
delay(200);
start=0;
}
EX0=1;
}
void shownum(uchara[24])
{
uchar i;
if(start)
{
EX0=0;
for(i=0;i<12;i++)
{
P0=a[i*2];
P2=a[i*2+1];
delayus(10);
P2=0xff;
P0=0xff;
}
start=0;
}
EX0=1;
}
void show(ucharzishu,uchar lieshu,uchar a[][48],bit b)
{
uchar i,j,yiweit1,yiweit2;
if(start) //红外接收管 判断起始位
{
EX0=0;
yiweit1=yiwei;
for(j=KSZ;j<zishu;j++)
{
for(i=yiweit1;i<lieshu;i++) //每转一圈 前进一列
{
P0=a[j][i*2];
P2=a[j][i*2+1];
delayus(10);
P2=0xff;
P0=0xff;
}
yiweit1=0;
}
for(j=0;j<KSZ+1;j++)
{
if(j==KSZ)
yiweit2=yiwei;
else
yiweit2=lieshu;
for(i=0;i<yiweit2;i++)
{
P0=a[j][i*2];
P2=a[j][i*2+1];
delayus(10);
P2=0xff;
P0=0xff;
}
}
if(b)
{
yiwei++;
if(yiwei==lieshu)
{
KSZ++;
yiwei=0;
}
if(KSZ==zishu)
{
KSZ=0;
yiwei=0;
}
}
start=0;
}
EX0=1;
}
还有红外解码的代码就不给出来了,想了解的网上搜索一下,大把的资料