/*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;
}