tag 标签: 旋转灯

相关博文
  • 热度 14
    2012-8-12 11:03
    2847 次阅读|
    2 个评论
      视频的播放地址 http://v.youku.com/v_show/id_XNDM4MTYyMjIw.html   2.       程序编写         首先,我还是想的是直接显示汉字为主吧。这个程序和LED 点阵的是相似的。原理就不用再介绍了。直接写个程序就可以了。   呵呵 ,大白天的效果也是不错的啊。就是噪声有点大。估计是电机的原因了。   再往后就是这次制作POV LED 的重点了。怎么让他全屏滚动。这个我发现其实也是很简单。稍微改动一下显示的最大数据量就可以了。比如,上面的几个汉字,我只是显示了224 个数据(2 ×16 ×7 )。所以,适当的增加一点就可以满屏显示并滚动了。这个视频就不怎么样了。闪的厉害啊。   其实,我发现这个全屏的滚动,和电机旋转的稳定性有着至关重要的作用。当你调整好程序之后,却发现电机工作不稳定,一会快,一会慢,上面字来回移动,有的时候出现重叠的情况,整个屏都会闪的很厉害。所以,电机的选用也是一个重点,如果想接着往下做,就需要准备一个好的电机了,当然,选择一个步进电机自己控制速度,应该最理想吧?这个以后在验证了。     下面是开始制作表盘了啊。首先,由于我的单片机工作速度很慢,使用的是外部32768kHZ 的晶振,没有接高速晶振,所以只好将就了啊。我选定的一周是120 个点,也就是说,每2 个点表示1 的话,60 秒是正好的。那么,就在中断程序里面定义一个P ,是这个P 转一周正好是120 ,这个需要不断的调节你的延时函数。我的这个单片机的工作速度很低,所以调节的时间更长,这个也启发着我,以后一定要用高速晶振。速度在1M 以上最好。我之前的作品是51 单片机,但是外界的是24M 晶振啊。   先介绍一下我的电路吧,最外面的一个灯是绿色灯,初衷是用来表示秒针的。P3口(8个),P4口(8个),P5口(8个),P2口(2个)。一次排开,P2口在最里面。排的方法都是低位在外,高位在内,其中,P2口是P2.4~P2.7。绿灯是P6口,且只用 了一个,所以操作起来就方便了啊。操作一个绿灯只需要直接对P6 口操作就可以了。不用进行位操作了。P1 口是留给了红外中断了。 下面我们接着上面的说。整个圆周分成了120 份。每两个数表示一个秒数。这样,我们就可以使用下面的程序画出整个表盘来。                 if(p%10==0)//120/2/5=12, 表示12 个时针位置                   P3OUT = 0XF0;                 else if(p%2==0)                   P3OUT = 0XFC;                 else                   P3OUT = 0XFE; 如下面的图片所示:   表盘上暂时没有加上数字,是因为单片机的速度问题吧。把这个工作放到了最后了。先把指针给显示出来在说表盘上数字的问题也不迟。 下面我们重点分析指针的问题了。 第一个是非常简单的秒针了。秒针我只用最外面的绿灯来代替。如果用双色LED 表示时针和分针,那程序写起来就会方便很多了。 在制定位置显示秒针呗,程序如下:               // 下面部分用于显示秒针的位置                 if(p==miao*2)                   P6OUT = 0X00;// 显示出秒针                 else                   P6OUT = 0XFF;// 否则,不显示秒针的位置. 如果是秒针的位置,则显示秒针,否则,都熄灭LED灯。这样就可以了。我的板子上没有时钟芯片,所以我就使用定时器吧。使用MSP430内部的看门狗定时器, 定时一秒,这个不是很准确,但是,好几天错上一分钟两分钟的还是可以接受的。最主要的是,这个东西就是显示出来看看的,最起码,这个作品我还没有打算一直挂在墙上当钟的打算,等我下回把噪声给降低了,在做考虑吧。所以,表走走就行,能写出这个程序就算成功了啊。   下面在分析时针和分针了。这两个指针有相互重叠的地方。因为我打算使用P4 ,P5 ,P2 作为分针,P5 ,P2 作为秒针。重叠的地方怎么处理呢?这个就需要做出判断了啊。在写分针的时候,分针需要在擦除分针显示的时候,需要判断时针是否存在,如果时针存在,那么需要保留时针的显示。这个就是两个指针交叉问题我的解决方法。   我的指针,分针是小箭头,占用3 个格,分别是fen-1,fen,fen+1 。时针占用5 个格,分别是shi-2,shi-1,shi,shi+1,shi+2 。控制显示着部分的函数贴出来给大家看看。大家应该有比这个要好的多的方法,希望高手多多指教。               /***********************************************                 下面部分用于显示时针和分针,由于时针和分针是                 有一部分重合的地方,所以需要交叉讨论。               ***********************************************/                                                // 因为P4 部分不会影响到时针,所有先单独拿出来考虑                 if(fen == 0)                 {                     if(p==118)                       P4OUT = 0XFD;                     else if(p==2)                       P4OUT = 0XFD;                     else if(p==0)                       P4OUT = 0X00;                     else                       P4OUT = 0XFF;                 }                 else  if((p=(fen-1)*2)(p=(fen+1)*2))                 {                                      if(p==(fen-1)*2)                         P4OUT = 0XFD;// 分针箭头的左端                       // 这部分只有分针有,与时针不冲。                       if(p==(fen+1)*2)                         P4OUT = 0XFD;                       if(p==fen*2)                         P4OUT = 0X00;                 }                 else                       P4OUT = 0XFF;                                if((p==fen*2)(p==fen*2+1))                   {                     //P4OUT = 0X00;                     P5OUT = 0X00;                     P2OUT = 0X00;                   }                 else                 {                   // 先关闭所有的LED 灯,在考虑不同的情况。                   // 如果以下五种情况都不存在,那么就直接熄灭LED 灯就可以了                   // 注意,表芯是P2.7 ,这个灯不能熄灭,一直亮着。                   //P4OUT = 0XFF;                   P5OUT = 0XFF;                   P2OUT = 0X7F;                   // 重合的五种情况                   if(p==((shi*10-4)+ffss))                     P5OUT = 0XFB;                   else if(p==((shi*10-2)+ffss))                     P5OUT = 0XFD;                   else if(p==((shi*10)+ffss))                   {                     P5OUT = 0X00;                     P2OUT = 0X00;                   }                   else if(p==((shi*10+4)+ffss))                     P5OUT = 0XFB;                   else if(p==((shi*10+2)+ffss))                     P5OUT = 0XFD;                 }            上面的程序为什么要单独考虑fen=0 的情况呢?因为在分针指到0 处时,左边的数据应该是118 ,而右边的P 的值则成了2 了。中间的值正好是0. 所以这个位置不符合正常情况,所以需要拿出来单独处理了。时针也是需要单独处理的,不过时针的处理上面还没有,我还没有写。呵呵。         这个的效果已经可以满足我们的简单需求了。如下图所示了。           下面的工作就是给这个表盘上面添加上数字了。为了添加数字,我想,应该把分针变短一点啊。这样好腾出空来显示数字。因为,显示数字最起码需要6 个空的地方。不过,那样会同时使用P4 口和P3 口,这样很是麻烦,我还是先直接只使用P3 口来显示吧。情况要看看效果了啊。   自己算了一下,显示数字,最少要用5 个LED 灯,于是就自己做了张表格,看看到底哪些位需要用。做了一个table ,把数据放到里面,数据的低三位是用于给程许显示表盘的刻度的。所以,用一个 操作就可以了。 显示如下图所示:    
  • 热度 15
    2012-8-12 10:46
    3638 次阅读|
    0 个评论
    由于我没有画电路图。所以,也没有什么电路图给大家看。电路很简单。LED电路使用共阳接法,串接的是330欧姆的电阻。电阻和LED的型号都是0805. 从最外圈向里数,依次是一个绿色LED灯(接P6口),P6口我只用了这一个灯,所以我也没有记是哪一位,直接对P6OUT操作就可以控制这一个绿色灯了。然后是8个led灯(P3口),8个LED灯(P4口) ,8个led灯(P5口)4个led灯(P2口)。中断部分使用的是红外对管,电路也很简单了。还有一个就是电容电路。这个就是反接了一个二极管。电路如下所示: 下面是源程序:   /************************************************************ 表盘显示和指针控制文档 时间 2012年7月29日11:58:29 作者 朱志强 QQ   512826028 说明:在POV LED的LED板上,最上面的是一个绿色LED灯,控制口是P6       口中的一个,直接控制P6口即可。这个表示秒针。           其次是P3口,P4口,P5口和4个P2口。其中,P3口用于显示       表盘。显示60格和时针的12格。P4,P5口用于显示分针,P5,       P2口用于显示时针。 作用:本程序的作用就是验证时针和分针公用的P5,P2口的处理问题。 ************************************************************/ #include "MSP430X41X.H" unsigned int p,m; unsigned char shi,fen,ff,ffss,miao; unsigned char bp;//用于保存暂时的表盘显示数据。 unsigned char mu;//用于显示图像的切换,初始值是0。 unsigned char sanlong_i;//显示三龙维修班的时候的计数,用于统计显示的次数是否到 unsigned char sanlong_ms;//用于控制显示三龙维修班这几个字的速度。 unsigned char sanlong_flag;//方向标志 const unsigned char sanlong ={ //字模部分去掉了 16位汉字 }; const unsigned char biaopan ={     0x17,0x57,0x47,0xff,0xff,0xff,0xff,0xff,0xff,//2(12)     0xff,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//1     0x17,0x57,0x47,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//2    //表盘部分显示是自己弄的。数字占用5位。从最开始的位置显    //示12点的2字,然后是1,2,3,一直到12点的1字。正好是表盘的一周。 }; void delayms(int ms) {     char i;     while(ms--){         for(i=0;i112;i++)           ;     } } //专门用于显示三龙维修班几个字的时候使用 void delay_sanlong(int ms) {   char i;   while(ms--)   {       for(i=0;i2;i++)         ;   } }   void wait() {    unsigned char i;    for(i=0;i10;i++)    {       P6OUT = 0X00;       delayms(3000);       P6OUT = 0XFF;       delayms(3000);    } } void main( void ) {   // Stop watchdog timer to prevent time out reset   //WDTCTL = WDTPW + WDTHOLD;   WDTCTL = WDTPW + WDTTMSEL + WDTSSEL;   //打开看门狗定时器,定时时间 1s,使用的是ACLK时钟   SCFQCTL = 0xff;       P4DIR = 0XFF;//P4口输出   P3DIR = 0XFF;   P6DIR = 0XFF;   P5DIR = 0XFF;   P2DIR = 0XFF;     //中断控制部分,输入中断和看门狗的1秒定时中断   P1DIR = 0X00;   P1IE  = 0XF0;//P1.4~P1.7中断使能   P1IES = 0XF0;//下降沿触发中断    IE1 |= WDTIE;//打开WDT中断     p = 0;//防止出现错乱     mu = 0;//初试是显示第一幕,第一幕是显示汉字。     //给时分秒初始化一个任意的初值   shi = 1;   fen = 0;   ff  = 0;//这个数据与分钟一起计数,用于控制ffss   ffss= 0;//每当数据ff技术到6,ffss加一,用于控制时针的位置。   miao= 0;     sanlong_i=0;   sanlong_ms=0;   sanlong_flag=0;     wait();   __enable_interrupt();//打开全局中断     while(1)   {     P2OUT = 0X7F; //点亮表心。   } } #pragma vector = PORT1_VECTOR __interrupt void P1INT() {     if(P1IFG 0X40)     {       if(P1IFG 0X40)       {         if(mu==0)         {               for(p=0;p360;)               {                   P3OUT = ~sanlong ;                   P4OUT = ~sanlong ;                   P5OUT = ~sanlong ;                   delay_sanlong(sanlong_ms);                   P3OUT = 0XFF;                   P4OUT = 0XFF;//置为高电平,目的是为了防止显示错乱。                   P5OUT = 0XFF;               }               sanlong_i++;               if(sanlong_i=5)               {                  sanlong_i=0;                  if(sanlong_flag==0)//如果是增加                  {                     sanlong_ms++;                     if(sanlong_ms=40)                        sanlong_flag=1;//改为减模式                  }                  if(sanlong_flag==1)                  {                       sanlong_ms--;                       if(sanlong_ms=0)                         //sanlong_flag=0;//显示完一遍之后,开始进入第二幕                         mu= 1;                  }               }//end sanlong_i=5         }//end mu ==0;         if(mu==1)         {               for(p=m;p320+m;)               {                   P3OUT = ~zimo ;                   P4OUT = ~zimo ;                   delayms(1);                   P3OUT = 0XFF;                   P4OUT = 0XFF;//置为高电平,目的是为了防止显示错乱。               }               //p = p+2;               m = m+2;               if(p2336-240)                 //p=0;                 mu=2;//准备进入第三幕         }         if(mu==2)         {         for(p=0;p120;p++)         {             if(p%10==0)//120/2/5=12,表示12个时针位置                   P3OUT = 0XF0;                 else if(p%2==0)                   P3OUT = 0XFC;                 else                   P3OUT = 0XFE;             P3OUT = biaopan P3OUT;             //下面部分用于显示秒针的位置             if(p==miao*2)                   P6OUT = 0X00;//显示出秒针             else                   P6OUT = 0XFF;//否则,不显示秒针的位置.               /***********************************************                 下面部分用于显示时针和分针,由于时针和分针是                 有一部分重合的地方,所以需要交叉讨论。               ***********************************************/                                                //因为P4部分不会影响到时针,所有先单独拿出来考虑                 if(fen == 0)                 {                     if(p==118)                       P4OUT = 0XFD;                     else if(p==2)                       P4OUT = 0XFD;                     else if(p==0)                       P4OUT = 0X00;                     else                       P4OUT = 0XFF;                 }                 else  if((p=(fen-1)*2)(p=(fen+1)*2))                 {                                      if(p==(fen-1)*2)                         P4OUT = 0XFD;//分针箭头的左端                       //这部分只有分针有,与时针不冲。                       if(p==(fen+1)*2)                         P4OUT = 0XFD;                       if(p==fen*2)                         P4OUT = 0X00;                 }                 else                       P4OUT = 0XFF;                                if((p==fen*2)||(p==fen*2+1))//注意,这个地方是或,不是与运算                   {                     //P4OUT = 0X00;                     P5OUT = 0X00;                     P2OUT = 0X00;                   }                   //先关闭所有的LED灯,在考虑不同的情况。                   //如果以下五种情况都不存在,那么就直接熄灭LED灯就可以了                   //注意,表芯是P2.7,这个灯不能熄灭,一直亮着。                   //P4OUT = 0XFF;                else                {                   P5OUT = 0XFF;                   P2OUT = 0X7F;                   //重合的五种情况                   if(p==((shi*10-4)+ffss))                     P5OUT = 0XFB;                   else if(p==((shi*10-2)+ffss))                     P5OUT = 0XFD;                   else if(p==((shi*10)+ffss))                   {                     P5OUT = 0X00;                     P2OUT = 0X00;                   }                   else if(p==((shi*10+4)+ffss))                     P5OUT = 0XFB;                   else if(p==((shi*10+2)+ffss))                     P5OUT = 0XFD;                 }                 delayms(1);         }//end for(p=0;p120)         }//end mu==2               }       P1IFG = 0;     } } #pragma vector=WDT_VECTOR __interrupt void wdt(void) {     miao++;//秒 ++     if(miao 1)     {       miao = 0;       fen  ++;       ff   ++;       if(fen 59)       {         fen = 0;         shi++;         if(shi 11)           shi = 0;       }//end fen59       if(ff5)       {         ff=0;         ffss++;           if(ffss9)             ffss = 0;       }     } }
  • 热度 14
    2012-8-12 10:16
    2088 次阅读|
    0 个评论
                POV LED 制作总结                         作者:朱志强 QQ : 512826028 邮箱 : i-love-zzq@163.com 时间: 2012 年 7 月 29 日 16:49:36       1. 准备工作     我是拿了公司一个报废的系统板,拆掉上面不用的东西。 去掉上面的排针, LCD ,还有反面的芯片。去成了这个样子了。         为什么选用这块板呢?是因为我想做一个能够全屏的 LED 灯,考虑到需要使用很多的 IO 口,就想起这块板的主意了。呵呵, IO 口基本上我能用的有 40 多个,虽然我用不到这么多 IO 口,但是,用 LCD 液晶留下的孔就可以方便我焊接了。也就省了打板了啊。            去的差不多了啊。留下了最主要的,复位电路,晶振,编程口。正面还留了一个 LED 灯,是用来查看板子是否正常工作的。注意,中间我还用胶*固定了一个电机上的小齿轮,这个是想用来固定板子用的,当然,最后又改动了很多次才成型。这个单片机最小系统就准备完毕了。下面开始着手制作 LED 灯吧。           我是直接从洞洞板上切下一条,作为焊接 LED 灯使用的。由于板材的有限,洞洞板的长度决定可以焊接多少个 LED 灯啊。每一个孔上焊接一个正好。使用的电阻是 330 欧姆的。测试过亮度,无论是灌电流还是拉电流,亮度都很好。这个主要取决去 MSP430 的拉电流能力比普通 51 单片机强很多啊。         焊功不大行啊,整的外扭七八的,技术不行不能怨烙铁啊。 LED 使用的是共阳接法,左边使用一个细丝把所有的电阻都连接起来。右边的孔就是连接单片机 IO 口的了。    连接的线怎么选择呢?为了保证作品的重量和质量,我选用是电机里面的细丝,这个事可以保证绝对绝缘的啊。上一次作品使用的是比这个粗的变压器线。这次这个方面进步不小,给我这个破焊功也好好的上了一个实训课。呵呵。         不信,你来看一看啊,就用这个细丝啊。毕竟,我在做传电部分的时候,拆了几个电机,不废物利用,多浪费啊?这个也不和我们玩电子的初衷嘛!一般我对这个的解决办法就是用火烧啊。于是下楼专门买了一个打火机,结果,用火烧的效果非常的不理想,我还是用我的老本行,小心的用刀片刮去导线外面的绝缘物质。这个苦逼了啊。。。 555. 。。。         我在焊接之前,先是打了一个孔,固定了一个螺栓,目的是为了防止 led 的这个小板乱动,它可不能乱动啊,一不小心,把线给弄断了,可有的哭了。     我的方法是,先给单片机写好一个能够把所有 LED 灯都给点亮的程序,然后在开始焊接,每焊接好一根线,就要通电测试一下,因为每一根线都是离得很近,而且我的烙铁头还老大,很容易焊连,要是都焊接好了,才发现中间的某一个接触不良,那就死翘翘了啊。         耐心的一个个焊吧。         焊接完毕之后,我就写了一个简单的流水灯程序,来验证自己焊接时对应的 IO 口是否正确。这一步很重要啊,要是发现 IO 口焊反了,顺序不对,将来怎么显示汉字呢?         效果还是不错的。亮度是相当的可以啊。总算不用经历我上一次的那个痛苦了,晚上关了灯才勉强看得见啊。            这部分搞定之后,我就可以开始鼓捣电机部分了。         在网上看了很多网友的作品,但是电刷都是自己制作。我可不知道自己做的怎么样啊。想起来电机里面有了,于是就取下电机里面的电刷,当做通电的电刷了。     但是,这个东西真的是太脆弱了啊。我开开心心的整这个电刷,还没有整好呢,两个小电刷都一命呜呼了。无奈,我只好再拆一个电机。这种小电机上面都会有固定的小孔,我就利用这个小孔,切小块的 PCB 板,把电刷焊接到 PCB 板上,然后再用螺丝固定在电机上,这样就可以稳定电刷了啊。         问题又出现了,我怎么才能够固定好电刷呢?我想来想去,最后想了一个非常不错的方法,就是在最小系统板上面开了一个孔,这个孔正对着下面的螺丝孔,而且可以容下一个螺丝刀。这样,我就可以先固定好旋转部分,在调节电刷,最后再用螺丝刀固定死电刷了。         我为什么这么做,你看了我的链接部分就知道了。这部分没有拍多少照片,可以看一下这个地方,也是可以了解到的。         我在电机齿轮的外面套了两个一样大小的铜环,中间用纸和胶作为绝缘,把这个部分固定到了齿轮上。并用万能胶给粘牢固了。电刷呢,也像电机里面那个样子,一高一低,通过移动所在的 PCB 小板,使其连接好了,在固定好螺丝。           通电测试了一下,发现程序一直在复位,估计是我的电刷太小了,而且铜环放的圆心不是很正。怎么调节电刷也没有解决这个问题,期间还弄坏了一个电刷。最后不得不使用歪招,在上面接了一个超级电容,让电容工作,而电刷就是给电容充电吧。这样,就不会在旋转的时候断电了。           判断中断的部分,我这次选用的是红外对管,没有在使用霍尔传感器。自己写了一个下降沿有效的中断程序,测试正常。让后我就可以开始大干一场了啊。