日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

GD32芯片移植完全攻略

發布時間:2024/2/2 综合教程 27 生活家
生活随笔 收集整理的這篇文章主要介紹了 GD32芯片移植完全攻略 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

GD32是國產兆易創新公司生產的完全兼容STM32系列的Cortex-M3處理器,具有幾大亮點:
1,高主頻108MHz。性能提升30%以上,可超頻到120MHz
2,Flash零等待。STM32的72MHz需要兩個等待,其實兆易創新公司本來就是做Flash起家的,具有gFlash專利
3,采用ARM Cortex-M3新內核R2p1。STM32采用R1p1,帶有一些缺陷
4,性價比高。GD32比對應的STM32芯片一般便宜20%,某些芯片便宜30%以上

收到樣片GD32F103VET6后,替換STM32F103VET6,寫入最新版本TinyBooter和MF固件,以及MF測試例程,全部一次性通過!
兼容性非常好。
不過我們不能滿足于此,MF固件默認跑在72MHz主頻,Flash還是使用兩個等待,我們需要測試更高速度!
于是根據官方的資料,修改主頻為108MHz,Flash為零等待。

RCC->CFGR |= (uint32_t)(0x08000000 | RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL12);

修改以后發現USB無法識別,串口一團糟!
上面是網上能找到的最多的資料,意思是HSE/2*(12+15),除以2和12都可以理解,15哪里冒出來的就實在不懂了。

請求官方技術支持,幾分鐘后得到郵件回復。
大意是108MHz無法分頻得到USB所需要的48MHz,STM32本來支持1分頻和1.5分配,然后GD32在這方面擴展了2分頻和2.5分配。所以,如果想要使用USB,要么降頻到96MHz,要么超頻到120MHz,這樣分別使用2分頻和2.5分配即可得到USB所需要的48MHz。
這就說明GD32無法在標準108MHz下使用USB,好杯具!??!

另外,關于串口亂碼的問題,給我的答復是修改RCC_GetClocksFreq函數:

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;
}

大概意思是判斷一個標識位,如果有那個標識位,則采用另一條公式來計算倍頻。暫時猜測那個標識位是GD32專用。
但是這樣解決不了我的問題,我們的MF系統采用的是寄存器設定波特率,根本就沒有使用庫函數。我就想理清思路搞清楚這里為什么要這樣修改,然后我依葫蘆畫瓢同樣操作寄存器。結果我失敗了,這里的17跟上面的15同樣莫名其妙,不過+17比下面原來的+2剛好多了15,看來有什么關系。

就以0x20000000作為切入口,查看它在RCC->CFGR中的用途。

果然是GD32專用,0x20000000是第29位保留位。
小飛覺得這一位跟前面的15有關,那么我們嘗試把前面分頻使用的0x08000000改為0x20000000試試

RCC->CFGR |= (uint32_t)(0x20000000 | RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL12);

這個時候系統跑起來了,串口沒有亂碼,但是USB口不能使用,當然了,USB在108MHz不能用呀。
這樣子算是解決了串口亂碼這個問題。
但是有個非常奇怪的問題,Keil調試看到系統時鐘是48MHz,通過寄存器換算也是,百思不得其解!
花哥提醒,Keil的RCC調試界面是為STM32準備的,看GD32的特殊頻率可能不準。
其實關鍵就在于這個29位,由于它的存在,導致RCC_GetClocksFreq函數計算108MHz分頻時忽略了29位,從而得到48MHz,也就是8M/2*12,那個15不見了。
因此,GD32新手需要修改RCC_GetClocksFreq是為了讓頻率計算結果為108MHz,從而解決串口亂碼問題。而我用0x0800000分頻的時候,MCU實際工作在48MHz,然后在串口那里計算波特率的時候,我使用了108MHz。兩者犯了不同的錯誤,導致了相同的結果,然后歪打正著解決了這個問題。
之前很多人讓我等比例換算頻率,108M是72M的1.5倍,然后在波特率那里也這樣算。但是我不服氣,因為F407是168M,也是這個公式。
結論表明:串口亂碼的關鍵是計算波特率的頻率必須與實際MCU頻率相符

對于MF系統來說,不能使用USB是不可原諒的,于是我們測試96MHz和120MHz,分別12倍頻和15倍頻,USB分別2分頻和2.5分頻,非常好算!
通過Keil調試發現系統成功工作在96MHz和120MHz,但是顯示的USB頻率有時是64MHz,有時是96MHz/80MHz/120MHz,很是莫名其妙!
PC無法發現USB設備,非常郁悶!
后來無意中清空一次芯片Flash后才明白,原來是TinyBooter工作在120MHz已經啟動,但是TinyCLR還跑在72MHz,導致發現不了USB。
重新編譯TinyCLR到120MHz后解決問題,發現USB。
并且,在刷寫TinyCLR的時候,速度明顯加快,大概100k Byte/s

實際上這些問題可能不是很難,但是官方沒有統一的詳細的文檔(沒有說清楚為什么那樣子改)。
事后在網上發現一個信息:

Q:GD32F105/107系列MCU 配置為108MHz有何不同?
A:通過Clock configuration register (RCC_CFGR) 中,第21:18位為PLLMUL[3:0],再結合第29位PLLMUL[4]組成5 位的位域來確定PLL 倍頻系數,
即通過軟件配置來定義PLL 的倍頻系數,且PLL 輸出頻率絕對不得超過最高主頻(108MHz)。

真是坑爹呀,有木有???

120MHz主頻,加上Flash零等待,性能提升應該不止50%了吧,對于性能不足的MF來說,可是極大的利好!
至于是否穩定,咱不懂,直接裝上流水線試試!

End.

                                    轉石頭大哥

總結

以上是生活随笔為你收集整理的GD32芯片移植完全攻略的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。