專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

51單片機學習之2-流水燈

作者:佚名   來源:本站原創(chuàng)   點擊數:  更新時間:2013年10月20日   【字體:

第五集

講解了74HC573 使用方法,我在《51單片機復習筆記1(更新)》有記錄。這里略。

講解了Keil 的仿真方法。比較有用的內容是可以用它來測試一段代碼所使用的時間,例如延時函數,在需要精確延時又不想使用定時器的時候可以使用該方法。至于其他的,個人認為還是直接下載到單片機中觀察實際情況會比較直觀。

 

第六集

51最小系統(tǒng)


 

 

復位原理:

51單片機是高電平脈沖復位,在RST引腳。復位脈沖的高電平寬度必須大于2個機器周期。為了方便計算,我們假設晶振頻率為12M,那么它的時鐘周期為1/12us(微秒)。它的一個機器周期是12*1/12=1us(微秒)。復位脈沖高電平寬度必須大于2個機器周期即2us,那么就要保證RST引腳高電平的時間大于2us單片機即可自動復位。

 

上電復位:

當通電時,開關是斷開的,那么電流從VCC→電容→RST、R32GND。剛上電的時候,電容開始充電,充滿電后相當于斷路,在電容充電到充滿的過程中電壓逐漸從高到低(從5V0V)。也就是說一上電,RST端得到就是高電平,當這個時間超過2us時單片機復位,電容快充滿到充滿后RST得到是低電平,電源不斷那么RST就一直是低電平而不會一直復位。RST高電平持續(xù)的時間取決于電容充電時間.。(這個電容要取多大?怎么計算的?)

 

手動復位:

通電之后,RST會自動復位一次,當單片機在運行的過程中我們需要它復位時可以斷電使之上電復位;蛘甙聪SW0開關也能實現復位。當SW0開關按下時電流從VCCR33RST、R32GND形成回路。為方便計算R33假設為300歐即0.3K,我們可以先計算R33得到的電壓是 5V* 0.3k/4.7k+0.3k))= 0.3V  R32得到的電壓為 5V*4.7k/4.7k+0.3k))=4.7V  RST端的電壓也為4.7V,那么4.7對于單片機來說也算高電平,當按下手動按下SW按鈕到松開肯定超過2us,所以單片機自動復位。

 

晶振電路:

兩個電容一定要相等,取值范圍為20-50pf 越大啟動越慢。

 

自己搭建最小系統(tǒng)要注意的地方:

EA引腳一定要接高電平即VCC,這是最容易忽略的。這個引腳是用來選擇是用片內存儲器還是用片外存儲器。51內部存儲器一般都夠我們使用。在以前的單片機需要外擴存儲器。我們燒錄的程序就是存在片內存儲器。

要將P0組引腳當普通IO用時,需要接10K的上拉電阻。P1-P3里面都有上啦電阻。

1  做地址/數據總線時和做輸入I/O口時,p0口不用接上拉電阻。
但當做輸出I/O口時,p0口必須要接上拉電阻才可以。

P0口是集電極開路輸出,也就是OC這種結構沒有輸出高電平的能力就相當于一個一端接地的開關,按下去就輸出低電平0V,斷開就沒有電壓,是懸空狀態(tài)。
至于用不用上拉電阻取決于外部電路,如果要輸出高電平控制一個器件,而這個器件本身又沒有內置上拉,就必須自己接一個上拉電阻,如果要用低電平控制一個器件,則可以不用加上拉。

 

第七集

一、流水燈的設計

流水燈就是讓八個小Led的依次亮滅。先看看流水燈的電路圖。

 

 

 

 

 



這是我的實驗板的流水燈電路圖。其中
74HC573D輸入引腳DB1DB8接在單片機的P1組引腳。74HC573LE接在P2.5引腳。

 

程序設計思路:

我實驗板上有8Led燈,正極接在VCC,負極接在單片機的P1引腳(這里不使用74HC573鎖存功能所以LE一直保存高電平,相當于Led直接接在單片機的IO口)。要讓Led燈亮只需要把對應的端口設為低電平,那么Led燈亮。依次讓P1的八個引腳給高低電平那么Led燈也會跟著暗亮。由于51單片機執(zhí)行的速度很快,所以Led燈的閃爍速度也會很快,我們肉眼無法看到,所以要在電平切換時適當的延時一下。

流水燈的程序設計有很多種方法,如按位置位、數組、函數_cror_()_crol()等,我本來我是比較喜歡用函數的方法,但后來看了一下AVR的,貌似用的最多的是 與、或、非、異或這些運算符來操控IO口,所以我就用這種方式吧,練熟一些方便以后學習。

 

#include "reg52.h"
 

#define uchar unsigned char

#define uint unsigned int
 

 

// 用來延時

void delay ( uchar x)  

{

    uint y;

    for (; x > 0 ; x--  )

    for( y=500 ;y>0;y--);

}
 

 

void main()

{

   uchar Tmp;

   uchar i;

   while(1)

   {

      Tmp=0xFE;          //在流之前先讓第一個燈亮 1111 1110 

      for(i=0; i<8; i++)

      {

         P1= Tmp;

         Tmp = Tmp<<1;     //左移動一位 0xFE=1111 1110 << 1 = 1111 1100

         Tmp = Tmp|0x01;   //將最后一位置1  1111 1100 | 0000 0001 = 1111 1101

         delay(100);       // 讓燈亮一段時間

      }

   }
 
}

關閉窗口

相關文章