原创 POV LED(我的新版旋转灯)三

2012-8-12 10:46 3637 15 15 分类: 工程师职场

由于我没有画电路图。所以,也没有什么电路图给大家看。电路很简单。LED电路使用共阳接法,串接的是330欧姆的电阻。电阻和LED的型号都是0805. 从最外圈向里数,依次是一个绿色LED灯(接P6口),P6口我只用了这一个灯,所以我也没有记是哪一位,直接对P6OUT操作就可以控制这一个绿色灯了。然后是8个led灯(P3口),8个LED灯(P4口) ,8个led灯(P5口)4个led灯(P2口)。中断部分使用的是红外对管,电路也很简单了。还有一个就是电容电路。这个就是反接了一个二极管。电路如下所示:

20120812103621227.gif

下面是源程序:

 

/************************************************************
表盘显示和指针控制文档
时间 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[]={

//里面显示三龙维修班五个字,24位汉字


};

const unsigned char zimo[]={

//字模部分去掉了 16位汉字

};

const unsigned char biaopan[120]={
    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;i<112;i++)
          ;
    }
}
//专门用于显示三龙维修班几个字的时候使用
void delay_sanlong(int ms)
{
  char i;
  while(ms--)
  {
      for(i=0;i<2;i++)
        ;
  }
}
 
void wait()
{
   unsigned char i;
   for(i=0;i<10;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;p<360;)
              {
                  P3OUT = ~sanlong[p++];
                  P4OUT = ~sanlong[p++];
                  P5OUT = ~sanlong[p++];
                  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;p<320+m;)
              {
                  P3OUT = ~zimo[p++];
                  P4OUT = ~zimo[p++];
                  delayms(1);
                  P3OUT = 0XFF;
                  P4OUT = 0XFF;//置为高电平,目的是为了防止显示错乱。
              }
              //p = p+2;
              m = m+2;
              if(p>2336-240)
                //p=0;
                mu=2;//准备进入第三幕
        }
        if(mu==2)
        {
        for(p=0;p<120;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;p<120)
        }//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 fen>59
      if(ff>5)
      {
        ff=0;
        ffss++;
          if(ffss>9)
            ffss = 0;
      }
    }
}

文章评论0条评论)

登录后参与讨论
我要评论
0
15
关闭 站长推荐上一条 /2 下一条