兩片聯級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時,大於幾十納秒就行了。我通常都選微秒級),更新顯示數據。
/OE(13腳):高電平時禁止輸出(高阻態)。如果單片機的引腳不緊張,用一個引腳控制它,可以方便地產生閃爍和熄滅效果。比通過數據端移位控制要省時省力。*/

/*8個LED燈交替閃爍*/
#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(); //定時中斷函數
sbit hc595_sh_dr=P3^6;  //上升沿數據寄存器移位,QA->QB;下降沿不變
sbit hc595_st_dr=P3^5;  //上升沿移位寄存器數據進入數據存儲寄存器,下降沿數據存儲寄存器不變。當移位完后,ST會產生正脈沖,更新顯示數據
sbit hc595_ds_dr=P3^4;  //串行數據輸入端,聯級的話接上一級Q7S
unsigned char ucLedStep=0; //步驟變量
unsigned int uiTimeCnt=0; //統計定時中斷次數的延時計數器
void main()
{
 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;
}
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;
 }
void T0_time() interrupt 1
{
 TF0=0; //清除中斷標志
 TR0=0; //關中斷
 if(uiTimeCnt<0xffff) //設定這個條件,防止uiTimeCnt超范圍
 {
  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; 
}
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM