基于51单片机的旋转LED

大三的期末设计(大三好几个期末设计),当初感觉这个东西挺酷炫的,就去搞了一下,然而未曾料到,大三期末太多设计,同时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;

        }      

 

还有红外解码的代码就不给出来了,想了解的网上搜索一下,大把的资料
  • 45
    点赞
  • 224
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值