這個問題我是怎麼發現的呢?首先我一般的風格不會使用while(1)這種等待的,一般會選擇加入超時機制來保證系統的正常執行。但是在我移植野火的stm32h750的sdram的程式的時候,我發現程式停留在sdram_init()裡面的while(1)中。
關於這個問題,先看stm32h750的時鐘樹:
這是我的時鐘相關配置,理論上是沒問題,也沒有達到最高頻率480mhz。
從野火的fmc的時鐘配置來看,
rcc_periphclkinit.periphclockselection = rcc_periphclk_fmc;
rcc_periphclkinit.pll2.pll2m =5;
rcc_periphclkinit.pll2.pll2n =
144;
rcc_periphclkinit.pll2.pll2p =2;
rcc_periphclkinit.pll2.pll2q =2;
rcc_periphclkinit.pll2.pll2r =3;
rcc_periphclkinit.pll2.pll2rge = rcc_pll2vcirange_2;
rcc_periphclkinit.pll2.pll2vcosel = rcc_pll2vcowide;
rcc_periphclkinit.pll2.pll2fracn =0;
rcc_periphclkinit.fmcclockselection = rcc_fmcclksource_pll2;
配置的是pll2的時鐘引數,這看上去貌似也沒什麼問題。但為什麼會pll2的時鐘初始化失敗呢?
首先找原因:
1、是不是晶振壞了?
2、是不是系統時鐘**寫錯了?
3、是不是fmc時鐘初始化在**中的位置不對?
經過一系列排查,發現都是沒問題的,並沒有解決的實際問題。任然是初始化sdram的時候卡在while(1)中,也就是fmc時鐘引數配置失敗。
從新回到stm32h7的時鐘樹上!有乙個我們不太看得到的點!
沒錯就是這裡,本來在程式上應該配置的是pll2r這個地方的時鐘,用這個地方的時鐘輸出到fmc上,但是卻是預設選擇hclk3,所以,這就是導致為什麼pll2初始化一直失敗的原因!這時候將它選中pll2q,
將會和預期的一樣,得到360mhz的時鐘。通過stm32cubemx生成工程,後新增相關驅動檔案,發現sdram的初始化不會再卡住了。這時候,我們比對兩個工程的systemclock_config(),就很容易發現多了一句話,
沒錯,就是因為這裡的選擇問題,fmc的時鐘源,必須選擇rcc_fmcclksource_pll2的時候,才能對pll2的配置生效,否則配置將error。這問題搞了我一晚上,真不應該啊!
STM32的時鐘控制
stm32外部晶振經倍頻後提供系統時鐘常用設定 void rcc configuration void rcc sysclkconfig rcc sysclksource pllclk 設定pll為系統時鐘 while rcc getsysclksource 0x08 檢測系統的時鐘源是否是pll ...
STM32的時鐘分割
tim timebasestructure.tim clockdivision 時鐘分割 timx ccmr1 暫存器 是定時器的輸入頻率 timxclk 一般是 72mhz 而則是根據 timx cr1 的ckd 1 0 的設定來確定的,如果 ckd 1 0 設定為00 那麼 n 值就是濾波長度,...
STM32 STM32的復用時鐘何時開啟?
stm32的afio時鐘真的是在開啟引腳復用功能的時候開啟嗎?其實並不是 我們知道,stm32有很多外設,這些外設的外部引腳都是與gpio共用的。我們可以通過軟體來配置引腳作為gpio引腳還是作為外設引腳。當引腳配置為外設引腳時就叫做復用。如串列埠預設復用的引腳為 pa9 pa10引腳可配置為普通i...