最新74HC595驱动LED.docx
《最新74HC595驱动LED.docx》由会员分享,可在线阅读,更多相关《最新74HC595驱动LED.docx(10页珍藏版)》请在冰豆网上搜索。
最新74HC595驱动LED
74HC595-驱动LED
第17节:
两片联级74HC595驱动16个LED灯的基本驱动程序
时间:
2015-07-29
0
关键字:
[导读]从业将近十年!
手把手教你单片机程序框架第17讲:
开场白:
上一节讲了如何把矩阵键盘翻译成独立按键的处理方式。
这节讲74HC595的驱动程序。
要教会大家两个知识点:
第一点:
朱兆祺的学习板是用74HC595控制LED,因此可以
从业将近十年!
手把手教你单片机程序框架第17讲:
开场白:
上一节讲了如何把矩阵键盘翻译成独立按键的处理方式。
这节讲74HC595的驱动程序。
要教会大家两个知识点:
第一点:
朱兆祺的学习板是用74HC595控制LED,因此可以直接把595的OE引脚接地。
如果在工控中,用来控制继电器,那么此芯片的片选脚OE不要为了省一个IO口而直接接地,否则会引起上电瞬间继电器莫名其妙地动作。
为了解决这个问题,OE脚应该用一个IO口单独驱动,并且千万要记住,此IO必须接一个15K左右的上拉电阻,然后在程序刚上电运行时,先把OE置高,并且尽快把所有的74HC595输出口置低,然后再把OE置低.当然还有另外一种解决办法,就是用一个10uF的电解电容跟一个100K的下拉电阻,组成跟51单片机外围复位电路原理一样的电路,连接到OE口,这样确保上电瞬间OE口有一小段时间是处于高电平状态,在此期间,尽快通过软件把74hc595的所有输出口置低。
第二点:
两个联级74HC595的工作过程:
每个74HC595内部都有一个8位的寄存器,两个联级起来就有两个寄存器。
ST引脚就相当于一个刷新信号引脚,当ST引脚产生一个上升沿信号时,就会把寄存器的数值输出到74HC595的输出引脚并且锁存起来,DS是数据引脚,SH是把新数据送入寄存器的时钟信号。
也就是说,SH引脚负责把数据送入到寄存器里,ST引脚负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。
具体内容,请看源代码讲解。
(1)硬件平台:
基于朱兆祺51单片机学习板。
(2)实现功能:
两片联级的74HC595驱动的16个LED灯交叉闪烁。
比如,先是第1,3,5,7,9,11,13,15八个灯亮,其它的灯都灭。
然后再反过来,原来亮的就灭,原来灭的就亮。
交替闪烁。
(3)源代码讲解如下:
#include"REG52.H"
#defineconst_time_level200
voidinitial_myself();
voidinitial_peripheral();
voiddelay_short(unsignedintuiDelayShort);
voiddelay_long(unsignedintuiDelaylong);
voidled_flicker();
voidhc595_drive(unsignedcharucLedStatusTemp16_09,unsignedcharucLedStatusTemp08_01);
voidT0_time(); //定时中断函数
/*注释一:
*朱兆祺的学习板是用74HC595控制LED,因此可以直接把595的OE引脚接地。
如果在工控中,用来控制继电器,
*那么此芯片的片选脚OE不要为了省一个IO口而直接接地,否则会引起上电瞬间继电器莫名其妙地动作。
*为了解决这个问题,OE脚应该用一个IO口单独驱动,并且千万要记住,此IO必须接一个15K左右的
*上拉电阻,然后在程序刚上电运行时,先把OE置高,并且尽快把所有的74HC595输出口置低,然后再把OE置低.
*当然还有另外一种解决办法,就是用一个10uF的电解电容跟一个100K的下拉电阻,组成跟51单片机外围复位电路原理
*一样的电路,连接到OE口,这样确保上电瞬间OE口有一小段时间是处于高电平状态,在此期间,
*尽快通过软件把74hc595的所有输出口置低。
*/
sbithc595_sh_dr=P2^3;
sbithc595_st_dr=P2^4;
sbithc595_ds_dr=P2^5;
unsignedcharucLedStep=0;//步骤变量
unsignedint uiTimeCnt=0;//统计定时中断次数的延时计数器
voidmain()
{
initial_myself();
delay_long(100);
initial_peripheral();
while
(1)
{
led_flicker();
}
}
/*注释二:
*两个联级74HC595的工作过程:
*每个74HC595内部都有一个8位的寄存器,两个联级起来就有两个寄存器。
ST引脚就相当于一个刷新
*信号引脚,当ST引脚产生一个上升沿信号时,就会把寄存器的数值输出到74HC595的输出引脚并且锁存起来,
*DS是数据引脚,SH是把新数据送入寄存器的时钟信号。
也就是说,SH引脚负责把数据送入到寄存器里,ST引脚
*负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。
*/
voidhc595_drive(unsignedcharucLedStatusTemp16_09,unsignedcharucLedStatusTemp08_01)
{
unsignedchari;
unsignedcharucTempData;
hc595_sh_dr=0;
hc595_st_dr=0;
ucTempData=ucLedStatusTemp16_09; //先送高8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80)hc595_ds_dr=1;
elsehc595_ds_dr=0;
hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
delay_short(15);
hc595_sh_dr=1;
delay_short(15);
ucTempData=ucTempData<<1;
}
ucTempData=ucLedStatusTemp08_01; //再先送低8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80)hc595_ds_dr=1;
elsehc595_ds_dr=0;
hc595_sh_dr=0; //SH引脚的上升沿把数据送入寄存器
delay_short(15);
hc595_sh_dr=1;
delay_short(15);
ucTempData=ucTempData<<1;
}
hc595_st_dr=0; //ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来
delay_short(15);
hc595_st_dr=1;
delay_short(15);
hc595_sh_dr=0; //拉低,抗干扰就增强
hc595_st_dr=0;
hc595_ds_dr=0;
}
voidled_flicker()////第三区LED闪烁应用程序
{
switch(ucLedStep)
{
case0:
if(uiTimeCnt>=const_time_level)//时间到
{
uiTimeCnt=0;//时间计数器清零
hc595_drive(0x55,0x55);
ucLedStep=1;//切换到下一个步骤
}
break;
case1:
if(uiTimeCnt>=const_time_level)//时间到
{
uiTimeCnt=0;//时间计数器清零
hc595_drive(0xaa,0xaa);
ucLedStep=0;//返回到上一个步骤
}
break;
}
}
voidT0_time()interrupt1
{
TF0=0; //清除中断标志
TR0=0;//关中断
if(uiTimeCnt<0xffff) //设定这个条件,防止uiTimeCnt超范围。
{
uiTimeCnt++; //累加定时中断的次数,
}
TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
TL0=0x2f;
TR0=1; //开中断
}
voiddelay_short(unsignedintuiDelayShort)
{
unsignedinti;
for(i=0;i {
; //一个分号相当于执行一条空语句
}
}
voiddelay_long(unsignedintuiDelayLong)
{
unsignedinti;
unsignedintj;
for(i=0;i {
for(j=0;j<500;j++) //内嵌循环的空指令数量
{
;//一个分号相当于执行一条空语句
}
}
}
voidinitial_myself() //第一区初始化单片机
{
TMOD=0x01; //设置定时器0为工作方式1
TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
TL0=0x2f;
}
voidinitial_peripheral()//第二区初始化外围
{
EA=1; //开总中断
ET0=1; //允许定时中断
TR0=1; //启动定时中断
}
总结陈词:
这节讲了74HC595的驱动程序,它是一次控制16个LED同时亮灭的,在实际中应用不太方便,如果我们想要像单片机IO口直接控制LED那样方便,我们该怎么编写程序呢?
欲知详情,请听下回分解-----把74HC595驱动程序翻译成类似单片机IO口直接驱动的方式。
分享到: