<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 牛人業(yè)話(huà) > 奔跑吧,SOC(一)軟件是怎么控制硬件的

奔跑吧,SOC(一)軟件是怎么控制硬件的

作者: 時(shí)間:2015-08-31 來(lái)源:網(wǎng)絡(luò ) 收藏

  很多人肯定很疑惑,在嵌入式開(kāi)發(fā)中,為什么寫(xiě)c代碼,就能夠控制硬件。這一切是怎么發(fā)生的了,下面我就給大家解剖一下,軟件是怎么控制硬件的。

本文引用地址:http://dyxdggzs.com/article/279515.htm

  我們從控制8個(gè)led為例來(lái)說(shuō)明:

  從最簡(jiǎn)單的開(kāi)始,如果使用硬件,控制8個(gè)led,最簡(jiǎn)單的方式是什么:直接接上開(kāi)關(guān)。就是以下的圖。通過(guò)開(kāi)關(guān)控制led管腳輸出不同的電平,就能控制led了。但是這個(gè)方法很不靈活,我們要手動(dòng)的去撥動(dòng)開(kāi)關(guān),才能改變led狀態(tài)。

  

clip_image001

 

  我們將上面電路改一下,把開(kāi)關(guān)的地方換成,并加一些額外的電路,這樣就可以通過(guò)使能信號和信號值改變led值輸出不同電平,間接的控制led了。而使能信號和信號值我們是可以通過(guò)外部給的,就比開(kāi)關(guān)要靈活一些了。

  

clip_image003

 

  既然,上面有,我們可以給這個(gè)定義一個(gè)地址,當然這個(gè)地址目前是可以隨意定義的。假設為0x77777777。你可能會(huì )有疑問(wèn),為什么要給寄存器定義地址了?而且定義的地址為什么是32位了,這個(gè)先不著(zhù)急,聽(tīng)我慢慢道來(lái)。

  我們繼續在前面加電路

  

clip_image005

 

  這里,多了一個(gè)前級電路,前級電路提供兩個(gè)信號,一個(gè)地址,一個(gè)數據。在地址信號通路上,有一個(gè)電路模塊,判斷地址是不是0x77777777,是的話(huà),使能信號為1,這樣數據不就直接傳遞給寄存器了。不是的話(huà),使能信號為0。寄存器的輸出不變。這樣,通過(guò)地址和數據就能改變led了。

  這里0x77777777是不是很熟悉,這不就是之前定義的寄存器A的地址嗎?原來(lái),地址就是用來(lái)判斷是否產(chǎn)生使能信號的,使能才能使數據能夠輸入到寄存器中。

  到了這里,是不是對軟件控制硬件有些眉目了。別著(zhù)急,我們繼續往下走。

  既然前級電路只需要提供地址和數據,并且地址是0x77777777,就可以控制寄存器A的值了,而控制了寄存器A,就控制led。那么我們將前級電路換成一個(gè)32位CPU。

  我們知道,CPU是可以產(chǎn)生3種總線(xiàn)信號的,一種地址總線(xiàn),一種數據總線(xiàn),一種控制總線(xiàn)??刂瓶偩€(xiàn)我們這里用不到。將地址總線(xiàn)接到地址線(xiàn)上,將數據總線(xiàn)接到數據線(xiàn)上。就是以下的電路:

  

clip_image007

 

  如果我們讓CPU產(chǎn)生地址為0x77777777,然后發(fā)出想要寫(xiě)入寄存器A的數據B,那么數據B不就被寫(xiě)入到寄存器A中,這樣,不就控制led了。這里知道為什么地址要32位的把,因為CPU是32位的,地址就是32位寬的。之所以定義32位的地址,目的是為了和CPU的地址總線(xiàn)32位寬兼容。

  到這里,是不是有豁然開(kāi)朗的感覺(jué)了。我們再繼續。

  我們知道CPU是要取機器碼然后執行的。如果剛好某條機器碼,能讓地址總線(xiàn)上產(chǎn)生0x77777777,數據總線(xiàn)上產(chǎn)生數據B。那么結果,數據B不就被寫(xiě)入到寄存器A中了。假設CPU是32位risc的CPU,機器碼就是32位。那么該機器碼應該是如下:

  1001 0000 1110 0000 1011 1010 1111 0010(假設)

  既然這是一條機器碼,那么就應該有一個(gè)匯編指令與之對應,假設是

  str r0, r1

  我們預先將地址0x77777777寫(xiě)入到r0中,數據B寫(xiě)入到r1中,那么上面一條語(yǔ)句執行后,不就將數據B寫(xiě)入到寄存器A中了,不就控制led了。這樣不就實(shí)現了軟件控制了硬件了。既然匯編代碼可以控制硬件了,那么高級語(yǔ)言同樣也是控制硬件的,只要編譯后的匯編代碼是以上代碼就行了。

  整體控制硬件的代碼就是

  ldr r0, = 0x77777777

  ldr r1, =B

  str [r0], r1

  對應的C代碼就是

  (*(volatile unsigned long *)0x77777777) = B;

  使用指針操作,往0x77777777地址的寄存器寫(xiě)入數據B,加入volatile關(guān)鍵字,是防止編譯器對操作進(jìn)行優(yōu)化。

  通過(guò)上面的過(guò)程,是不是也可以理解,為什么在嵌入式底層驅動(dòng)開(kāi)發(fā)中,基本都是用C語(yǔ)言,而不用其他高級語(yǔ)言,比如JAVA等。因為這些高級語(yǔ)言沒(méi)有指針,你就不能控制寄存器,不能控制寄存器了,你當然就控制不了硬件了。C++也很少用,因為底層驅動(dòng)開(kāi)發(fā)需要高效率代碼,不能太復雜,而C++在這方面,比不過(guò)C語(yǔ)言。

  以上是寫(xiě)入的過(guò)程了,如果想要知道led的狀態(tài)呢?通過(guò)讀取寄存器A的值,不就知道led的狀態(tài)了。原理是一樣的。只不過(guò)數據線(xiàn)要變成兩根,一個(gè)是負責寫(xiě),一根負責讀。電路圖如下:

  

clip_image009

 

  因為只考慮了一個(gè)寄存器,當不選中寄存器A時(shí),讀取的數據為全0。

  通過(guò),上面的講述,對軟件控制硬件有沒(méi)有了解一些了。軟件控制硬件,本質(zhì)上,就是通過(guò)寫(xiě)代碼去修改或讀取硬件對應的寄存器的值。這樣,就相當于間接的控制了硬件。而硬件的寄存器對于一個(gè)處理器來(lái)說(shuō),都是固定的,都預先定義好了地址。所以在看ARM的數據手冊中,可以看到很多寄存器的地址。這些地址的作用,也就是能夠讓你在寫(xiě)程序的時(shí)候,能夠正確的往這些寄存器里面寫(xiě)入或讀取正確的值,從而控制硬件。

  CPU對外看到的都是寄存器,所以硬件設計的時(shí)候,就要對硬件的功能設置幾個(gè)寄存器,然后對這幾個(gè)寄存器分別定義幾個(gè)地址,這樣CPU才可以去控制這幾個(gè)寄存器,也就能控制硬件了。定義的寄存器地址位寬是和CPU的地址線(xiàn)位寬是有關(guān)系的,如果是一個(gè)8位的CPU,也就是經(jīng)典的C51,地址的寬度就是8位,所以你可以在頭文件reg51.c中看到使用sfr定義的地址位寬是8位。在STM32中,CPU是32位的,所以地址的寬度就是32位的,所以你看到STM32數據手冊中,寄存器的地址都是32位的,而且是4字節對齊的。

  以上,CPU只是控制了一個(gè)硬件,led,但是我們知道,CPU是可以控制很多硬件的,那這又是怎么實(shí)現的了?這個(gè)就得談?wù)勂匣ヂ?lián)總線(xiàn)了。

c++相關(guān)文章:c++教程




關(guān)鍵詞: SOC 寄存器

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>