使用gd32f450的demo修改usb驅動,發現120m和168m時正常,200m時很不穩定。懷疑usb時鐘分頻有問題,一查果然是,記錄如下:
200m是庫函式主時鐘分頻**如下
static這裡注意幾個重要資訊,pll_m=25,pll_n=400,pll_q=9void system_clock_200m_25m_hxtal(void
)while((0u == stab_flag) && (hxtal_startup_timeout !=timeout));
/*if fail
*/if(0u == (rcu_ctl &rcu_ctl_hxtalstb))
}rcu_apb1en |=rcu_apb1en_pmuen;
pmu_ctl |=pmu_ctl_ldovs;
/*hxtal is stable
*//*
ahb = sysclk
*/rcu_cfg0 |=rcu_ahb_cksys_div1;
/*apb2 = ahb/2
*/rcu_cfg0 |=rcu_apb2_ckahb_div2;
/*apb1 = ahb/4
*/rcu_cfg0 |=rcu_apb1_ckahb_div4;
/*configure the main pll, pll_m = 25, pll_n = 400, pll_p = 2, pll_q = 9
*/rcu_pll = (25u | (400u
<< 6u) | (((2u >> 1u) - 1u) << 16u) |(rcu_pllsrc_hxtal) | (9u
<< 24u
));
/*enable pll
*/rcu_ctl |=rcu_ctl_pllen;
/*wait until pll is stable
*/while(0u == (rcu_ctl &rcu_ctl_pllstb))
/*enable the high-drive to extend the clock frequency to 200 mhz
*/pmu_ctl |=pmu_ctl_hden;
while(0u == (pmu_cs &pmu_cs_hdrf))
/*select the high-drive mode
*/pmu_ctl |=pmu_ctl_hds;
while(0u == (pmu_cs &pmu_cs_hdsrf))
/*select pll as system clock
*/rcu_cfg0 &= ~rcu_cfg0_scs;
rcu_cfg0 |=rcu_cksyssrc_pllp;
/*wait until pll is selected as system clock
*/while(0u == (rcu_cfg0 &rcu_scss_pllp))
}
再檢視demo裡的usb時鐘配置**,從**裡我們可以了解,usb時鐘**是pllm_48m,而pllm_48m是hxtal倍頻後經由pllq分頻得到
rcu_pll48m_clock_config(rcu_pll48msrc_pllq);對比資料手冊裡usb這塊的時鐘樹我們計算下usb時鐘rcu_ck48m_clock_config(rcu_ck48msrc_pll48m);
rcu_periph_clock_enable(rcu_usbfs);
輸入時鐘25mhz,usb時鐘=25/pll_m*pll_n/pll_q=25/25*400/9=44.44444mhz,而我們知道usb需要48mhz的時鐘才能穩定工作,所以這導致了usb工作的不穩定。
為什麼120mhz和168mhz時不會有這個穩定呢?那是因為不同時鐘主時鐘分頻函式不一樣,在120mhz和168mhz時能分出48m的時鐘給usb。
知道問題哪後,就好解決了,方法如下:
1、直接修改庫函式裡pll的分頻係數,這個方法新人不推薦
2、使用內部rck_48m作為usb的時鐘源,
rcu_ck48m_clock_config(rcu_ck48msrc_irc48m)3、修改pllm_48m由pllai分頻來rcu_osci_on(rcu_irc48m)
/*wait till rcu_irc48m is ready
*/while(success !=rcu_osci_stab_wait(rcu_irc48m))
//使用pllai_q作為pll_sel的輸入
rcu_pll48m_clock_config(rcu_pll48msrc_pllsaip);
//使用pll_sel作為usb主頻
rcu_ck48m_clock_config(rcu_ck48msrc_pll48m);
/*configure pllsai
pllai_n=192;pll_p=192/4=48mhz,pll_q=192/2=96mhz,pll_r=192/3=64mhz
注意,此處的pll_p用於後面的usb主時鐘,要確保為48mhz
*/if(error == rcu_pllsai_config(192, 4, 2, 3
))
rcu_osci_on(rcu_pllsai_ck);
if(error ==rcu_osci_stab_wait(rcu_pllsai_ck))
GD32F13x移植問題
由於stm32交期太長,產品需要更換晶元。國產晶元有數家可選,gd32 mm32 at32等等。當前我使用的是gd32,在國產晶元中算比較好的了。不過在移植過程中,也遇到過奇奇怪怪的問題,下面總結一下踩過的坑。第一次移植gd時,沒有完全移植,只是部分外設移植,導致配置混亂。stm和gd在暫存器命名上...
兆易創新 GD32F103系列
北京兆易創新科技股份 成立於2005年4 月,是一家以中國為總部的全球化晶元設計公司。公司致力於各類儲存器 控制器及周邊產品的設計研 發,已通過 sgs iso9001 及iso14001 等管理體系的認證,研發人員佔全員比例 62 在中國 南韓 美國等多個國家設有分支機構,營銷網路遍布全球,為我們...
GD32F20x系列使用問題總結
gd微控制器近幾年越來越火了,既有他自身相比與st的 優勢,也有支援國貨的信仰加成。然而乙個新的東西,或者說乙個相對較新的東西,在使用的友好性和資料的完整性方面還有很長的路要走。現將個人使用過程中碰到過的問題總結一下 1 jlink燒錄和除錯問題 這個問題非常坑!以致於後面在錯誤的道路上浪費了大量的...