筆者是在大一暑假接觸的單片機,現今已是大三狗了。在這一年半的時間里,我用過stm32、學過FPGA,從40腿的控制器件到140多腳的處理器件,從幾十行代碼到上百上千行代碼,也算是一種“步步高升”吧。然而對單片機的態度卻是從崇拜到鄙視再到敬重的轉換。也深深懂得了什么叫做“莫在浮沙筑高臺”。 記得起初,花了150多大洋買的單片機開發板,對單片機的頂列膜拜與對教科書的“萬馬奔騰”齊頭并進。對了,現價竟是78,靠!想當初,自己是多么單純——哇哦,這樣燈就亮了、額滴神,這就是流水燈啊、我勒個去,竟然還能和電腦交流,真讓人興奮。那種感覺就好像剛戀愛那樣,雖已存活二十余載仍就“孑然一身”,但覺得應該是這種感覺吧<(^-^)>。當然,讓人苦惱的莫過于看不懂的教科書,那都是些什么鬼,一個又一個搞不清的名詞,一段有一段不理解的句子,心中奔騰的馬必然是草泥馬。不過現在我明白了,人到達了一定的高度就會忽略當初的幼稚,然而如同《編碼的奧妙》這樣是個人都能看懂的書,也只有大師級的人才能夠完成。 記得去年暑假,在偶然的機會接觸了stm32F4,個頭雖比51小,但卻有144條腿(當時并沒有意識到這是貼片的)。而且還可以庫開發,真是簡直了,經過一個多月的學習,心中油然而生對51的鄙夷,那玩意簡直是low爆了。隨后又用到了FPGA,學會了用它來描述出自己想要的東西,哎呀,這才是我想要的嘛。對51 的鄙夷之情再次加深。我想我已經脫離低級轉向高端,可擺脫菜鳥身份了吧。而然,這一切的一切只能說明 到了大三,學了數電,開了一個名叫《單片機原理及其應用技術》的課程,開始接觸單片機的內部原理,ALU、ACC、PC、DPRT一系列名詞鋪面而來,JC、SUBB、INC、DEC一連串指令符迎頭痛擊,徹底擊敗了我那脆弱的自信心,只得對自己說一句 棍哥都說了海明威的“一個人可以被毀滅,但不能給打敗”。我豈能落后,我相信只要思想不滑坡,方法總比困難多。于是萌生了搞懂單片機的念頭,還提出了一個所謂的三步走戰略,即用C語言會使單片機,用匯編理解單片機,用verliog掌握單片機。 就我而言,初學時任何一個名詞都可能成為一個很大的障礙,對單片機內部結構的了解更簡直是噩夢。但是,對單片機的程序控制而言,程序的本質是寄存器之間的數據傳遞。用C語言我們可以學會用單片機,但對其內部結構不了解就難以掌握真正的掌握單片機。單片機不是憑空造出來的,用C語言,只是學習“單片機編程”。用匯編,才是學習“單片機”的正確姿勢,寫匯編其實就是幫你理清楚內在原理。當然了,如果只追求會用的話,的確不需要學匯編。然而學校開設單片機一課落腳于原理,在筆者看來懂其原理才能融會貫通,才能游刃于各種控制器件,才能不只是學了80C51單片機。可以說學單片機就是學微機原理,不懂微機原理即便再會寫程序,也只是代碼的搬運工。 Verilog是可編程邏輯語言,它的魅力就在于描繪出自己想要的邏輯器件,若是用它來造個單片機,雖然沒有什么實用價值,但對我們掌握單片機可以說是絕妙之筆。 故此,為了自己不再是菜鳥,為了不做代碼的搬運工,寫下層層深入單片機的系列筆記。
何為單片機?網上有云:“單片機是在一片硅片上集成了CPU、存儲器(RAM、ROM、EPROM)和各種I/O接口(定時器、計數器、并行I/O口等)具有一臺計算機功能的設備,又稱單板機、單片微型計算機、微控制器、嵌入式控制器”。我覺得這句話說得很好,不過在這里我更想說.
所以,先說一下單片機并記住一句話,單片機的引腳可以接收或發出高低電平。人家的原則貌似是“不求規模大,力求小而全”。n(*≧▽≦*)n
上圖是51單片機實物圖,右圖是引腳圖,引腳什么鬼?引腳,又叫管腳,英文叫Pin。就是從集成電路(芯片)內部電路引出與外圍電路的接線。即左圖白色的短小矩形,我們先要用意念控制住自己,不要想這黑塊內部是什么,只需要知道這些引腳可以接收或發出高低電平,接收的電平或可影響著輸出,輸出的也可左右著輸入,如要里二者的相互影響的奧秘,就是知道這個黑塊的原理。對于剛接觸單片機的在下來說,還是簡單的認識一下能看得見的東西吧。
引腳。20接負極,40接正極,這家伙是供電, 5V電壓最好。P1、P2口共16個,它們是一樣的,都是輸出或接收所謂的高低電平。P3腳比較勤勞,不僅有與P1、P2相同的功能,而且還兼職,也就是第二功能,這個先不說。P0口則有些先天不足,需要給它提供驅動力,才能與P1口一樣,這個驅動力叫做上拉電阻。當然,這樣的設計,是有人家的目的的,具體為什么,也先不說了吧。我們現在主要用的就是這些P口。
學習C語言Java什么的,第一件事是說“hello world”,那么,學習單片機首先要亮一個燈,我們初中就知道怎么亮了,拿一兩塊電池,把燈的一頭接在負極,一頭接在正極,他就亮了。就像這樣
現在我們要用單片機來點亮一個燈,先說這個燈,我們管它叫led,即是發光二極管(我記得當初并不知道led就是發光二極管(⊙﹏⊙))。
二極管想必都知道,具有單項導通性,如下圖
A接正極,B接負極,它是導通的,如果反過來就不管用了,當然,你可以暴力的擊穿它,讓它與世長辭。那么發光二極管呢?顧名思義,當A接正極,B接負極時,導通燈亮,反之不會亮。而在這里,我們又有了新的詞匯來形容正極和負極。這就是高電平和低電平。物理解釋中,正極指電源中電位(電勢)較高的一端,負極與之相對。高電平對應正極,負極與低電平相對應。我們說的“水平”,詞典中解釋與水平面平行、或在某方面達到一定高度,引申指事物在同等條件下的比較結論。
看這幅圖,水從高的地勢下泄,水從高水平面向低水平面溜達。現在再想想高電平和低電平也就了然了,電荷從高電平溜達到低電平,就是從正極流竄到負極。就是這個道理。在數字系統中,我們用1來表示表示高電平,用0來表示低電平,為什么呢?用0表示高電平當然也可以,不過,0比1大有沒有覺得很別扭,接下來就說說發光二極管,看下圖
A高電平,B低電平就亮了。那么這和單片機有什么關系呢?還記得開頭怎么說沒?單片機的引腳可以接收或發出高低電平。所以,當把A接的高電平用單片機來提供,B接到負極,燈就亮了,若將A外接高電平,B接單片機發出的低電平,燈也亮了。其實這倆種接法又稱共陽、共陰,這以后再談。那么如何讓單片機發出高低電平呢?這就需要軟件來實現。我用的是在keil3,軟件如何應用,就不贅述了~( ̄0 ̄)/。
我覺得不得不說一句,任何不看電路圖所寫的程序都是瞎扯淡,所以這里假設led連接在P1.1角上。
#include
要想知道這個頭文件干什么很簡單,選中頭文件,右鍵,選中open document #include就可以看到一些內容。
document 是文件的意思。include是包含,reg52.h是針對51/52單片機定義的頭文件,主要包括寄存器定義。所以也就大概理解了這個頭文件的意思了。SFR = special funtion register //特殊功能寄存器。舉例來說,如果你寫P0=0x01燒寫軟件會給0x80這個地址賦0x01,就是這樣,打起來了C語言與單片機的橋梁。如果學了匯編,相信會對這些內容很熟悉的。如果不太清楚我想也不必要糾結,寫程序的時候寫上這些也就可以了,以后會懂得。要知道,程序的本質是寄存器之間的數據傳遞。
#include
sbit led = P1^1;// 定義特殊功能寄存器的位變量。在函數中不允許對P0~P3 //口進行為位操作的,故使用前要先進行位定義。
main()
{
while(1)
{
led=1;
}
}
那為什么寫while(1)嘞?main是主程序, while(1)是無線循環的意思。學過C語言的知道,讓led=1;一直保持下去。為什么非要加while(1)來保持下去呢?引腳輸出1他不就亮了么?確實是這樣,可是我們先要清楚一點,單片機是順序執行,led=1;不是它的最后一句,如果不加while(1),led=1確實是最后一句啊,是的,對于C語言是這樣,但匯編不是這樣,對于單片機。并不是傳遞了led=1就停止工作了,這需要我們探索內部結構才能知曉,現在知道這樣一個概念吧。再補充一句,忘了加限流電阻了 。/(ㄒoㄒ)/~~
一節流水猶未盡,下節接著說廢話,學識淺薄出拙文,如察錯誤望賜教,小弟在此感涕零。
|