成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

匯編實(shí)現(xiàn)時(shí)鐘設(shè)置代碼理解-創(chuàng)新互聯(lián)

匯編實(shí)現(xiàn)時(shí)鐘設(shè)置代碼理解

10余年的呼圖壁網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。網(wǎng)絡(luò)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整呼圖壁建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“呼圖壁網(wǎng)站設(shè)計(jì)”,“呼圖壁網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

下面的筆記是我在看《朱老師物聯(lián)網(wǎng)大講堂》(www.zhulaoshi.org)之后所做的筆記,只是大概根據(jù)自己看了視頻與朱老師上課做的筆記而有的理解記錄下來。

寫了

有代碼的,要把代碼給理解完整。

朱老師的隨堂程序是:clock.s

// 時(shí)鐘控制器基地址

#define ELFIN_CLOCK_POWER_BASE0xE0100000

// 時(shí)鐘相關(guān)的寄存器相對(duì)時(shí)鐘控制器基地址的偏移值

#define APLL_LOCK_OFFSET0x00

#define MPLL_LOCK_OFFSET0x08

#define APLL_CON0_OFFSET0x100

#define APLL_CON1_OFFSET0x104

#define MPLL_CON_OFFSET0x108

#define CLK_SRC0_OFFSET0x200

#define CLK_SRC1_OFFSET0x204

#define CLK_SRC2_OFFSET0x208

#define CLK_SRC3_OFFSET0x20c

#define CLK_SRC4_OFFSET0x210

#define CLK_SRC5_OFFSET0x214

#define CLK_SRC6_OFFSET0x218

#define CLK_SRC_MASK0_OFFSET    0x280

#define CLK_SRC_MASK1_OFFSET    0x284

#define CLK_DIV0_OFFSET0x300

#define CLK_DIV1_OFFSET0x304

#define CLK_DIV2_OFFSET0x308

#define CLK_DIV3_OFFSET0x30c

#define CLK_DIV4_OFFSET0x310

#define CLK_DIV5_OFFSET0x314

#define CLK_DIV6_OFFSET0x318

#define CLK_DIV7_OFFSET0x31c

#define CLK_DIV0_MASK0x7fffffff

// 這些M、P、S的配置值都是查數(shù)據(jù)手冊(cè)中典型時(shí)鐘配置值的推薦配置得來的。

// 這些配置值是三星推薦的,因此工作最穩(wěn)定。如果是自己隨便瞎拼湊出來的那就要

// 經(jīng)過嚴(yán)格測(cè)試,才能保證一定對(duì)。

#define APLL_MDIV       0x7d// 125

#define APLL_PDIV       0x3

#define APLL_SDIV       0x1

#define MPLL_MDIV0x29b// 667

#define MPLL_PDIV0xc

#define MPLL_SDIV0x1

#define set_pll(mdiv, pdiv, sdiv)(1<<31 | mdiv<<16 | pdiv<<8 | sdiv)

#define APLL_VALset_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)

#define MPLL_VALset_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)

.global clock_init

clock_init:

ldrr0, =ELFIN_CLOCK_POWER_BASE

// 1 設(shè)置各種時(shí)鐘開關(guān),暫時(shí)不使用PLL

ldrr1, =0x0

// 芯片手冊(cè)P378 寄存器CLK_SRC:Select clock source 0 (Main)

strr1, [r0, #CLK_SRC0_OFFSET]

// 2 設(shè)置鎖定時(shí)間,使用默認(rèn)值即可

// 設(shè)置PLL后,時(shí)鐘從Fin提升到目標(biāo)頻率時(shí),需要一定的時(shí)間,即鎖定時(shí)間

ldrr1,=0x0000FFFF

strr1,[r0, #APLL_LOCK_OFFSET]

str r1, [r0, #MPLL_LOCK_OFFSET]

// 3 設(shè)置分頻

// 清bit[0~31]

ldr r1, [r0, #CLK_DIV0_OFFSET]

ldrr2, =CLK_DIV0_MASK

bicr1, r1, r2

ldrr2, =0x14131440

orrr1, r1, r2

strr1, [r0, #CLK_DIV0_OFFSET]

// 4 設(shè)置PLL

// FOUT = MDIV*FIN/(PDIV*2^(SDIV-1))=0x7d*24/(0x3*2^(1-1))=1000 MHz

ldrr1, = APLL_VAL

strr1, [r0, #APLL_CON0_OFFSET]

// FOUT = MDIV*FIN/(PDIV*2^SDIV)=0x29b*24/(0xc*2^1)= 667 MHz

ldrr1, = MPLL_VAL

strr1, [r0, #MPLL_CON_OFFSET]

// 5 設(shè)置各種時(shí)鐘開關(guān),使用PLL

ldrr1, [r0, #CLK_SRC0_OFFSET]

ldrr2, =0x10001111

orrr1, r1, r2

strr1, [r0, #CLK_SRC0_OFFSET]

movpc, lr

(下面就是對(duì)這一個(gè)代碼的理解)

對(duì)clock.s這一個(gè)匯編代碼的理解

    這一段代碼的第一部分:設(shè)置各種時(shí)鐘開關(guān),暫時(shí)不用PLL

    在前面的課程里面有對(duì)于時(shí)鐘框圖的解釋,像在文檔的3.2的Figure3.3的左上角的部分有畫著這么樣的東西,初始時(shí)鐘從左邊過來,然后有兩條路走,一條是通過PLL,另一條是直接連到一個(gè)MUX開關(guān),所以我們?cè)O(shè)置初始時(shí)鐘而且不用PLL的時(shí)候我們做的就是選MUX開關(guān)來達(dá)到只設(shè)置時(shí)鐘不通過(繞過)PLL。這樣子的話就要去設(shè)置寄存器控制選通位了。

代碼:

ldrr0, =ELFIN_CLOCK_POWER_BASE

ldrr1, =0x0

strr1, [r0, #CLK_SRC0_OFFSET]// 芯片手冊(cè)P378 寄存器CLK_SRC:Select clock source 0 (Main)

解釋說到上面的代碼:

上往下數(shù)第一句

這一句是把ELFIN_CLOCK_POWER_BASE這個(gè)值賦給r0寄存器,為什么要賦這一個(gè)值呢?

可以從這一段匯編函數(shù)開始的更前面看起,這一個(gè)“ELFIN_CLOCK_POWER_BASE”是一個(gè)宏定義就是相當(dāng)把ELFIN_CLOCK_POWER_BASE與0xE0100000等值起來了(就是用到ELFIN_CLOCK_POWER_BASE的時(shí)候就是相當(dāng)于在用0xE0100000這個(gè)值)。

    為什么要把這個(gè)值在前面給宏定義出來呢?

從數(shù)據(jù)手冊(cè)的3.7 REGISTER DESCRIPTION看到關(guān)于這個(gè)時(shí)鐘的寄存器地址都是從0xE0100000這個(gè)地址開始,這個(gè)就是基地址,其他的地址都是相對(duì)著這一個(gè)地址偏移多少的量,通過一個(gè)計(jì)算,就是用基址地址加上偏移的量就可以找到我們想要設(shè)置的寄存器了,

如何通過上述所說的來給目標(biāo)寄存器寫東西呢?

代碼的第三句有一個(gè)CLK_POWER_BASE,這個(gè)東西就是偏移量啦,但這是一堆字母沒看到量啊,其實(shí)就是想上面的ELFIN_CLOCK_POWER_BASE一樣,在前面已經(jīng)給宏定義一個(gè)值了。這一個(gè)值是0x200,因?yàn)槲覀円獙懙募拇嫫魇蔷嚯x0xE0100000有0x200,我們就依據(jù)這個(gè)東西來找寄存器,并且寫入東西。寫入的值是0x0.就是這一個(gè)寄存器全部寫零。 為什么寫入0xE0100200這一個(gè)寄存器呢?

    這個(gè)地址所對(duì)應(yīng)的寄存器的名稱是:CLK_SRC0,首先去看一下這個(gè)寄存器是干嘛的,在手冊(cè)的378頁(yè)有這個(gè)寄存的介紹與如何設(shè)置(3.7.3.1 Clock Source Control Registers)。為什么要設(shè)置這個(gè)寄存器,首先就要看我們剛開始的目的是什么,我們想干嘛。我們是想“設(shè)置各種時(shí)鐘開關(guān),暫時(shí)不用PLL”,那么我們?cè)趺慈?shí)現(xiàn)呢,那就要看一下,哪一個(gè)寄存器能夠滿足我們的要求了??匆幌逻@一寄存器的功能是,數(shù)據(jù)手冊(cè)上面寫的什么Clock Source Control,就是時(shí)鐘源控制的寄存器,我想的是這一個(gè)寄存器就是控制時(shí)鐘源的來源,從圖上面看的是設(shè)置晶振與時(shí)鐘發(fā)生器產(chǎn)生的時(shí)鐘是否是要經(jīng)過PLL,這樣子就可以滿足我們的目的要求了,我們的目的就是不要PLL,晶振與時(shí)鐘產(chǎn)生多少的頻率就向右傳多 少頻率,那么我們就是要使它不使用經(jīng)過PLL的頻率好。

    為什么傳入0x0:

    從手冊(cè)上面看到這一個(gè)寄存器的初始值(默認(rèn)值都是選擇0的)就是都是剛開始默認(rèn)不用PLL倍頻過后的程序。這個(gè)的話與上面的目標(biāo)相符。這里重點(diǎn)看這幾個(gè):

1、VPLL_SEL

2、EPLL_SEL

    3、MPLL_SEL

4、APLL_SEL

這幾個(gè)控制位都是賦值零的。就是都選擇FINOUT,這么選,貌似是因?yàn)閟5pv210這個(gè)板子上面只焊了一個(gè)時(shí)鐘發(fā)生器。這個(gè)可供其他使用了,這樣子的話都選擇了0,那么就是都不經(jīng)過PLL的了,這樣的話就是不倍頻了。

代碼最后一段:

這個(gè)是按照變址尋址來做的,就是把r1的值寫入到r0+CLK_SRC0_OFFSET這一個(gè)地址里面去(因?yàn)槭墙y(tǒng)一編址,這個(gè)是個(gè)寄存器地址)。

到此,設(shè)置各種時(shí)鐘開關(guān),暫時(shí)不用PLL的問題解決了。

第二步:設(shè)置鎖定時(shí)間,使用默認(rèn)值即可。

為什么要設(shè)置鎖定時(shí)間,我的認(rèn)為,因?yàn)殒i相環(huán)(PLL)想要初始時(shí)鐘(24MHz)在瞬間完成倍頻到1G是不可能的,它需要低頻率在PLL里面回環(huán)轉(zhuǎn),一次次頻率的升高來達(dá)到1G這樣子的話就是是需要時(shí)間的,所以等一會(huì)兒,好了就可以了,在文檔(3.7.2 PLL CONTROL REGISTERS)上面是說當(dāng)輸入的頻率頻率改變或者分頻的值改變是得鎖定時(shí)間。鎖定時(shí)間的長(zhǎng)短基于PLL的源時(shí)鐘,用PLL_LOCK這一個(gè)寄存器去設(shè)置,

ldrr1,=0x0000FFFF

strr1,[r0, #APLL_LOCK_OFFSET]

str r1, [r0, #MPLL_LOCK_OFFSET]

為什么寫入0x0000FFFF

這個(gè)寄存器只有低十六位可以用,大值就是0x0000FFFF,值設(shè)置越大,鎖定的時(shí)間就越就久。默認(rèn)值是0x00000FFF,設(shè)置這一個(gè)大值也沒事,也就是隔久一點(diǎn)而已。時(shí)間超過剛好值的話那時(shí)候已經(jīng)是好了。

有兩個(gè)寄存器,就是鎖好兩個(gè)APLL和MPLL兩個(gè)倍頻器。就是這樣。

第三步:設(shè)置分頻

設(shè)置分頻系統(tǒng),由它決定給左邊的分多少倍從而得到右邊的頻率,說得清楚一些就是左邊的頻率除以一個(gè)分頻器可以接受的值,然后得到的值輸出到右邊。我們要做的就是設(shè)置分頻系數(shù),說清楚些就是設(shè)置那一個(gè)除數(shù)。設(shè)置的寄存器是CLK_DIV

如何設(shè)置呢?

視頻上面用說的方式給清楚地說出了如何去設(shè)置,在代碼中那個(gè)值是什么意思了。

    直接用代碼中的設(shè)置值來分析:

ldr r2, =0x14131440

給r2所指代的寄存器寫入0x14131440,從文檔的3.7.4.1 Clock Divider Control Register這一部分看。所寫入的數(shù)據(jù)的第一個(gè)1,是30:28位的,在關(guān)于這一個(gè)寄存器的設(shè)置描述欄中寫的是公式PCLK_PSYS = HCLK_PSYS / (PCLK_PSYS_RATIO + 1),我們寫的1,那就相當(dāng)于給PCLK_PSYS_RATIO的值賦了一個(gè)1,這樣子的話下面的除數(shù)就是2.因?yàn)?+1等于2,PCLK_PSYS和HCLK_PSYS要從文檔上面3.4 CLOCK GENERATION的那個(gè)3.3圖中找,可以找到在右下角的PSYS域中的HCLK_PSYS和PCLK_PSYS,描述欄的公式意思是PCLK_PSYS的時(shí)鐘頻率是通過HCLK_PSYS的頻率除以2得到的。

代碼的理解:

  ldr r1, [r0, #CLK_DIV0_OFFSET]

  ldrr2, =CLK_DIV0_MASK

  bicr1, r1, r2

  ldrr2, =0x14131440

  orrr1, r1, r2

  strr1, [r0, #CLK_DIV0_OFFSET]

//忽然發(fā)現(xiàn)我理解不了,方法是往哪個(gè)寄存器寫東西?為什么往那里寫,為什么寫//0x14131440?(漫長(zhǎng))

第四步:設(shè)置PLL

這個(gè)地方也是要學(xué)會(huì)看文檔。(可見有會(huì)看文檔的功力也是很重要的)

講的是APLL和MPLL,這兩個(gè)PLL我們可以在文檔的361頁(yè)可以看到圖。

要對(duì)它做什么?

對(duì)他設(shè)置合適的參數(shù),然后lock,然后等待輸出。

怎么設(shè)置參數(shù):

找文檔,現(xiàn)在設(shè)置的是APLL,找啊找,在文檔的372,上面有個(gè)APLL_CON0,看這一頁(yè)的寄存器位的介紹,首先要看一個(gè)公式:

 FOUT = MDIV X FIN / (PDIV × 2^(SDIV-1))

這個(gè)公式是與寄存位的介紹配合起來看的,想知道在公式上面的變量怎么設(shè)置看寄存器位的介紹表中的MDIV[25:16]、PDIV[13:8]、SDIV[2:0]這幾位。這幾個(gè)很重要。

公式中的MDIV值就是設(shè)置寄存器中的25:26位的值,F(xiàn)IN的值是左邊的頻率進(jìn)PLL的值,比如在文檔上面“3.4 CLOCK GENERATION”部分的那個(gè)圖中看左上角的APLL地方的左邊寫著有PLL這就是FIN。FOUT同理可以理解。PDIV就是我們?cè)O(shè)置的PDIV(所在寄存器的位是13:8)的值,SDIV是就是設(shè)置的SDIV所在寄存器的位是(2:0)的值。

例:在文檔中給定的初始值是:MDIV是0xc8(對(duì)應(yīng)的10進(jìn)制是200),PDIV是0x3(對(duì)應(yīng)的10進(jìn)制是3),SDIV是0x1(對(duì)應(yīng)的10進(jìn)制是1),對(duì)于APLL的話FIN是24MHz把這些值代入上式得FOUT=24*200/3*2^0=1600,這是文檔上面一個(gè)想不到的東西,因?yàn)槲覀円O(shè)置的是1GHz,但是按照這一個(gè)初值來設(shè)置的話就變成了1.6GHz了。在程序中的數(shù)值與上述的數(shù)值不一樣的是MDIV的值,這個(gè)值應(yīng)該設(shè)置成0x7d(對(duì)應(yīng)的10進(jìn)制是125)。關(guān)于這些經(jīng)典值可以到文檔的357頁(yè)的3.3.1RECOMMENDED PLL PMS VALUE FOR APLL可以得到三星給的推薦值。

但是在程序中計(jì)算FOUT的值有點(diǎn)讓人眼前一新(自己沒有碰到過的,在朱老師的C高級(jí)里面有講位運(yùn)算):

#define set_pll(mdiv, pdiv, sdiv)(1<<31 | mdiv<<16 | pdiv<<8 | sdiv)

#define APLL_VALset_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)

#define MPLL_VALset_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)

下面要講的是MPLL:

MPLL的設(shè)置方法與APLL是一樣的,只是公式不一樣而已。

第五步:設(shè)置各種時(shí)鐘開關(guān),使用PLL

從代碼來看:

ldrr1, [r0, #CLK_SRC0_OFFSET]

ldrr2, =0x10001111

orrr1, r1, r2

strr1, [r0, #CLK_SRC0_OFFSET]

這里要理解的是0x10001111的問題,在CLK_SRC0寄存器中寫入這一個(gè)值,為什么要寫入這一個(gè)值。

這里又要配合著文檔上面的《3.7.3.1 Clock Source Control Registers》這一部分來查看開了使用了哪一個(gè)東西,之后去配合《3.4 CLOCK GENERATION》這一部分的圖后,結(jié)合之前學(xué)過的xPLL與DIV的使用原理,可以算出在CLK_SRC0之后,頻率經(jīng)過什么樣的路徑,最后到達(dá)使用的部件的頻率是多少。

剛剛才入ARM裸機(jī)這水,還不深,其中肯定會(huì)有疏忽和錯(cuò)誤,如果看了這篇筆記發(fā)現(xiàn)了錯(cuò)誤,請(qǐng)指出,謝謝。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)頁(yè)題目:匯編實(shí)現(xiàn)時(shí)鐘設(shè)置代碼理解-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)鏈接:http://jinyejixie.com/article10/dsijdo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)網(wǎng)站策劃、全網(wǎng)營(yíng)銷推廣標(biāo)簽優(yōu)化、App設(shè)計(jì)、品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
焦作市| 贵港市| 肇源县| 察隅县| 浦江县| 澜沧| 德惠市| 临朐县| 白玉县| 澄城县| 丰原市| 永春县| 罗山县| 通河县| 灌南县| 黔西| 鲁甸县| 井冈山市| 井冈山市| 积石山| 巫山县| 新沂市| 卢龙县| 拉萨市| 辉南县| 拜城县| 黎川县| 哈密市| 运城市| 长泰县| 马关县| 和静县| 农安县| 辽中县| 东台市| 苍梧县| 钟山县| 西青区| 新竹县| 岗巴县| 镇原县|