(五)arm裸機開發 主頻和時鐘配置

2021-10-22 14:39:24 字數 4235 閱讀 5843

本節主要涉及imx6ull的時鐘配置,包括arm核心時鐘配置,外設時鐘配置,以及imx6ull的時鐘樹設定。主要參考的是imx6ull的reference(《imx6ull 參考手冊》)。

二、編寫程式

imxull的時鐘**於倆部分,一部分是實時時鐘,32.768mhz,用於提供rtc的時鐘。另一部分是24mhz的晶振,用於提供核心以及其他外設的時鐘。我們的時鐘樹就是從24m時鐘經過倍頻,分頻得來的,共有7路pll。

具體的時鐘樹就不放上來了,截圖實在是看不清楚。其實就是通過設定一些暫存器,設定多路選擇器和分頻器,輸出指定的頻率。

我們將 i.mx6ull 的主頻設定為 528mhz。我們如果要設定2分屏的話,pll1必須設定為1056m的輸出。 arm_pll 是由ccm_analog_pll_arm[div_select]設定的,計算公式是pll output frequency = fref * div_sel/2。所以 經過計算,ccm_analog_pll_arm[div_select]=88。2分屏的設定為ccm_cacrr[arm_podf]=0x2

我們在設定主頻的時侯需要先將主頻設定為備用模式(必須得有乙個主頻,微控制器才可以工作,即使是設定暫存器)。

從上圖中可以看到先要設定ccsr[step_sel]=0,然後設定ccsr[pll1_sw_clk_sel]=1

所以綜上所述;

1.ccsr[step_sel]=0; //備用時鐘設定

2.ccsr[pll1_sw_clk_sel]=1; //切換備用時鐘

3.ccm_analog_pll_arm[div_select]=88; //設定主頻

4.ccm_cacrr[arm_podf]=0x1; //設定2分頻

5.ccsr[pll1_sw_clk_sel]=0; //切換回主時鐘

以下是我們要設定的pll和pfd:

pll2_pfd0的計算公式為528*18/pfd0_frac

ccm_analog_pfd_528[pfd0_frac] = 0x1b; //pfd0=352m

ccm_analog_pfd_528[pfd1_frac] = 0x10; //pfd1=594m

ccm_analog_pfd_528[pfd2_frac] = 0x18; //pfd2=396m

ccm_analog_pfd_528[pfd3_frac] = 0x20; //pfd3=297m

pll2_pfd0的計算公式為480*18/pfd3_frac

ccm_analog_pfd_480[pfd0_frac] = 0xc; //pfd0=720m

ccm_analog_pfd_480[pfd1_frac] = 0x10; //pfd1=540m

ccm_analog_pfd_480[pfd2_frac] = 0x11; //pfd2=508.2m

ccm_analog_pfd_480[pfd3_frac] = 0x13; //pfd3=454.7m

設定完主頻和其他pll pfd之後我們還需要設定ahb_clk_root,ipg_clk_root,perclk_clk_root。ahb_clk_root 最高可以設定 132mhz,ipg_clk_root和perclk_clk_root最高可以設定66mhz。

#ahb_clk_root設定

cbcmr[pre_periph_clk_sel] = 01 //選擇396m

cbcdr[periph_clk_sel] =0 //需要握手訊號

cbcdr[ahb_podf]=010 //3分頻,需要握手訊號

#ipg_clk_root設定

cbcdr[ipg_podf]=01 //設定2分頻

#perclk_clk_root設定

cscmr1[perclk_clk_sel] = 0 //多路選擇

cscmr1[perclk_podf] = 000000 //1分頻

暫存器 ccm_cdhipr判斷握手訊號是否完成,1 握手沒有完成,0握手完成。

在修改 arm_podf 和 ahb_podf 的時候需要先關閉其時鐘輸出,等修改完成以後再開啟

#include

"bsp_clk.h"

//使能時鐘

intenable_clock

(void

)void

init_imx6u_clock

(void

)//設定主頻

ccm_analog->pll_arm &=~

(0x7f);

//0-6位清零

ccm_analog->pll_arm |=(

1<<13)

|(88)

;//0-6位設定為88,13位為使能位

//設定2分頻

ccm->cacrr =

0x1;

//切換回主時鐘

ccm->ccsr &=~

(1<<2)

;/*2.配置其他pll和pfd*/

/*ppl2*/

unsigned

int reg = ccm_analog->pfd_528;

reg &=~

(0x3f3f3f3f);

//pfd每個byte的0-5位清零

reg |

=0x1b

<<0;

//pfd0=352m

reg |

=0x10

<<8;

//pfd1=594m

reg |

=0x18

<<16;

//pfd2=396m

reg |

=0x20

<<24;

//pfd3=297m

ccm_analog->pfd_528 = reg;

/*ppl3*/

reg = ccm_analog->pfd_480;

reg &=~

(0x3f3f3f3f);

//pfd每個byte的0-5位清零

reg |

=0xc

<<0;

//pfd0=720m

reg |

=0x10

<<8;

//pfd1=540m

reg |

=0x11

<<16;

//pfd2=508.2m

reg |

=0x13

<<24;

//pfd3=454.7m

ccm_analog->pfd_480 = reg;

/*3. ahb、 ipg 和 perclk 根時鐘設定*/

#if 0

/*ahb_clk_root設定為132m*/

ccm->cbcmr &=(

~(3<<18)

)|(1

<<18)

;//選擇396m

ccm->cbcdr &=~

(1<<25)

;while

(ccm->cdhipr &(1

<<5)

);//等待握手完成

ccm->cbcdr &=(

~(7<<10)

)|(2

<<10)

;//設定3分頻

while

(ccm->cdhipr &(1

<<1)

);//等待握手完成

#endif

/*ipg_clk_root設定為66m*/

ccm->cbcdr &=(

~(3<<8)

)|(1

<<8)

;//設定2分頻

/*perclk_clk_root設定為66m*/

ccm->cscmr1 &=~

(1<<6)

;//多路選擇

ccm->cscmr1 &=~

(0x7);

//1分頻 不是3f?

}

總結:i.mx6ull的時鐘系統還是很複雜的,本節我們也只是講解了如何進行主頻、pll、 pfd 和一些匯流排時鐘的設定。

ARM裸機開發(五)SPI

以下裸機程式基於gt2440,編譯器為arm linux gcc 4.4.3。程式結構 本程式只有乙個spi.s檔案。程式流程 首先上電復位進入復位異常,在復位異常裡依次呼叫子程式關閉看門狗 初始化系統時鐘 初始化串列埠,最後呼叫spi傳送資料,spi傳送的資料在程式裡指定,對於本程式傳送資料為乙個...

ARM 裸機 02 ARM裸機開發流程

執行在不同平台上的程式,開發過程不盡相同。為了更好地理解 arm 裸機的開發流程,我們先和比較熟悉的 windows linux 應用程式開發對比。不同平台程式開發流程對比示意 編譯嵌入式程式的平台稱為宿主機,譬如執行 ubuntu 系統的 pc。執行嵌入式程式的平台稱為目標機,譬如 arm 開發板...

ARM裸機開發快速體驗

一。linux平台 自己寫makefile 自己寫lds指令碼 自己搭建除錯環境 二。裸機開發流程 1 編寫裸機程式 2 除錯裸機程式 3 編譯 鏈結 格式轉換成二進位制映像 1.安裝交叉工具鏈 把課程裡面的工具包拷貝到linux,解壓arm linux gcc到根目錄 c 交叉工具在usr loc...