我也来个旋转LED【恢复】

2020-01-21 21:42发布

旋转LED挺好玩,简单的电路就能获得不错的显示效果,看到论坛有不少旋转LED的帖子,就参考做了一个,效果还不错。

下面是硬件的照片:



 (原文件名:旋转LED硬件照片.JPG) 

能转的部分被架在一个小直流电动机轴上,万用板上面放了一个最小89S52系统和16个发光二极管。单片机通过电动机轴和简易电刷供电,因为配重不很平衡会震动,有时会瞬间掉电,为了稳定加了一个1000uF的电容。在万用板上的89S52引出了MISO,MOSI,SCLK,RST四个引脚通过插针引脚和我的89S52实验板的对应引脚相连,以便ISP编程(要拔掉实验板上的89S52芯片)。另外单片机的电源也是通过引线来自于实验板。电动机是用1节5号电池供电。

程序设定为显示电动机转过的总圈数。



 (原文件名:AT89S52板子照片-上传版.JPG) 

转起来之后显示的效果如下:



 (原文件名:旋转LED效果照片1.JPG) 





 (原文件名:旋转LED效果照片.JPG) 



补充以下源代码:

#include"at89x52.h"

/*

P2口连接外侧8个led

P0口连接内侧8个led

MISO,MOSI,SCLK,RST通过插针引出



旋转LED显示当前电机转过的圈数

*/

//0-9数字编码库8*8数字的编码库 

code unsigned char NumTable[10][8]=

{

        {0x00,0xFF,0x81,0x81,0x81,0xFF,0x00,0x00},/*"0"*/

        {0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00},/*"1"*/

        {0x00,0xF1,0x91,0x91,0x91,0x9F,0x00,0x00},/*"2"*/

        {0x00,0x91,0x91,0x91,0x91,0xFF,0x00,0x00},/*"3"*/

        {0x00,0x1F,0x10,0x10,0x10,0xFF,0x00,0x00},/*"4"*/

        {0x00,0xCF,0x89,0x89,0x89,0xF9,0x00,0x00},/*"5"*/

        {0x00,0xFF,0x89,0x89,0x89,0xF9,0x00,0x00},/*"6"*/

        {0x00,0x01,0x01,0x01,0x01,0xFF,0x00,0x00},/*"7"*/

        {0x00,0xFF,0x89,0x89,0x89,0xFF,0x00,0x00},/*"8"*/

        {0x00,0x8F,0x89,0x89,0x89,0xFF,0x00,0x00} /*"9"*/

};

unsigned char DisplayBuffer[90];

unsigned char counter=0;

unsigned char index=0;  //180份之一的指针

unsigned char old_th1,old_tl1;

unsigned char Round=0;

unsigned long RoundCounter=0;

void int0Svr(void) interrupt 0

{

    unsigned long temp32;

    unsigned char orderOfNum=0;

    unsigned char temp,i,j;

    temp32 = counter;

    temp32 = temp32<<16;

    temp32 = temp32+TH0*256+TL0;

    temp32 = temp32/180;

    temp32 = 0xffff - temp32;

    TL1 = temp32 & 0xff;

    old_tl1 = TL1;

    TH1 = (temp32>>8)&0xff;

    old_th1 = TH1; 

    RoundCounter++;//圈数加1

//取出圈数的对应位(个位、十位、百位、千位,万位,十万位)

//从个位取起

    orderOfNum = 0;

    temp32 = RoundCounter;

    for(i=0;i<6;i++)

                {

            temp = temp32 %10;

                   for(j=0;j<8;j++)

                         {

                           DisplayBuffer[(5-i)*8+j] = NumTable[temp][j];//数字

                         }

                         temp32 = temp32/10;

                }

                index = 0;

                P0++;//修改P0口内容,增强显示效果



                if(Round==0)

                {

            TR0 = 1;         

            Round++;

                }else

                {

            TR1 = 1;

            TR0 = 1;

                } 

                counter = 0;

        TH0 =0;

        TL0 =0;

}

void temer0Svr(void) interrupt 1

{

  counter++;

}



void timer1Svr(void) interrupt 3

{

    TR1 = 0;

    TL1 = old_tl1+8;

        TH1 = old_th1;

     TR1 = 1;

    if(index<90)

        {

        P2 = ~DisplayBuffer[index];        

    }else 

        {

        P2 = ~DisplayBuffer[index-90];         

        }

        index++;        

//达到180说明原定速度下一周已经完成

//如果还没有重新被归零说明没有经过磁铁,可能减速或者要停下来了

  if(index==180)// 

        {

                TR1 = 0;

                P2 = 0xff;

                P0 = 0xff;

        }

}



void main(void)

{

        EA=1;

        IT0=1;

        EX0=1; 

        SP=128;

    P0=0;

    P2=0;

    TMOD=0x11;//定时器T0工作于方式1由TR0开启,定时器T1工作于方式1由TR1开启

        TCON=1;//INT0边沿触发方式

    IE=0x8b;

        TR0 = 1;

        while(1)

        {        

          if(counter>30)  //30*定时器1溢出周期,30*64ms=1.9s,这么久没有归零一般电机停下来了

                {

                        P2 = 0xff;

                        P0 = 0xff;

                        counter = 0;

                        TR0 = 0;  //关闭2个定时器

                        TR1 = 0;

                        PCON = PCON & 0x02;//进入掉电模式,节能;由中断重新激活                  

                }

        }

} 





本贴被 hithyy 编辑过,最后修改时间:2008-10-27,12:53:32.
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。