本節主要涉及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...