最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

8.1第1個ARM裸板程序及引申(上)

2020-08-15 13:43 作者:韋東山  | 我要投稿

第001節(jié)_輔線1_硬件知識_LED原理圖

當(dāng)我們學(xué)習(xí)C語言的時候,我們會寫個Hello程序。那當(dāng)我們寫ARM程序,也該有一個簡單的程序引領(lǐng)我們?nèi)腴T,這個程序就是點亮LED。

我們怎樣去點亮一個LED呢? 分為三步:

  1. 看原理圖,確定控制LED的引腳;

  2. 看主芯片的芯片手冊,確定如何設(shè)置控制這個引腳;

  3. 寫程序;

先來講講怎么看原理圖: LED樣子有很多種,像插腳的,貼片的。

Chapter8 lesson1 001.jpg

它們長得完全不一樣,因此我們在原理圖中將它抽象出來。

點亮LED需要通電源,同時為了保護(hù)LED,加個電阻減小電流。 控制LED燈的亮滅,可以手動開關(guān)LED,但在電子系統(tǒng)中,不可能讓人來控制開關(guān),通過編程,利用芯片的引腳去控制開關(guān)。

Chapter8 lesson1 002.jpg

LED的驅(qū)動方式,常見的有四種。

  • 方式1:使用引腳輸出3.3V點亮LED,輸出0V熄滅LED。

  • 方式2:使用引腳拉低到0V點亮LED,輸出3.3V熄滅LED。

有的芯片為了省電等原因,其引腳驅(qū)動能力不足,這時可以使用三極管驅(qū)動。

  • 方式3:使用引腳輸出1.2V點亮LED,輸出0V熄滅LED。

  • 方式4:使用引腳輸出0V點亮LED,輸出1.2V熄滅LED。


由此,主芯片引腳輸出高電平/低電平,即可改變LED狀態(tài),而無需關(guān)注GPIO引腳輸出的是3.3V還是1.2V。 所以簡稱輸出1或0:

  • 邏輯1-->高電平

  • 邏輯0-->低電平

第002節(jié)_輔線1_硬件知識_S3C2440啟動流程與GPIO操作

在原理圖中,同名的Net表示是連在一起的。


怎么樣GPF4怎么輸出1或0?

1. 配置為輸出引腳;

2. 設(shè)置狀態(tài);


因此,設(shè)置GPFCON[9:8]=0b01,即GPF4配置為輸出;

設(shè)置GPFDAT[4]=1或者0,即輸出高電平或低電平;?


S3C2440框架:

Chapter8 lesson2 001.png


S3C2440啟動流程:

  • Nor啟動:

Nor Flash的基地址為0,片內(nèi)RAM地址為0x4000 0000;

CPU讀出Nor上第1個指令(前4字節(jié)),執(zhí)行;

CPU繼續(xù)讀出其它指令執(zhí)行。

  • Nand啟動:

片內(nèi)4k RAM基地址為0,Nor Flash不可訪問;

2440硬件把Nand前4K內(nèi)容復(fù)制到片內(nèi)的RAM,然后CPU從0地址取出第1條指令執(zhí)行。?


第003節(jié)_編寫第1個程序點亮LED

在開始寫第1個程序前,先了解一些概念。

2440是一個SOC,它里面的CPU有R1、R2、R3……等 寄存器;

它里面的GPIO控制器也有很多寄存器,如 GPFCON、GPFDAT。

這兩個寄存器是有差異的,在寫代碼的時候,CPU里面的寄存器可以直接訪問,其它的寄存器要以地址進(jìn)行訪問。


把GPF4配置為輸出,需要把0x100寫入GPFCON這個寄存器,即寫到0x5600 0050上;

把GPF4輸出1,需要把0x10寫到地址0x5600 0054上;

把GPF4輸出0,需要把0x00寫到地址0x5600 0054上;

這里的寫法會破壞寄存器的其它位,其它位是控制其它引腳的,為了讓第一個裸板程序盡可能的簡單,才簡單粗暴的這樣處理。


寫程序需要用到幾條匯編代碼:

①LDR ?(load):讀寄存器

舉例:LDR R0,[R1]

假設(shè)R1的值是x,讀取地址x上的數(shù)據(jù)(4字節(jié)),保存到R0中;


②STR ?(store):寫寄存器

舉例:STR R0,[R1]

假設(shè)R1的值是x,把R0的值寫到地址x(4字節(jié));


③B ?跳轉(zhuǎn)


④MOV ?(move)移動,賦值 舉例1:MOV R0,R1把R1的值賦值給R0;

舉例2:MOV R0,#0x100 把0x100賦值給R0,即R0=0x100;


⑤LDR

舉例:LDR R0,=0x12345678這是一條偽指令,即實際中并不存在這個指令,他會被拆分成幾個真正的ARM指令,實現(xiàn)一樣的效果。 最后結(jié)果是R0=0x12345678。


為什么會引入偽指令?
在ARM的32位指令中,有些字節(jié)表示指令,有些字節(jié)表示數(shù)據(jù),因此表示數(shù)據(jù)的沒有32位,不能表示一個32位的任意值,只能表示一個較小的簡單值,這個簡單值稱為立即數(shù)。引入偽指令后,利用LDR可以為R0賦任意大小值,編譯器會自動拆分成真正的的指令,實現(xiàn)目的。

有了前面5個匯編指令的基礎(chǔ),我們就可以寫代碼了。

第一個程序只能是匯編,以前你們可能寫過單片機(jī)程序,一上來就寫main()函數(shù),那是編譯器幫你封裝好了。


第一個LED程序代碼如下:?


將代碼上傳到服務(wù)器, 先編譯:?

再鏈接:?

生成bin文件:?

以上的命令,要是我們每次都輸入會容易輸錯,因此我們把他們寫到一個文件里,這個文件就叫Makefile. 關(guān)于Makefile以后會講。本次所需的Makefile如下:?

以后只需要 使用 make 命令進(jìn)行編譯, make clean 命令進(jìn)行清理。

最后燒寫到開發(fā)板上,即可看到只有一個LED亮,符合我們預(yù)期。


第004節(jié)_匯編與機(jī)器碼

前面介紹過偽指令,偽指令是實際不存在的ARM命令,編譯器在編譯時轉(zhuǎn)換成存在的ARM指令。我們代碼中的ldr r1, =0x56000050這條偽指令的真實指令時什么呢?

我們可以通過反匯編來查看。


在前面的Makefile中加上:?

上傳服務(wù)器,編譯。

生成的led_on.dis就是反匯編文件。led_on.dis如下:?

第一列是地址,第二列是機(jī)器碼,第三列是匯編;

在反匯編文件里可以看到,ldr r1, =0x56000050被轉(zhuǎn)換成ldr r1, [pc, #20],pc+20地址的值為0x56000050,通過這種方式為r1賦值。 對于立即數(shù)0x100而言,ldr r0,=0x100即是轉(zhuǎn)換成了mov r0,#256;

在2440這個SOC里面,R0-R15都在CPU里面,其中:

為什么 PC=當(dāng)前指令+8?

ARM指令采用流水線機(jī)制,當(dāng)前執(zhí)行地址A的指令,已經(jīng)在對地址A+4的指令進(jìn)行譯碼,已經(jīng)在讀取地址A+8的指令,其中A+8就是PC的值。


C/匯編(給人類方便使用的語言)———編譯器———>bin,含有機(jī)器碼(給CPU使用)?


第005節(jié)_編程知識_進(jìn)制

17個蘋果,有4種表示方式,它們表示同一個數(shù)值:


計算驗證:

十進(jìn)制:17=1x10^1 + 7x10^0;?

二進(jìn)制:17=1x2^4 + 0x2^3 + 0x2^2 + 0x2^1 + 1x2^0;?

八進(jìn)制:17=2x8^1 + 1x8^0;?

十六進(jìn)制:17=1x16^1 + 1x16^0;


為何引入二進(jìn)制?

在硬件角度看,晶體管只有兩個狀態(tài):on是1,off是0; 數(shù)據(jù)使用多個晶體管進(jìn)行表示,用二進(jìn)制描述,吻合硬件狀態(tài)。?


為何引入八進(jìn)制?

將二進(jìn)制的三位作為一組,把這一組作為一位進(jìn)行表示,就是八進(jìn)制。?


為何引入十六進(jìn)制?

將二進(jìn)制的四位作為一組,把這一組作為一位進(jìn)行表示,就是十六進(jìn)制。八進(jìn)制和十六進(jìn)制方便我們描述,簡化了長度。


如何快速的轉(zhuǎn)換2/8/16進(jìn)制: 首先記住8 4 2 1 ——>二進(jìn)制權(quán)重?


舉例1:

將二進(jìn)制0b01101110101轉(zhuǎn)換成八進(jìn)制: 將二進(jìn)制從右到左,每三個分成一組:

Chapter8 lesson5 002.png

結(jié)果就是1565;


舉例2:

將二進(jìn)制0b01101110101轉(zhuǎn)換成十六進(jìn)制: 將二進(jìn)制從右到左,每四個分成一組:

Chapter8 lesson5 003.png

結(jié)果就是375;


舉例3:

將十六進(jìn)制0xABC1轉(zhuǎn)換成二進(jìn)制: 將十六進(jìn)制從右到左,每個分成四位:

Chapter8 lesson5 004.png

結(jié)果就是1010 1011 1100 0001;


在C語言中怎么表示這些進(jìn)制呢?

十進(jìn)制: int a = 96;?

八進(jìn)制: int a = 0140;//0開頭?

十六進(jìn)制: int a = 0x60;//0x開頭

用0b開頭表示二進(jìn)制,約定俗成的規(guī)定。?


視頻教程??

韋東山升級版全系列嵌入式免費(fèi)視頻_快速入門篇


8.1第1個ARM裸板程序及引申(上)的評論 (共 條)

分享到微博請遵守國家法律
陆丰市| 渭南市| 皮山县| 岐山县| 集安市| 曲靖市| 瑞金市| 新安县| 克东县| 梧州市| 肥东县| 左权县| 汾西县| 肇源县| 清原| 宁城县| 霍邱县| 西青区| 清水河县| 宜州市| 德清县| 宁陕县| 高台县| 永平县| 淳化县| 清涧县| 赫章县| 泾源县| 大埔区| 金阳县| 靖边县| 八宿县| 宜宾县| 大方县| 平果县| 古浪县| 贵州省| 满城县| 光山县| 揭西县| 大足县|