旋转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.
分辨率是560*128.
一周热门 更多>