1. 51單片機概述
51單片機是對所有兼容Intel 8031指令系統的單片機的統稱。目前教科書基本都是以早期的MCS-51為原型,講解微機的原理及其接口技術的。早期的51單片機功能都較弱,需擴展rom,ram等才能組成一個較復雜的系統。而現今流行的8位51單片機都比早期芯片作了較多的功能擴展,性能強勁。生產51單片機的廠家有很多,像atmel的at80c51系列,華邦w78c051系列,宏晶stc80c51系列等,其中***宏晶stc系列51單片機在國內尤為流行。因此,筆者采用宏晶性價比較高的一款51單片機stc12c5a60s2來作開發講解。該款51單片機已經是宏昌第N代產品了,其主要特征如下:
1.1. 增強型8051 CPU,1T,單時鐘/機器周期,指令代碼完全兼容傳統8051;
1.2. 工作頻率范圍:0 - 35MHz,相當于普通8051的 0~420MHz;
1.3. 用戶應用程序空間60K字節,片上集成1280字節RAM;
1.4. 通用I/O口36個(以封裝PDIP40為例),可設置成準雙向口/弱上拉,推挽/強上拉,僅為輸入/高阻,開漏,每個I/O口驅動能力均可達到20mA,但整個芯片最大不要超過55Ma;
1.5. ISP(在系統可編程)/IAP(在應用可編程),無需專用編程器,無需專用仿真器 可通過串口(P3.0/P3.1)直接下載用戶程序。
1.6. 內部集成MAX810專用復位電路,2路PWM,8路高速10位A/D轉換(250K/S),EEPROM,看門狗,內部RC振蕩器,4個定時器,7路外部I/O口中斷等。
尤其需注意的是stc新一代的單片機都是1T單時鐘/機器周期,與課本介紹的早期51單片機是12T單周期是不一樣的,軟件實現延時時需作注意,其余擴充的特殊功能寄存器等請參考stc12c5a60s2的數據手冊。
2. 51單片機編程環境概述2.1. 代碼編譯工具
51單片機開發軟件基本無疑選用Keil C51集成開發環境。Keil C51是德國Keil Software公司(ARM公司收購了)出品的51系列兼容單片機C語言軟件開發系統,提供了包括C編譯器、宏匯編、連接器、庫管理和一個功能強大的仿真調試器等,目前最新版本已經到了uVision5。這里需要說明的是,Keil C51并不完全與ANSI C一樣,Keil C51由于面向的是51單片機,為了更好地詳述51的架構,Keil C51擴展了一些獨特的關鍵字,語法描述等。如用code說明為常量放在代碼區,data說明直接尋址區的變化,sfr聲明特殊功能寄存器等。
圖2.1-1
2.2. 代碼調試工具2.2.1. Keil自帶仿真調試器
Keil集成開發環境除了編譯鏈接工具外,還自帶了一個功能強大的仿真調試器。當然軟仿真是能夠看到Keil編譯后的匯編代碼,單步調試可以跟蹤各個寄存器的狀態變化,但是軟仿真是無法得到真實的外部輸入狀態的,如仿真真實開發板的按鍵輸入等。代碼調試時往往需要知道編譯器是否按照要求進行代碼的編譯處理,因此,可以讓編譯器輸出它是如何編譯,鏈接文件的,我們可以查看這些了解編譯器編譯c生成的匯編代碼,鏈接的符號,內存分配之類的信息。Keil在Target屬性中Listing列可進行設置,如C Compiler Listing選項中是c編譯器輸出選項,點上Assembly Code即輸出c編譯對應的匯編代碼,在文件.lst中。C Preprocessor Listing為c編譯器預處理輸出的信息,AssemblerListing為匯編器輸出的處理信息,LinkerListing為鏈接器輸出的處理信息(在.m51后綴文件中),這包括編譯器對內存的分配,各個函數符號等。通常編譯后的匯編代碼以及代碼的鏈接信息是可以跟蹤查看,以判斷代碼的問題所在。
2.2.2. Proteus仿真軟件
Proteus軟件是英國Lab Center Electronics公司出版的EDA工具軟件,它不僅具有其它EDA工具軟件的仿真功能,還能仿真單片機及外圍器件。Proteus具有電路仿真功能,能仿真一些最基本電子元器件,如led,數碼管,鍵盤等,并且是能仿真51單片機代碼運行的。在這里需要說明的是,請務必不能以仿真電路的效果圖與真實的硬件開發混攪,電路仿真軟件往往都是邏輯上的電路連接,完全不能夠用來說明真實硬件開發過程。此外,Proteus仿真51單片機也會有一些邏輯的問題,例如,在硬件上真實可運行的代碼在Proteus上無法仿真達到效果,修改一下代碼順序即可。總之,對于小代碼,Proteus都是可以勝任的,如果代碼太復雜,仿真任務會達到100%,無法再進行仿真了。因此,筆者推薦對于初學者,可先用Proteus進行仿真,進行一些最基本的練習,熟悉匯編語言,51單片機狀態變化,c語言等,驗證自己在51單片機架構學習中的一些理解,代碼實現的理解。學習到一定的程度還是需要一塊51開發板進行開發練習的,畢竟仿真軟件只能仿真很少部分的外圍,也不能仿真復雜的硬件及代碼。
圖2.2.2-1
2.3. 代碼燒錄工具
Keil C51編譯生成的hex文件通過STC_ISP工具,連接串口線(一般采用usb轉串口線)進行下載。代碼燒寫傳輸是通過51單片機的uart串口信號線Tx,Rx完成的,stc單片機實現isp下載是因為芯片內部有廠商的固化代碼,上電復位后是先執行固化代碼,檢測串口有無接收到特定的命令,如果有則進入下載模式,與上位機的isp下載軟件進行通信,從而把代碼下載進單片機rom區。如果沒有有效的串口下載命令,則跳轉執行真正的用戶代碼,即從0000H處開始執行代碼。
圖2.3-1
3. 匯編流水燈入門代碼
筆者認為學習51單片機并不是能通過別人的例子用c語言模仿寫出類似的功能即可,必須要對自己的編碼意圖比較清晰,這樣脫離任何例程都是可以自己掌控編寫代碼。因此學習51單片機其實更準確來說是學習微機的原理以及接口技術。而微機的原理以及接口技術對于51,arm或其它架構的mcu都是通用的,通過51來學習微機原理會涉及到匯編語言,因為只有匯編語言才能直接描述51內部的工作狀態。筆者以過來人的身份推薦初學者從51微機原理,匯編學起。C語言只是簡化封裝了匯編語言的一些處理過程,學完匯編,c語言也自然會達到相應的水平。此外,對于軟件出錯調試,只能跟蹤匯編代碼,查看寄存器的狀態判斷,而想學習arm,從事更深入的嵌入式開發,匯編是必不可少的。
3.1. 硬件原理圖
8個LED連接到P0口,當短接CON2后,只要P0口對應位為0(低電平),相應的LED則被點亮。此外說明一下為什么不用P0對應位為1時點亮而用0,因為傳統51單片機I/O口是弱上拉的,高電平是輸不出大電流的(相對低電平),高電平拉電流估計是ua級,但低電平灌電流幾個ma是不成問題的。對于stc系列51單片機,I/O口是可以配置成推挽輸出的,這樣高低電平都是可以達到20ma(手冊數據)的輸出/吸收電流。
圖3.1-1
3.2. 工程搭建
打開Keil C51,Project-》NewuVersion Project,保存項目后,選擇cpu為Atmel的AT89C52的51單片機,這里需要說明的是,Keil沒有stc系列的51單片機選擇,只要是51內核,在Keil下可選擇任一廠家,任一款51單片機進行代碼編寫,因為代碼都是兼容的。而不同廠商芯片之間的差異只是rom大小,ram大小,片內外設以及一些廠家特有的特殊功能寄存器的定義。這些都可以在工程中,代碼中重新定義,編譯器會老老實實按照要求編譯代碼。選擇了cpu后,會提示是否加入51的啟動代碼到工程中,由于我們編寫的是匯編語言,此處不需要,加入后啟動代碼會與我們自己的匯編代碼定義沖突。這里需要說明的是,啟動代碼是初始化c環境需要的文件,啟動代碼會設置c代碼運行時的堆棧,清零全局變量,靜態變量區等。這就是為什么我們在c文件中定義一個全局變量,默認這個變量的初始值為0(C標準)。
3.3. 代碼編寫
創建一個新文件,命名為LEDs.ASM,ASM為51匯編文件后綴,保存并加入工程。匯編的一些基本用法在代碼注釋中有說明,更多的匯編用法請google,百度。這里需要說明的是,51單片機第一條指令位置是在0H,后面相鄰的地址是分配給相應的中斷進入的,因此第一條指令往往會跳轉避開中斷向量地址區。以下代碼實現8個LED燈輪流點亮,點亮延時1s,這個匯編代碼是模仿c語言函數結構化編程的,里面可以類似認識到c編譯器大概是如何處理c函數并生成匯編的,當然編譯器匯編質量基本是無法達到人工匯編質量的。
ORG 0H ; 表示后面緊跟的那條指令的地址是 0000H
JMP Begin; 無條件跳轉到Begin處,以避免中斷向量地址
ORG 0BH ;000BH處為定時器T0的中斷處理入口
JMP T0_INT ; 未使用T0定時器中斷,只供代碼說明
T0_INT:
; 中斷發生時會自動把當前程序運行地址PC壓入棧sp
; 中斷處理完后用RETI中斷返回,從棧sp中出棧到PC返回打斷程序處
RETI
LED1 EQUP0.0 ; LED1由P0口第0位控制,以下類似
LED2 EQU P0.1
LED3 EQU P0.2
LED4 EQU P0.3
LED5 EQU P0.4
LED6 EQU P0.5
LED7 EQU P0.6
LED8 EQU P0.7
ORG 100H
Begin:
MOV P0, #0xff ;P0口輸出全1,所有LED滅
LOOP:
; R6,R7為調用函數的參數傳入,參數為16位,需2字節
; _Delay_ms對應c函數原型為void Delay_ms(intnCount)
; 共延時nCount * 1ms(12M普通8051),對于stc指令周期1T的
; 延時nCount * (1/6)ms (12M)
CLR LED1 ;直接位清0指令,清除P0口第0位,LED1亮
MOV R7, #(1000& 0xff) ; 參數為1000,普通8051延時1s
MOV R6, #((1000》》8) & 0xff) ; 16位變量
評論
查看更多