GD32F450 200M時USB不穩定

2022-03-18 20:27:10 字數 2828 閱讀 9901

使用gd32f450的demo修改usb驅動,發現120m和168m時正常,200m時很不穩定。懷疑usb時鐘分頻有問題,一查果然是,記錄如下:

200m是庫函式主時鐘分頻**如下

static

void 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))

}

這裡注意幾個重要資訊,pll_m=25,pll_n=400,pll_q=9 

再檢視demo裡的usb時鐘配置**,從**裡我們可以了解,usb時鐘**是pllm_48m,而pllm_48m是hxtal倍頻後經由pllq分頻得到

rcu_pll48m_clock_config(rcu_pll48msrc_pllq);

rcu_ck48m_clock_config(rcu_ck48msrc_pll48m);

rcu_periph_clock_enable(rcu_usbfs);

對比資料手冊裡usb這塊的時鐘樹我們計算下usb時鐘

輸入時鐘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)

rcu_osci_on(rcu_irc48m)

/*wait till rcu_irc48m is ready

*/while(success !=rcu_osci_stab_wait(rcu_irc48m))

3、修改pllm_48m由pllai分頻來

//

使用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燒錄和除錯問題 這個問題非常坑!以致於後面在錯誤的道路上浪費了大量的...