1、usb除錯注意事項
最近做乙個專案,用的是gd32f303的mcu,用到了usb資料傳輸的方式,該系列mcu只支援usb的device的模式,不支援otg模式。本人用的是gd32官方提供的庫資訊,因此直接移植了官方的demo。在除錯過程中,除錯了很多天,每次插上usb後,電腦均提示「裝置描述符請求失敗」,一直無果後,偶然間開了內部rc時鐘,竟然可以識別了。
後面經分析得知,電路中用的是12m外部晶振,而官方demo用的是8m外部晶振。不光需要改巨集定義,還要改計算倍數,
改動如下 :
static void system_clock_48m_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/1 */
rcu_cfg0 |= rcu_apb2_ckahb_div1;
/* apb1 = ahb/2 */
rcu_cfg0 |= rcu_apb1_ckahb_div2;
#if (defined(gd32f30x_hd) || defined(gd32f30x_xd))
/* select hxtal/2 as clock source */
rcu_cfg0 &= ~(rcu_cfg0_pllsel | rcu_cfg0_predv0);
rcu_cfg0 |= (rcu_pllsrc_hxtal_irc48m | rcu_cfg0_predv0);
//改了這裡,注釋掉的是以前的
// /* ck_pll = (ck_hxtal/2) * 12 = 48 mhz */
// rcu_cfg0 &= ~(rcu_cfg0_pllmf | rcu_cfg0_pllmf_4 | rcu_cfg0_pllmf_5);
// rcu_cfg0 |= rcu_pll_mul12;
/* ck_pll = (ck_hxtal/2) * 8 = 48 mhz */
rcu_cfg0 &= ~(rcu_cfg0_pllmf | rcu_cfg0_pllmf_4 | rcu_cfg0_pllmf_5);
rcu_cfg0 |= rcu_pll_mul8;
#elif defined(gd32f30x_cl)
/* ck_pll = (ck_prediv0) * 12 = 48 mhz */
rcu_cfg0 &= ~(rcu_cfg0_pllmf | rcu_cfg0_pllmf_4 | rcu_cfg0_pllmf_5);
rcu_cfg0 |= (rcu_pllsrc_hxtal_irc48m | rcu_pll_mul12);
/* ck_prediv0 = (ck_hxtal)/5 *8 /10 = 4 mhz */
rcu_cfg1 &= ~(rcu_cfg1_pllpresel | rcu_cfg1_predv0sel | rcu_cfg1_pll1mf | rcu_cfg1_predv1 | rcu_cfg1_predv0);
rcu_cfg1 |= (rcu_pllpresrc_hxtal | rcu_predv0src_ckpll1 | rcu_pll1_mul8 | rcu_predv1_div5 | rcu_predv0_div10);
/* enable pll1 */
rcu_ctl |= rcu_ctl_pll1en;
/* wait till pll1 is ready */
while((rcu_ctl & rcu_ctl_pll1stb) == 0)
#endif /* gd32f30x_hd and gd32f30x_xd */
/* 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 120 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_pll;
/* wait until pll is selected as system clock */
while(0u == (rcu_cfg0 & rcu_scss_pll))
}
由於該usb device只支援48mhz時鐘,如果按照8mhz的放大倍數,算出來的與實際的差別很大,因此將時鐘修改正確就ok了。
修改掉了注釋那裡,重新計算,則usb可正常執行。
2 、gd32 dfu問題
官網下的dfu工具,在win7上會提示設定選項位元組失敗。改回win10系列後,可正常使用dfu,應該是該軟體存在問題,現在並未修復。
GD32 USB除錯總結
1 usb通訊都是基於中斷完成的,主要使用兩個中斷 復位中斷 資料傳輸中斷。1.1 復位中斷 對於復位中斷來講,裝置插入主機後,並設定連線,主機識別裝置連線後,會復位裝置。復位後使用0預設位址,對裝置進行列舉,列舉過程其實就是獲取裝置的各種描述符。當裝置被主機復位後,裝置會對端點0的相關暫存器進行初...
GD32F450 200M時USB不穩定
使用gd32f450的demo修改usb驅動,發現120m和168m時正常,200m時很不穩定。懷疑usb時鐘分頻有問題,一查果然是,記錄如下 200m是庫函式主時鐘分頻 如下 static void system clock 200m 25m hxtal void while 0u stab fl...
GD32 GD32設定TIMER0輸出PWM
系統狀態 供電3.3v,系統主頻為8m 目標 使用timer0的ch1在pa9引腳輸出1khz的方波 步驟 1.初始化io口 2.初始化定時器 3.初始化pwm輸出通道 io口時鐘 rcu periph clock enable rcu gpioa 設定io口,設定為復用模式 gpio mode s...