2017.11.18 手把手教你學51單片機-點亮LED

来源:http://www.cnblogs.com/wongsh/archive/2017/11/18/7858098.html
-Advertisement-
Play Games

In Doing We Learning 在操作中學習。如果只是光看教程,沒有實際的操作,對編程語言的理解很空泛,所以決定從單片機中學習C語言。 #include<reg52.h> //包含的頭文件。 sbit LED = P0^0; //這裡就是對P0寄存器進行位操作。相當於對P0^0位賦予了一個 ...


In Doing We Learning

在操作中學習。如果只是光看教程,沒有實際的操作,對編程語言的理解很空泛,所以決定從單片機中學習C語言。

 

#include<reg52.h>                 //包含的頭文件。

sbit LED = P0^0;                         //這裡就是對P0寄存器進行位操作。相當於對P0^0位賦予了一個新的名字,LED。實際上這一塊可以包含在頭文件中。避免重覆操作。
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

void main()
{
 ENLED = 0;
 ADDR3 = 1;
 ADDR2 = 1;
 ADDR1 = 1;
 ADDR0 = 0;

 LED = 0;
 while(1);
}

 

以上程式能夠在KingST的C52單片機學習板上點亮一個LED小燈。

附上單片機原理圖

 

 

 

 

 

 

 

 

#include <reg52.h>

表示包含了C52單片機的特殊功能寄存器,和位的定義。

51單片機頭文件reg51.h詳解 

我們在用c語言編程時往往第一行就是頭文件,51單片機為reg51.h或reg52.h,51單片機相對來說比較簡單,頭文件裡面內容不多,像飛思卡爾、ARM系列的單片機頭文件往往內容就非常多,儘管如此,對一些初次接觸單片機的朋友來說,51的頭文件還是搞不太清楚,今天具體來說明一下。
1)“文件包含”處理概念

所謂“文件包含”是指在一個文件內將另外一個文件的內容全部包含進來。因為被包含的文件中的一些定義和命令使用的頻率很高,幾乎每個程式中都可能要用到,為了提高編程效率,減少編程人員的重得勞動,將這些定義和命令單獨組成一個文件,如reg51.h,然後用#include<reg51.h>包含進來就可以了,這個就相當於工業上的標準零件,拿來直接用就可以了。

 2寄存器地址及位地址聲明的原因 
 reg51.h裡面主要是一些特殊功能寄存器的地址聲明,對可以位定址的,還包括一些位地址的聲明,如果如sfr P1=0x80; sfr IE=0xA8;sbit EA=0xAF等。

sfr P1 = 0x90這句話表示:P1口所對應的特殊功能寄存器P1在記憶體中的地址為0x80,sbit EA=0xAF這句話表示EA這一位的地址為0xAF。
        註意這裡出現了一個使用很頻繁的sfr和sbit。

sfr 表示特殊功能寄存器的意思,它並非標準C 語言的關鍵字,而是Keil 為能直接訪問80C51中的特殊功能寄存器 而提供了一個新的關鍵詞,其用法是:sfr  特殊功能寄存器名=地址值(註意對於頭文件里“特殊功能寄存器名”,用戶實際上也可以修改的,如P1=0x80,也可改為A1=0x80,但sfr  和地址值則不能更改,否者會編譯出錯。)
   sbit 表示位的意思,它也是非標準C 語言的關鍵字,編寫程式時如需操作寄存器的某一位(可位定址的寄存器才能用)時,需定義一個位變數,此時就要要到sbit,如sbit deng=P1^0,sbit EA   = 0xAF;需要註意的是,位定義時有些特殊, 用法有三種:

第一種方法:sbit 位變數名=寄存器位地址值

第二種方法:sbit 位變數名=SFR 名稱^寄存器位值(0-7)

第三種方法:sbit 位變數名=SFR 地址值^寄存器位值

如:

sbit IT0=0x88 (1)說明:0x88是IT0 的位地址值

sbit  deng=P1^2 (2)說明:其中P1 必須先用sfr 定義好

sbit EA=0xA8^7 (3)說明:0xA8 就是IE寄存器的地址值
    以上三種定義方法需註意的是 IT0 deng EA可由用戶隨便定義,但必須滿足C語言對變數名的定義規則。除些外其它的則必須按照上面的格式寫,如“名稱^變數位地址值中“^”,它是由keil軟體的規定的 ,不能寫成其它的,只能這樣能才編譯通過。
    以上是對寄存器地址和位地址的定義和聲明作瞭解釋,大家需要牢牢記住:只有對寄存器及相關位進行聲明地址後,我們才能對其進行賦相關的值,keil軟體才能編譯通過。至於說為什麼,這可能一句話兩句話也說不清楚。
      3記憶體、SFR、位、地址等的通俗解釋 

前面講到了寄存器地址和位地址(前提能位定址)聲明的目的是為告訴C編譯器相應寄存器及其位在記憶體中的地址,這樣我們對寄存器及一些位賦的變數和數值才能正確保存,然後才能供CPU正確的調用,完成相應的功能。
    上段文字出現了寄存器(SFR)、位,地址、記憶體等,單片機學習過程中還會出現ROM、RAM等名詞,可能大家覺得不是很好理解,這裡可以通俗的解釋一下,如下麵三個圖所示。
    我們把記憶體比作賓館,ROM、RAM、SFR相當於賓館里具體的有三種不同功能樓層(具體這個賓館多少層即多少ROM、RAM、SFR,視各個賓館或者每種單片機而不同),每層8個房間相當於8位,每個房間要麼住男人要麼住女人相當於每位要麼放入數字1要麼放入數字0,keil編譯器就相當於賓館的工作人員,旅客去住旅館相當寫程式的過程,住賓館的人必須事先要給工作人員說你是哪一層哪一個房間(即聲明寄存器地址和位地址,)賓館工作人員才能把你帶到你的房間里去(這裡假設這個賓館可以由旅客自己決定住哪個房間)。即:只有對寄存器及相關位進行聲明地址後,我們才能對其進行賦相關的值,keil軟體才能編譯通過。

4)REG51.H頭文件原文及解釋
   打開reg51.h 可以看到這樣的一些內容(此文件一般在C:\KEIL\C51\INC下 ,INC文件夾根目錄里有不少頭文件,並且裡面還有很多以公司分類的文件夾,裡面也都是相關產品的頭文件。如果我們要使用自己寫的頭文件,使用的時候只需把對應頭文件拷貝到INC文件夾里就可以了。)
    下麵附出頭文件的原文,並把註釋文件一併附後。 


/*--------------------------------------------------------------------------

 

REG51.H

 

Header file for generic 80C51 and 80C31 microcontroller.

Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.

All rights reserved. 

--------------------------------------------------------------------------*/

 

#ifndef __REG51_H__

#define __REG51_H__

 

/*  BYTE Register  */

        

 sfr P0   = 0x80;   //三態雙向     IO      P0口 此句話的意思是:特殊功能寄存器 P0 地址為0x80 ,可位定址,下同

                          //8位地址匯流排/數據匯流排(一般不用而只作普通I/O口,註意作I/O口用時,硬體上需接上接電阻)

sfr P1   = 0x90;   //準雙向       IO      P1

 


sfr P2   = 0xA0;   //
準雙向  IO      P2

                          //8位地址匯流排,一般也作普通I/O用

sfr P3   = 0xB0;   //雙功能

                          //1.準雙向      IO      P3

                        //2.  P30              RXD串列數據接受

                       //    P31              TXD串列數據發送

                          //     P32              外部中斷0     信號申請

                         //     P33              外部中斷1     信號申請

                            //     P34              定時/計數器T0     外部計數脈衝輸入

                            //     P35              定時/計數器T1     外部計數脈衝輸入

                            //     P36              WR  片外RAM寫脈衝信號輸入

                            //     P37           RD  片外ram讀脈衝信號輸入

sfr PSW  = 0xD0; // 可以位定址(C語言編程時可不考慮此寄存器)

                            //程式狀態寄存器Program Status WORD  (程式狀態信息)

                            //psw.7(CY)    進位標誌

                            //psw.6(AC)輔助進位標誌位低四位向高四位進位或借位時   AC=1

                            //主要用於十進位調整

                            //psw.5(F0)用戶可自定義的程式標誌位

                           //psw.4(RS1)

                            //psw.3(RS0)

                            //工作寄存器選擇位

                            //任一時刻只有一組寄存器在工作

                            //0 0  0     00H~07H

                            //0 1   1     08H~0fH

                            //1 0   2     10H~17H

                            //1 1   3     18H~1FH

                            //psw.2(OV)    溢出標誌位

                            //psw.1(   )      保留為 ,不可使用

                            //psw.0(P)              奇偶校驗位

 

sfr ACC  = 0xE0;     //累加器A     特殊功能寄存器    可位定址

sfr B    = 0xF0;        //寄存器B      主要用於乘除運算

sfr SP   = 0x81;       //堆棧指針寄存器SP    存放站定棧頂地址、

sfr DPL  = 0x82;      //

sfr DPH  = 0x83;     //數據指針寄存器DPTR、//對片外RAM及擴展IO進行存取用的地址指針

 

sfr PCON = 0x87; //電源控制寄存器  、不能位定址             

                           //管理單片機的電源部分包括上電覆位、掉電模式、空閑模式等

                           //單片機複位時PCON被全部清0,編程時一般是用到SMOD位,其它的一般不用

                          //D7 SMOD該位與串口通信波特率有關

                          //SMOD=0     串口方式1 2 3 波特率正常

                          //SMOD=1     串口方式1 2 3 波特率加倍

              

 

 

 

sfr TCON = 0x88;  //定時器/計數器    控制寄存器   可以位定址                                                           
         //D7  TF1        
定時器1溢出標誌位

                            //D6       TR1      定時器1運行控制位

                            //D5       TF0        定時器0溢出標誌位

                            //D4     TR0        定時器0運行控制位

                            //D3       IE1         外部中斷1請求標誌

                            //D2       IT1         外部中斷觸發方式選擇位

                            //D1       IE0       外部中斷0請求標誌

                            //D0     IT0         外部中斷觸發方式選擇位

 

 

sfr TMOD = 0x89; //定時器/計數器    工作方式寄存器    不能位定址

                            //確定工作方式和功能                                                  

                            //D7 GATE     門控制位

                            //GATE=0;定時器/計數器由TRXx=01)來控制

                            //GATE=1;定時器/計數器由TRXx=01

                            //和外部中斷引腳(init01)來共同控制

                            //D6  C/T      定時器、計數器選擇位

                            //     0    選擇定時器模式

                            //     1     選擇計數器模式

                            //D5       M1        

                            //D4       M0

                            //M1       M0         工作方式

                            //0   0            方式0     13位定時器/計數器

                            //0   1          方式1     16位定時器/計數器

                            //1   0          方式2     8位自動重裝定時器/計數器

                            //1   1          方式3     僅適用T0      分成兩個8位計數器,T1停止計數

                            //D3 GATE     門控制位

                            //GATE=0;定時器/計數器由TRXx=01)來控制

                            //GATE=1;定時器/計數器由TRXx=01

                            //和外部中斷引腳(init01)來共同控制

                            //D2  C/T             定時器、計數器選擇位

                            //0  選擇定時器模式

                            //1   選擇計數器模式

                            //D1       M1        

                            //D0       M0

                            //     M1 M0         工作方式

                            //     0     0     方式0     13位定時器/計數器

                            //     0     1     方式1   16位定時器/計數器

                            //     1     0     方式2   8位自動重裝定時器/計數器

                            //     1     1     方式3   僅適用T0      分成兩個8位計數器,T1停止計數

 

sfr TL0  = 0x8A;    //定時器/計數器08     容器   計數器

sfr TL1  = 0x8B;    //定時器/計數器18     容器

sfr TH0  = 0x8C;    //定時器/計數器08     容器

sfr TH1  = 0x8D;    //定時器/計數器18     容器

 

 

 

sfr IE   = 0xA8;                 //中斷允許寄存器          可以位定址

                                          //D7  EA         全局中斷允許位

                                          //D6       NULL

                                          //D5       ET2        定時器/計數器2中斷允許位     interrupt 5

 

                                          //D4  ES          串列口中斷允許位        interrupt 4

 

                                          //D3  ET1        定時器/計數器1中斷允許位     interrupt 3

 

                                          //D2  EX1        外部中斷1中斷允許位      interrupt 2

 

                                           //D1  ET0        定時器/計數器0中斷允許位  interrupt 1

 

                                           //D0  EX0        外部中斷0中斷允許位     interrupt 0

  

sfr IP   = 0xB8;        //中斷優先順序寄存器   可進行位定址

                             //D7 NULL

                                //D6 NULL

                                 //D5       NULL

                                                 //D4       PS          串列口中斷定義優先順序控制位

                                                 //            1            串列口中斷定義為高優先順序中斷

                                                 //            0            串列口中斷定義為低優先順序中斷

                                                 //         

                                                 //D3       PT1       

                                                 //            1     定時器/計數器1中斷定義為高優先順序中斷

                                                 //            0     定時器/計數器1中斷定義為低優先順序中斷

                                                 //D2 PX1

                                                 //            1            外部中斷1定義為高優先順序中斷

                                                 //            0          外部中斷1定義為低優先順序中斷

                                                 //D1       PT0       

                                                 //            1     定時器/計數器0中斷定義為高優先順序中斷

                                                 //            0     定時器/計數器0中斷定義為低優先順序中斷

                                                 //D0 PX0

                                                 //            1            外部中斷0定義為高優先順序中斷

                                                 //            0          外部中斷0定義為低優先順序中斷

 

 

 

sfr SCON = 0x98;   //串列口控制寄存器     可以進行位定址          

                              //D7   SM0             

                               //D6       SM1

                               //     SM0      SM1              串列口工作方式

                               //     0           0            同步移位寄存器方式

                             //     0         1            10位非同步收發(8位數據),波特率可變(定時器1溢出率控制)

                               //   1         0            11位非同步收發(9位數據),波特率固定

                               //     1         1            11非同步收發(9位數據)  ,波特率可變(定時器1溢出率控制)

                               //D5       SM2            多機通信控制位    主要用於方式2和方式3

                               //D4       REN            允許串列接收位

 

                               //D3       TB8        方式23中發送數據的第9

                               //D2       RB8      方式23中接受數據的第9

 

                               //D1       TI           發送中斷標誌位

                              //D0       RI         接受中斷標誌位

 

 

sfr SBUF = 0x99;    //串列數據緩衝區

 

/*****************************************************************************

                                                        下麵是位定址區

                                          上面做過解釋的就不在下麵一一解釋了

******************************************************************************/

/*  BIT Register  */    

/*  PSW   */

sbit CY   = 0xD7;

sbit AC   = 0xD6;

sbit F0   = 0xD5;

sbit RS1  = 0xD4;

sbit RS0  = 0xD3;

sbit OV   = 0xD2;

sbit P    = 0xD0;

 

/*  TCON  */

sbit TF1  = 0x8F;

sbit TR1  = 0x8E;

sbit TF0  = 0x8D;

sbit TR0  = 0x8C;

sbit IE1  = 0x8B;

sbit IT1  = 0x8A;

sbit IE0  = 0x89;

sbit IT0  = 0x88;

 

/*  IE   */

sbit EA   = 0xAF;

sbit ES   = 0xAC;

sbit ET1  = 0xAB;

sbit EX1  = 0xAA;

sbit ET0  = 0xA9;

sbit EX0  = 0xA8;

 

/*  IP   */

sbit PS   = 0xBC;

sbit PT1  = 0xBB;

sbit PX1  = 0xBA;

sbit PT0  = 0xB9;

sbit PX0  = 0xB8;

 

/*  P3  */

sbit RD   = 0xB7;

sbit WR   = 0xB6;

sbit T1   = 0xB5;

sbit T0   = 0xB4;

sbit INT1 = 0xB3;

sbit INT0 = 0xB2;

sbit TXD  = 0xB1;

sbit RXD  = 0xB0;

 

/*  SCON  */

sbit SM0  = 0x9F;

sbit SM1  = 0x9E;

sbit SM2  = 0x9D;

sbit REN  = 0x9C;

sbit TB8  = 0x9B;

sbit RB8  = 0x9A;

sbit TI   = 0x99;

sbit RI   = 0x98;

 

#endif


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 連接池中的參數介紹: name:表示你的連接池的名稱也就是你要訪問連接池的地址 auth:是連接池管理權屬性,Container表示容器管理 type:是對象的類型 driverClassName:是資料庫驅動的名稱 url:是資料庫的地址 username:是登陸資料庫的用戶名 password: ...
  • 1、收集統計信息vacuum full analyze ZCXT.ZCOT_PS_PROJECT; 2、檢查表的數據量分佈select gp_segment_id,count(*) from fact_table group by gp_segment_id; 3、表結構上建議創建表的時候,分佈鍵放 ...
  • 開發一個項目時都會有一個蛋疼的問題——寫資料庫需求文檔,然後根據這個文檔來建資料庫,如果後來需求改了,要改資料庫還要改文檔,有時忙著忙著就忘改了,導致文檔是過期的。那麼我們自己寫個腳本在資料庫運行直接生產數據字典,這樣只要改資料庫就行了。目前在網上搜了下,發現sqlServer只有2005的生成工具 ...
  • 0. properties ####################################mysql########################################### db.mysql.driverClassName=com.mysql.jdbc.Driver db.m ...
  • CK21190-Mycat分散式架構之Mycat分散式架構實戰解析 Mycat是國內第一個賣電子書的開源軟體,參與的作者們平生第一次分到了一筆開源收入的酬勞,雖然微不足道,但那一刻,他們都堅信,Mycat會越來越好。如今,Mycat的穩定參與者人數已經超過10人,包括很多美女,而第三代新生志願者團隊 ...
  • 我們在(人工智慧搶80萬工人的飯碗,卻增加了350萬個新崗位?!)文章中概述了人工智慧帶來的便利之處,那麼越來越多的人對人工智慧趨之若鶩,那人工智慧的就業崗位如何呢?薪資待遇如何呢?又有哪些實力強大的AI公司呢? 最課程為大家分析各個招聘網站,python在智聯招聘上薪資待遇4k-50k不等;拉勾網 ...
  • cobbler-自動安裝系統 1.1 cobber簡介 1.1.1 cobbler說明 1.2 服務端部署 1.2.1 系統環境 系統:CentOS 7.4 ip: 外網:10.0.0.202 內網:172.16.1.202 1.2.2 安裝依賴包 1.2.3 修改配置文件 #備份、修改cobble ...
  • Windows常用的分區格式有三種,分別是FAT16、FAT32、NTFS格式。 在Linux操作系統里有Ext2、Ext3、Linux swap和VFAT四種格式。 FAT16: 作為一種文件名稱,FAT(File Allocation Table,文件分配表)自1981年問世以來,已經成為一個計 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...