前言
物联网工程专业大三升大四的实习,主管要我搞一套方案,这套方案简单来说就是用最少的单片机来控制最多的灯。一开始的想法是用ESP8266来驱动WS2812B,实际成本也不高,一套下来30多,所以我自掏腰包直接买了实物,成品也做出来了,但和实际想要的方案不是很符合(有想要ESP8266驱动WS2812B,控制灯带上任意一个RGB的亮灭和颜色的可以私信我),后来我才知道具体方案想要的是LED灯,而不是WS2812B那样的RGB彩灯灯带。之后我查阅了很多网上的资料,将它们和自己的实践全部整合起来,完成了模拟仿真部分,现在我将模拟仿真的成品给大家分享一下。
所需软件和材料
我用到的软件是:Keil 5、Proteus8
所需要的硬件有:一个AT89C52、N个74HC595、电磁式继电器(Proteus搜索relay)、N个电源、N个LED
PROTEUS仿真设计图
由于画布太大,我把整张设计图的截图分成两张。这里我只级联了两个74HC595,使用了16个LED,展示的是第2、6、11、12个LED不亮,其他全部点亮。AT89C52左半边连接的是最小系统,仿真的时候画不画最小系统对仿真结果没有影响,读大学的话只有专业课的老师会让你到黑板上去画或者考试的时候让你画出来。级联的两个74HC595的11引脚SH_CP和12引脚ST_CP连在一块,再一起接到单片机的IO口。第一片74HC595的14引脚DS,直接接到单片机的IO口,从级联的第二片74HC595开始,DS引脚接到上一个74HC595的Q7'引脚,也就是74HC595的第9个引脚。74HC595的Q0到Q7后面接继电器、电源和LED,所有的LED共地才可以正常工作,至于为什么我也不知道。
为什么我要加继电器和电源呢,因为我要用到的符合方案需求的LED,我搜索到的最低是12V,而AT89C52和74HC595哪个都不能输出和承载那么大的电压,所以为了满足需求额外加了电源,而继电器是为了保护电路才加上去的。
具体代码
想要控制哪个灯的亮灭直接去led_control()函数里修改0和1即可
#include "REG52.H"
#define const_time_level 200
void initial_myself();
void initial_peripheral();
void delay_short(unsigned int uiDelayShort);
void delay_long(unsigned int uiDelaylong);
void led_control();
void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01);
void led_update();
void T0_time();
sbit hc595_sh_dr=P2^1;
sbit hc595_st_dr=P2^2;
sbit hc595_ds_dr=P2^0;
sbit open=P2^3;
unsigned char ucLed_dr1=0;
unsigned char ucLed_dr2=0;
unsigned char ucLed_dr3=0;
unsigned char ucLed_dr4=0;
unsigned char ucLed_dr5=0;
unsigned char ucLed_dr6=0;
unsigned char ucLed_dr7=0;
unsigned char ucLed_dr8=0;
unsigned char ucLed_dr9=0;
unsigned char ucLed_dr10=0;
unsigned char ucLed_dr11=0;
unsigned char ucLed_dr12=0;
unsigned char ucLed_dr13=0;
unsigned char ucLed_dr14=0;
unsigned char ucLed_dr15=0;
unsigned char ucLed_dr16=0;
unsigned char ucLed_update=0;
unsigned char ucLedStep=0;
unsigned int uiTimeCnt=0;
unsigned char ucLedStatus16_09=0;
unsigned char ucLedStatus08_01=0;
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
open=1;
while(1)
{
led_control();
led_update();
}
}
void led_update()
{
if(ucLed_update==1)
{
ucLed_update=0;
if(ucLed_dr1==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x01;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xfe;
}
if(ucLed_dr2==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x02;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xfd;
}
if(ucLed_dr3==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x04;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xfb;
}
if(ucLed_dr4==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x08;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xf7;
}
if(ucLed_dr5==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x10;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xef;
}
if(ucLed_dr6==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x20;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xdf;
}
if(ucLed_dr7==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x40;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xbf;
}
if(ucLed_dr8==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x80;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0x7f;
}
if(ucLed_dr9==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x01;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xfe;
}
if(ucLed_dr10==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x02;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xfd;
}
if(ucLed_dr11==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x04;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xfb;
}
if(ucLed_dr12==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x08;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xf7;
}
if(ucLed_dr13==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x10;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xef;
}
if(ucLed_dr14==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x20;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xdf;
}
if(ucLed_dr15==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x40;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xbf;
}
if(ucLed_dr16==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x80;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0x7f;
}
hc595_drive(ucLedStatus16_09,ucLedStatus08_01);
}
}
void hc595_drive(unsigned char ucLedStatusTemp16_09,unsigned char ucLedStatusTemp08_01)
{
unsigned char i;
unsigned char ucTempData;
hc595_sh_dr=0;
hc595_st_dr=0;
ucTempData=ucLedStatusTemp16_09;
for(i=0;i<8;i++)
{
if(ucTempData>=0x80)hc595_ds_dr=1;
else hc595_ds_dr=0;
hc595_sh_dr=0;
delay_short(15);
hc595_sh_dr=1;
delay_short(15);
ucTempData=ucTempData<<1;
}
ucTempData=ucLedStatusTemp08_01;
for(i=0;i<8;i++)
{
if(ucTempData>=0x80)hc595_ds_dr=1;
else hc595_ds_dr=0;
hc595_sh_dr=0;
delay_short(15);
hc595_sh_dr=1;
delay_short(15);
ucTempData=ucTempData<<1;
}
hc595_st_dr=0;
delay_short(15);
hc595_st_dr=1;
delay_short(15);
hc595_sh_dr=0;
hc595_st_dr=0;
hc595_ds_dr=0;
}
void led_control()
{
switch(ucLedStep)
{
case 0:
if(uiTimeCnt>=const_time_level)
{
uiTimeCnt=0;
ucLed_dr1=1; ucLed_dr9=1;
ucLed_dr2=0; ucLed_dr10=1;
ucLed_dr3=1; ucLed_dr11=0;
ucLed_dr4=1; ucLed_dr12=0;
ucLed_dr5=1; ucLed_dr13=1;
ucLed_dr6=0; ucLed_dr14=1;
ucLed_dr7=1; ucLed_dr15=1;
ucLed_dr8=1; ucLed_dr16=1;
ucLed_update=1;
ucLedStep=1;
}
}
}
void T0_time() interrupt 1
{
TF0=0;
TR0=0;
if(uiTimeCnt<0xffff)
{
uiTimeCnt++;
}
TH0=0xf8;
TL0=0x2f;
TR0=1;
}
void delay_short(unsigned int uiDelayShort)
{
unsigned int i;
for(i=0;i<uiDelayShort;i++)
{
;
}
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uiDelayLong;i++)
{
for(j=0;j<500;j++)
{
;
}
}
}
void initial_myself()
{
TMOD=0x01;
TH0=0xf8;
TL0=0x2f;
}
void initial_peripheral()
{
EA=1;
ET0=1;
TR0=1;
}
感谢
从无从下手到项目理论完成花了半个月时间,因为基础不牢固很多东西都不懂,一开始的时候我直接去问了我的物联网老师,结果问的老师沉默了哈哈哈。感谢在网上无私奉献自己成果的各位。最后特别感谢一个人,他分享的代码是实现我这个项目最关键的部分,原帖https://www.21ic.com/mcucourse/201507/635863.htm