工程师表白神器--炫彩心形DIY

假装没事ソ 提交于 2019-11-28 20:01:15

这段时间做了个玩具,用彩色LED搭建了一个心形图案,并用STC51单片机驱动,实现心形LED炫彩闪动,超级炫酷的,总工有32个灯,使用了单片机的所有IO口,可以灵活控制每个LED的闪烁,然后配上适合的音乐,绝对是屌丝工程师表白神器,先上两张图看看:



接下来简单说下实现过程:

将32个LED分成4组LED_P0,LED_P1,LED_P3,LED_P2,每一组代表8个LED灯,也就是讲心形分成4个部分, 如下图所示,这样,我们只需操作这些值,然后将这些值对应到相应的IO口上就可以了


为了便于操作,我们对每一组单独做了几个动作,然后将这些动作已多种方式结合起来,就可以啦。

基本动作:

uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移
uchar code table1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED从高位往低位移
uchar code table2[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};//LED从1个亮到8个都点亮(从低位往高位)
uchar code table3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};//LED从1个亮到8个都点亮(从高位往低位)
uchar code table4[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//LED从8个全亮到一个都不亮(从低位往高位)
uchar code table5[]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};//LED从8个全亮到一个都不亮(从高位往低位)
uchar code table6[]={0xfe,0xfc,0xfa,0xf6,0xee,0xde,0xbe,0x7e};//LED从低位往高位移(最低位始终为0)
uchar code table7[]={0x7f,0x3f,0x5f,0x6f,0x77,0x7b,0x7d,0x7e};//LED从高位往低位移(最高位始终为0)

下面我们将LED顺时针旋转一周,如下:

void disp1()			
{
	for(i=0;i<8;i++)
	{
		LED_P2=table1[i];
		Display(100);
	}
	LED_P2=0xff;
	for(i=0;i<8;i++)
	{
		LED_P3=table1[i];
		Display(100);
	}
	LED_P3=0xff;
	for(i=0;i<8;i++)
	{
		LED_P1=table1[i];        
		Display(100);
	}
	LED_P1=0xff;
	for(i=0;i<8;i++)
	{
		LED_P0=table1[i];
		Display(100);
	}
	LED_P0=0xff;
}

为了方便布线,我们的LED灯的位置并不是个单片机IO口严格对应的,所以我们要在显示函数里面做好对应关系,一起刷新显示:

//将LED_P0,LED_P1,LED_P3,LED_P2的值的对应到具体IO口上,并延时
void Display(uint time)	
{
	P0 = ((LED_P0 & 0xfe)>>1) + ((LED_P1 & 0x01)<<7);
	
	P1 = ((LED_P1 & 0xfe)>>1) + ((LED_P3 & 0x01)<<7);
	
	P3 = ((LED_P3 & 0xfe)>>1) + ((LED_P2 & 0x01)<<7);
	
	P2 = ((LED_P2 & 0xfe)>>1) + ((LED_P0 & 0x01)<<7);
	
	Delayms(time);
}

将LED顺时针旋转一周只是一周场景,这里可以t提供40多种场景,可以自由搭配顺序哦,实现方法也是很简单的:

#define SCENE_COUNT 20//定义循环播放发的数量

//可自定义场景,按场景顺序播放多种状态
uchar scene[SCENE_COUNT] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

选择要显示的场景函数:

void DispStatus(unsigned char index)
{
	switch(index)
	{
		case 0	:disp0()	;	break;
		case 1	:disp1()	;	break;
		case 2	:disp2()	;	break;
		case 3	:disp3()	;	break;
		case 4	:disp4()	;	break;
		case 5	:disp5()	;	break;
		case 6	:disp6()	;	break;
		case 7	:disp7()	;	break;
		case 8	:disp8()	;	break;
		case 9	:disp9()	;	break;
		case 10	:disp10()	;	break;
		case 11	:disp11()	;	break;
		case 12	:disp12()	;	break;
		case 13	:disp13()	;	break;
		case 14	:disp14()	;	break;
		case 15	:disp15()	;	break;
		case 16	:disp16()	;	break;
		case 17	:disp17()	;	break;
		case 18	:disp18()	;	break;
		case 19	:disp19()	;	break;
		case 20	:disp20()	;	break;
		case 21	:disp21()	;	break;
		case 22	:disp22()	;	break;
		case 23	:disp23()	;	break;
		case 24	:disp24()	;	break;
		case 25	:disp25()	;	break;
		case 26	:disp26()	;	break;
		case 27	:disp27()	;	break;
		case 28	:disp28()	;	break;
		case 29	:disp29()	;	break;
		case 30	:disp30()	;	break;
		case 31	:disp31()	;	break;
		case 32	:disp32()	;	break;
		case 33	:disp33()	;	break;
		case 34	:disp34()	;	break;
		case 35	:disp35()	;	break;
		case 36	:disp36()	;	break;
		case 37	:disp37()	;	break;
		case 38	:disp38()	;	break;
		case 39	:disp39()	;	break;
		case 40	:disp40()	;	break;
		case 41	:disp41()	;	break;
		default: break;		
	}
}

主函数循环播放设定好的场景

void main()
{	
	int i;
	while(1)
	{
		//按照自定义场景循环播放
		for(i=0;i<SCENE_COUNT;i++)
		{
			DispStatus(scene[i]);
		}
	}
}

这样一个表白神器就完成了,有需要的或者有其他问题的亲猿们,如果有需要可以直接评论我就好了哦。

git下载地址:https://github.com/zhui-ying/HeartColorLEDDIYcode.git


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!