两片联级74HC595驱动16个LED灯的基本驱动程序
/*74HC595使用方法
74HC595的数据端
QA--QH:八位并行输出端,可以直接控制8个输出位。
Q7S:级联输出端。将它接下一个595的DS端。
DS:串行数据输入端,级联的话接上一级的Q7S。
74HC595的控制端说明
/MR(10脚):低电平时将移位寄存器的数据清零。通常我将它接Vcc。
SH_CP(11脚):上升沿时数据寄存器的数据移位。Q0->Q1->Q2-->Q3-->...-->Q7;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。我通常都选微秒级)
ST_CP(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将ST_CP置为低电平,当移位结束后,在ST_CP端产生一个正脉冲(5V时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。
74HC595的数据端
QA--QH:八位并行输出端,可以直接控制8个输出位。
Q7S:级联输出端。将它接下一个595的DS端。
DS:串行数据输入端,级联的话接上一级的Q7S。
74HC595的控制端说明
/MR(10脚):低电平时将移位寄存器的数据清零。通常我将它接Vcc。
SH_CP(11脚):上升沿时数据寄存器的数据移位。Q0->Q1->Q2-->Q3-->...-->Q7;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。我通常都选微秒级)
ST_CP(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将ST_CP置为低电平,当移位结束后,在ST_CP端产生一个正脉冲(5V时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。
/OE(13脚):高电平时禁止输出(高阻态)。如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。*/
/*8个LED灯交替闪烁*/
#include "REG52.H"
#define const_time_level 200
#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_flicker();
void hc595_drive(unsigned char ucLedStatusTemp08_01);
void T0_time(); //定时中断函数
void initial_peripheral();
void delay_short(unsigned int uiDelayShort);
void delay_long(unsigned int uiDelayLong);
void led_flicker();
void hc595_drive(unsigned char ucLedStatusTemp08_01);
void T0_time(); //定时中断函数
sbit hc595_sh_dr=P3^6; //上升沿数据寄存器移位,QA->QB;下降沿不变
sbit hc595_st_dr=P3^5; //上升沿移位寄存器数据进入数据存储寄存器,下降沿数据存储寄存器不变。当移位完后,ST会产生正脉冲,更新显示数据
sbit hc595_ds_dr=P3^4; //串行数据输入端,联级的话接上一级Q7S
sbit hc595_st_dr=P3^5; //上升沿移位寄存器数据进入数据存储寄存器,下降沿数据存储寄存器不变。当移位完后,ST会产生正脉冲,更新显示数据
sbit hc595_ds_dr=P3^4; //串行数据输入端,联级的话接上一级Q7S
unsigned char ucLedStep=0; //步骤变量
unsigned int uiTimeCnt=0; //统计定时中断次数的延时计数器
unsigned int uiTimeCnt=0; //统计定时中断次数的延时计数器
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
led_flicker();
}
}
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
led_flicker();
}
}
void hc595_drive(unsigned char ucLedStatusTemp08_01) //1-8位
{
unsigned char i;
unsigned char ucTempData;
hc595_sh_dr=0;
hc595_st_dr=0;
ucTempData=ucLedStatusTemp08_01; //送8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80) //更新一次数据,移一次位
hc595_ds_dr=1; //串行数据输入,如果是多片联级的话,更新一次,输入一次数据。(我的单片机只用了一个74HC595芯片)
else
hc595_ds_dr=0;
hc595_sh_dr=0;
delay_short(15);
hc595_sh_dr=1; //SH引脚的上升沿把数据送入寄存器
delay_short(15);
ucTempData=ucTempData<<1; //左移一位
}
hc595_st_dr=0;
delay_short(15);
hc595_st_dr=1; //ST引脚负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。上升沿时更新显示数据。
delay_short(15);
hc595_sh_dr=0; //拉低,抗干扰就增强
hc595_st_dr=0;
hc595_ds_dr=0;
}
{
unsigned char i;
unsigned char ucTempData;
hc595_sh_dr=0;
hc595_st_dr=0;
ucTempData=ucLedStatusTemp08_01; //送8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80) //更新一次数据,移一次位
hc595_ds_dr=1; //串行数据输入,如果是多片联级的话,更新一次,输入一次数据。(我的单片机只用了一个74HC595芯片)
else
hc595_ds_dr=0;
hc595_sh_dr=0;
delay_short(15);
hc595_sh_dr=1; //SH引脚的上升沿把数据送入寄存器
delay_short(15);
ucTempData=ucTempData<<1; //左移一位
}
hc595_st_dr=0;
delay_short(15);
hc595_st_dr=1; //ST引脚负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。上升沿时更新显示数据。
delay_short(15);
hc595_sh_dr=0; //拉低,抗干扰就增强
hc595_st_dr=0;
hc595_ds_dr=0;
}
void led_flicker() // 第三区 LED闪烁应用程序
{
switch(ucLedStep)
{
case 0:
if(uiTimeCnt>const_time_level) //时间到
{
uiTimeCnt=0;
hc595_drive(0x55); // 0101 0101
ucLedStep=1; //切换到下一步骤
}
break;
case 1:
if(uiTimeCnt>const_time_level)
{
uiTimeCnt=0;
hc595_drive(0xaa); // 1010 1010
ucLedStep=0; //返回到上一步骤
}
break;
}
}
{
switch(ucLedStep)
{
case 0:
if(uiTimeCnt>const_time_level) //时间到
{
uiTimeCnt=0;
hc595_drive(0x55); // 0101 0101
ucLedStep=1; //切换到下一步骤
}
break;
case 1:
if(uiTimeCnt>const_time_level)
{
uiTimeCnt=0;
hc595_drive(0xaa); // 1010 1010
ucLedStep=0; //返回到上一步骤
}
break;
}
}
void T0_time() interrupt 1
{
TF0=0; //清除中断标志
TR0=0; //关中断
{
TF0=0; //清除中断标志
TR0=0; //关中断
if(uiTimeCnt<0xffff) //设定这个条件,防止uiTimeCnt超范围
{
uiTimeCnt++; //累加定时中断的次数
}
TH0=0xf8;
TL0=0x2f;
TR0=1; //开中断
}
{
uiTimeCnt++; //累加定时中断的次数
}
TH0=0xf8;
TL0=0x2f;
TR0=1; //开中断
}
void delay_short(unsigned int uiDelayShort)
{
unsigned int i;
for(i=0;i<uiDelayShort;i++)
;
}
{
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++)
;
}
{
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;
}
{
TMOD=0x01;
TH0=0xf8;
TL0=0x2f;
}
void initial_peripheral()
{
EA=1;
ET0=1;
TR0=1;
}
{
EA=1;
ET0=1;
TR0=1;
}