一、 移植說明
最近有個項目想用GD替代原有的STM32,因為GD的成本更低。然后我就找了一些GD的資料,發(fā)現(xiàn)目前網(wǎng)上已有的一些資料都比較老,比如ST移植到GD的攻略,很多都停留在GD剛推廣不久的過渡時期,目前已經不適用。就是當時有些GD的芯片官方還開發(fā)出對應的pack包或固件庫,那時移植GD只能在工程里面選擇STM32的芯片,然后修改32的固件庫。而現(xiàn)在,GD的芯片都有了自己的固件庫和pack包,只要安裝對應的pack包就能在芯片選型那里選擇對應的GD芯片。所以如果你是用GD做一個全新的項目,那么完全可以用GD官方的demo開發(fā),不再需要將32的程序改成GD的。不過對于我這種原有32的程序已經調試完成,只需修改成GD就能用的人來說,通過修改32固件庫來兼容GD是最省事的。
之前我發(fā)過一篇博文講了STM32和GD32的區(qū)別,這里就不多講了。STM32和GD32的型號是一一對應的,比如我測試用的STM32F103C8T6和GD32F103C8T6,引腳排列也是一模一樣的,測試的時候我是直接把板子上面的STM32拆下來換成GD32的。編譯軟件用的是keil,以后有時間的話我會再寫一篇IAR的。
好了,廢話不多說,下面馬上開始講解移植的過程,移植過程中用到的所有文件我會打包上傳,請在文章底部的鏈接下載。
二、 移植步驟
1、 安裝GD的支持包。
GD的程序芯片可以選擇STM32的替代,但是燒錄的時候Flash必須選擇GD的,所以安裝支持包是必須的。我安裝的pack包版本比較老,在keil官網(wǎng)上也沒有找到最新的,所以先湊合著用。打開圖1 的兩個文件,安裝到keil的安裝目錄就可以了。
注:我看到有些以前的攻略是這樣做的:第一步:解壓GD32F10xxx Keil IDE Config.rar壓縮文件。第二步:將編程算法文件FLM file拷貝到MDK的安裝路徑”KeilARMFlash"文件夾下面。然而這個方法已經不適用了,因為現(xiàn)在我根本找不到這個壓縮文件,而且官方也不再會提供這些類似的文件了,因為現(xiàn)在GD已經有了自己的支持包和固件庫,沒必要再搞這些。
安裝完成之后可以打開工程文件,點擊FlashConfigue flash ToolsDebugSettingsFlash DownloadAdd,如果看到下圖這幾個GD的Flash就ok了。
3、 軟件延時時間修改。
GD的主頻是108M,比ST的72M要大,代碼的運行速度更快。所以如果用到了while函數(shù)或者for函數(shù)延時,延時的時間肯定是變短了,如果你程序里面有用到延時函數(shù)作為IIC或者SPI通訊的時鐘線延時,可能就需要修改延時的時間了。官方給出了這么一個數(shù)據(jù):實測下面的這一段代碼:ST執(zhí)行該函數(shù)的延時時間是7.4us,GD執(zhí)行該函數(shù)的延時時間是5.4us。
void delay(void)
{
u8 i;
for(i=0;i<75;i++);
}
這個只是作為一個參考,隨著延時時間的加長,這個差距會不一樣,不能按線性計算。有示波器的話最好用示波器實測。
然后官方也給出了一段IIC的代碼,你們可以看一下。
IO模擬I2C他的查應答函數(shù)的編寫如下:
#define SDA_Status() GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)
void CheckACK(void)
{
cAcknowledge=TRUE
if(SDA_Status())
{
cAcknowledge=FalSE;
}
}
這段代碼在ST上面執(zhí)行OK,但是在GD上面運行不正常,其實這是由于GD的執(zhí)行速度更快,ACK信號還出來,語句就已經執(zhí)行完成了。建議修改代碼:
#define SDA_Status() GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)
void CheckACK(void)
{
u8 ErrTimer=0;
cAcknowledge=TRUE
while(SDA_Status())
{
ucErrTime++;
if(ucErrTime>250)
{
cAcknowledge=FalSE;
}
}
}
如果你的程序只是用到了最常用的功能,如外部中斷、定時器、串口這些,那么按照上面的3點改完之后就可以用STM32 的程序燒錄到GD上面了,F(xiàn)lash要選擇容量相同的GD芯片型號,程序運行應該都沒什么問題。而如果你要用到一些特殊的,比如用單片機內部的Flash存數(shù)據(jù),使用單片機內部標準的IIC,SPI接口(我們經常是用普通IO口模擬,不會用單片機的庫)。那么有些地方就需要修改了,我這里有一份官方給出的GD內部設計引起的一些bug,不過因為資料是比較老的,我也沒有一一去測試,所以就不羅列出來了。我只把我測試過的依然存在的問題給大家講一下。
三、 GD用ST庫函數(shù)會出現(xiàn)的一些問題
1、 Flash
GD的Flash執(zhí)行速度快,但是寫操作慢,所以在對Flash操作的時候需要修改下面幾個函數(shù):
FLASH_Status FLASH_EraseOptionBytes(void);
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);
上面這個這四個函數(shù)里面都有下面這一句代碼:
key( FLASH->OPTKEYR = FLASH_KEY1;FLASH->OPTKEYR = FLASH_KEY2;)
我們需要在這一句代碼后添加兩個__nop()語句或者是增加While( ! (FLASH->CR & 0x200 ) );// Wait OPTWRE 語句來增加等待的時間。比如改成下面這個代碼:
/* Authorize the small information block programming */
FLASH->OPTKEYR = FLASH_KEY1;
FLASH->OPTKEYR = FLASH_KEY2;
While( ! (FLASH->CR & 0x200 ) );// Wait OPTWRE
同時也要修改擦出和寫的超時宏定義:
#define EraseTimeout ((uint32_t)0x000B0000)
#define ProgramTimeout((uint32_t)0x00002000)
修改為:
#define EraseTimeout ((uint32_t)0x000FFFFF)
#define ProgramTimeout((uint32_t)0x0000FFFF)
2、 USART
GD的MCU和ST的相比在連續(xù)發(fā)送的時候會多一個IDLE bit,如下圖。這一點對于應用是基本沒有影響,只是會影響連續(xù)發(fā)送數(shù)據(jù)的發(fā)送時間。程序也不需要修改。
STM32的USART是可以發(fā)送停止位的時候是可以選擇0.5bit,1bit, 1.5bit和 2bit 。而GD32 USART發(fā)送的時候只能發(fā)送1 bit或2bit停止位,代碼里面如果配制成0.5bit或1bit都是發(fā)送1bit,如果配制成1.5bit或2bit則發(fā)送2bit停止位。
3、EXTI中斷相應異常
EXTI配置好之后如果關閉了EXTI,IO有沿跳變,再次打開EXTI時,系統(tǒng)會響應EXTI關閉過程中的外部觸發(fā),為了規(guī)避這個問題,每次打開中斷前都清一遍中斷標志位。(小容量存在該問題,大容量沒有)
好了,關于STM32移植到GD32的相關內容就講到這里。如果你們想了解更多關于ST和GD的差異,可以看我之前發(fā)的博文,如果你想要GD的支持包或官方的固件庫,可以在文章底部的鏈接下載,如果還有什么問題或者文章有誤,請一定要聯(lián)系我,謝謝?。?!
GD32和STM32的差異:https://blog.csdn.net/ShenZhen_zixian/article/details/103250238
GD32支持包和固件庫: https://download.csdn.net/download/ShenZhen_zixian/12004032