GD32芯片移植完全攻略
GD32是國產(chǎn)兆易創(chuàng)新公司生產(chǎn)的完全兼容STM32系列的Cortex-M3處理器,具有幾大亮點(diǎn):
1,高主頻108MHz。性能提升30%以上,可超頻到120MHz
2,Flash零等待。STM32的72MHz需要兩個(gè)等待,其實(shí)兆易創(chuàng)新公司本來就是做Flash起家的,具有g(shù)Flash專利
3,采用ARM Cortex-M3新內(nèi)核R2p1。STM32采用R1p1,帶有一些缺陷
4,性價(jià)比高。GD32比對(duì)應(yīng)的STM32芯片一般便宜20%,某些芯片便宜30%以上
收到樣片GD32F103VET6后,替換STM32F103VET6,寫入最新版本TinyBooter和MF固件,以及MF測(cè)試?yán)蹋恳淮涡酝ㄟ^!
兼容性非常好。
不過我們不能滿足于此,MF固件默認(rèn)跑在72MHz主頻,F(xiàn)lash還是使用兩個(gè)等待,我們需要測(cè)試更高速度!
于是根據(jù)官方的資料,修改主頻為108MHz,F(xiàn)lash為零等待。
|
修改以后發(fā)現(xiàn)USB無法識(shí)別,串口一團(tuán)糟!
上面是網(wǎng)上能找到的最多的資料,意思是HSE/2*(12+15),除以2和12都可以理解,15哪里冒出來的就實(shí)在不懂了。
請(qǐng)求官方技術(shù)支持,幾分鐘后得到郵件回復(fù)。
大意是108MHz無法分頻得到USB所需要的48MHz,STM32本來支持1分頻和1.5分配,然后GD32在這方面擴(kuò)展了2分頻和2.5分配。所以,如果想要使用USB,要么降頻到96MHz,要么超頻到120MHz,這樣分別使用2分頻和2.5分配即可得到USB所需要的48MHz。
這就說明GD32無法在標(biāo)準(zhǔn)108MHz下使用USB,好杯具!!!
另外,關(guān)于串口亂碼的問題,給我的答復(fù)是修改RCC_GetClocksFreq函數(shù):
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & CFGR_SWS_Mask;
switch (tmp)
{
case 0x00:/* HSI used as system clock */
RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
break;
case 0x04:/* HSE used as system clock */
RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
break;
case 0x08:/* PLL used as system clock */
/* Get PLL clock source and multiplication factor ----------------------*/
pllmull = RCC->CFGR &((uint32_t)0x203C0000);
pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;
if(((pllmull)&(0x20000000)) != 0)
pllmull = (((pllmull)&(0x003C0000)) >> 18) + 17;
else
pllmull = ( pllmull >> 18) +2;
if (pllsource == 0x00)
{/* HSI oscillator clock divided by 2 selected as PLL clock entry */
RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
}
else
{
/* HSE selected as PLL clock entry */
if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
{/* HSE oscillator clock divided by 2 */
RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;
}
else
{
RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;
}
}
break;
default:
RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
break;
}
/* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
/* Get HCLK prescaler */
tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;
tmp = tmp >> 4;
presc = APBAHBPrescTable[tmp];
/* HCLK clock frequency */
RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
/* Get PCLK1 prescaler */
tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;
tmp = tmp >> 8;
presc = APBAHBPrescTable[tmp];
/* PCLK1 clock frequency */
RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
/* Get PCLK2 prescaler */
tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;
tmp = tmp >> 11;
presc = APBAHBPrescTable[tmp];
/* PCLK2 clock frequency */
RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
/* Get ADCCLK prescaler */
tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;
tmp = (tmp >> 14)+(tmp >> 26);
presc = ADCPrescTable[tmp];
/* ADCCLK clock frequency */
RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
}
大概意思是判斷一個(gè)標(biāo)識(shí)位,如果有那個(gè)標(biāo)識(shí)位,則采用另一條公式來計(jì)算倍頻。暫時(shí)猜測(cè)那個(gè)標(biāo)識(shí)位是GD32專用。
但是這樣解決不了我的問題,我們的MF系統(tǒng)采用的是寄存器設(shè)定波特率,根本就沒有使用庫函數(shù)。我就想理清思路搞清楚這里為什么要這樣修改,然后我依葫蘆畫瓢同樣操作寄存器。結(jié)果我失敗了,這里的17跟上面的15同樣莫名其妙,不過+17比下面原來的+2剛好多了15,看來有什么關(guān)系。
就以0x20000000作為切入口,查看它在RCC->CFGR中的用途。
果然是GD32專用,0x20000000是第29位保留位。
小飛覺得這一位跟前面的15有關(guān),那么我們嘗試把前面分頻使用的0x08000000改為0x20000000試試
|
這個(gè)時(shí)候系統(tǒng)跑起來了,串口沒有亂碼,但是USB口不能使用,當(dāng)然了,USB在108MHz不能用呀。
這樣子算是解決了串口亂碼這個(gè)問題。
但是有個(gè)非常奇怪的問題,Keil調(diào)試看到系統(tǒng)時(shí)鐘是48MHz,通過寄存器換算也是,百思不得其解!
花哥提醒,Keil的RCC調(diào)試界面是為STM32準(zhǔn)備的,看GD32的特殊頻率可能不準(zhǔn)。
其實(shí)關(guān)鍵就在于這個(gè)29位,由于它的存在,導(dǎo)致RCC_GetClocksFreq函數(shù)計(jì)算108MHz分頻時(shí)忽略了29位,從而得到48MHz,也就是8M/2*12,那個(gè)15不見了。
因此,GD32新手需要修改RCC_GetClocksFreq是為了讓頻率計(jì)算結(jié)果為108MHz,從而解決串口亂碼問題。而我用0x0800000分頻的時(shí)候,MCU實(shí)際工作在48MHz,然后在串口那里計(jì)算波特率的時(shí)候,我使用了108MHz。兩者犯了不同的錯(cuò)誤,導(dǎo)致了相同的結(jié)果,然后歪打正著解決了這個(gè)問題。
之前很多人讓我等比例換算頻率,108M是72M的1.5倍,然后在波特率那里也這樣算。但是我不服氣,因?yàn)镕407是168M,也是這個(gè)公式。
結(jié)論表明:串口亂碼的關(guān)鍵是計(jì)算波特率的頻率必須與實(shí)際MCU頻率相符!
對(duì)于MF系統(tǒng)來說,不能使用USB是不可原諒的,于是我們測(cè)試96MHz和120MHz,分別12倍頻和15倍頻,USB分別2分頻和2.5分頻,非常好算!
通過Keil調(diào)試發(fā)現(xiàn)系統(tǒng)成功工作在96MHz和120MHz,但是顯示的USB頻率有時(shí)是64MHz,有時(shí)是96MHz/80MHz/120MHz,很是莫名其妙!
PC無法發(fā)現(xiàn)USB設(shè)備,非常郁悶!
后來無意中清空一次芯片F(xiàn)lash后才明白,原來是TinyBooter工作在120MHz已經(jīng)啟動(dòng),但是TinyCLR還跑在72MHz,導(dǎo)致發(fā)現(xiàn)不了USB。
重新編譯TinyCLR到120MHz后解決問題,發(fā)現(xiàn)USB。
并且,在刷寫TinyCLR的時(shí)候,速度明顯加快,大概100k Byte/s
實(shí)際上這些問題可能不是很難,但是官方?jīng)]有統(tǒng)一的詳細(xì)的文檔(沒有說清楚為什么那樣子改)。
事后在網(wǎng)上發(fā)現(xiàn)一個(gè)信息:
|
真是坑爹呀,有木有???
120MHz主頻,加上Flash零等待,性能提升應(yīng)該不止50%了吧,對(duì)于性能不足的MF來說,可是極大的利好!
至于是否穩(wěn)定,咱不懂,直接裝上流水線試試!
End.
轉(zhuǎn)石頭大哥
總結(jié)
以上是生活随笔為你收集整理的GD32芯片移植完全攻略的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 低血糖能不能吃豆制品
- 下一篇: 国密证书生成实践