在國(guó)內(nèi)芯片緊張的情況下,目前如果項(xiàng)目沒(méi)有成型可以安裝官方提供的GD32的pack,選擇相關(guān)的pack即可正常編程。若程序已經(jīng)成型,需要移植,首先就要考慮芯片類(lèi)型(stm32系列)的選擇。
選擇過(guò)程中首先要根據(jù)已用stm32單片機(jī)的封裝和引腳定義去對(duì)應(yīng)相關(guān)的gd32芯片類(lèi)型。
這里我選用的是GD32f305芯片替換stm32f103rc,所作設(shè)置如下:
1.點(diǎn)擊魔術(shù)棒選擇stm32f103芯片
2.根據(jù)晶振設(shè)置晶振,這里設(shè)置72MHz
3.根據(jù)芯片flash大小設(shè)置STM32F10X_LD、STM32F10X_MD、STM32F10X_HD,不知道的可以查手冊(cè),實(shí)在不行就一個(gè)一個(gè)去試。
4.Debug中設(shè)置,如果用的是jlink仿真器就選擇jlink仿真器,其他的就選用其他的,這里選擇SW方式。
另外注意:如果右邊框讀取不到單片機(jī)信息,或者下載不了程序可以把速度降低一些,設(shè)置10k或者5k基本可以解決!

?
Device芯片選型

?
C++內(nèi)容設(shè)置

?
Debug內(nèi)容設(shè)置
1.軟件移植注意事項(xiàng)
1.1系統(tǒng)方面的注意事項(xiàng)
stm32移植到GD32上芯片選擇上的問(wèn)題:
1.1.1 HSE相關(guān)內(nèi)容修改
在V3.x的庫(kù),啟動(dòng)時(shí)間宏定義在xxx32f10x.h頭文件中;
在V3.0以前的庫(kù),其啟動(dòng)時(shí)間宏定義在xxx32f10x.h中(HSEStartUp_TimeOut);
修改前:
#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */
修改后:
#define HSE_STARTUP_TIMEOUT ((uint16_t)0xFFFF) /*!< Time out for HSE start up */
這里我使用的庫(kù)是stm32f10x.h里面,位置如圖所示。

修改原因:
GD和STM32的晶振部分電路設(shè)計(jì)有一定的差異,兩者對(duì)外部高速晶振的參數(shù)要求也不一樣,
修改HSE_STARTUP_TIMEOUT宏定義可以保證晶振正常起振。當(dāng)然你會(huì)在應(yīng)用中發(fā)現(xiàn)有一些應(yīng)用
不修改也能照常跑,這是由于晶振的參數(shù)差異造成了,為了保證程序的正常運(yùn)行還是修改該宏定義。
1.1.2 BOOT管腳注意事項(xiàng)
BOOT0及BOOT1管腳在芯片復(fù)位時(shí)的電平狀態(tài)決定了復(fù)位后從哪個(gè)區(qū)域開(kāi)始執(zhí)行程序。一般情況下,BOOT0需外接10K下拉電阻就可。
如果程序從Flash啟動(dòng)把BOOT0懸空,則不能保證一定從Flash啟動(dòng)。
1.1.3 低功耗注意事項(xiàng)
如果在STOP模式設(shè)置低功耗需要將C口和E口也設(shè)置成模擬輸入,因?yàn)镚D的MCU內(nèi)部沒(méi)有將C口和E口拉至默認(rèn)的電平,為了實(shí)現(xiàn)低功耗
只能是增加相關(guān)的配置C口和E口模擬輸入的語(yǔ)句。
1.1.4 功耗注意事項(xiàng)
MCU上電所有IO口默認(rèn)是浮空輸入,IO口的高低電平會(huì)受到外界影響,從而影響MCU的功耗。為了芯片能夠獲得一致的功耗性能,需要將
所有用不到的IO口都配置成模擬輸入。
1.2ADC配置問(wèn)題
1.2.1ADC輸入通道模式配置
更換為GD芯片,輸入通道必須配制成模擬輸入的模式GPIO_Mode_AIN,配制成其他模式不能正
常工作。
1.2.2 ADC時(shí)鐘配置問(wèn)題
使用GD的MCU的時(shí)候,需要ADC的采樣配置時(shí)鐘(特別是小容量,一定要配置采樣時(shí)鐘),
而且不能大于14M Hz。采樣周期配置如下:
RCC_ADCCLKConfig(RCC_PCLK2_Divx);
1.3關(guān)于I2C配置
函數(shù)I2C_CheckEvent修改
使用V3.5.0之前的固件庫(kù)需要修改I2C_CheckEvent函數(shù)。
修改前:
ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
uint32_t lastevent = 0;
uint32_t flag1 = 0, flag2 = 0;
ErrorStatus status = ERROR;
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_EVENT(I2C_EVENT));
/* Read the I2Cx status register */
flag1 = I2Cx->SR1;
flag2 = I2Cx->SR2;
flag2 = flag2 << 16;
/* Get the last event value from I2C status register */
lastevent = (flag1 | flag2) & FLAG_Mask;
/* Check whether the last event contains the I2C_EVENT */
if (lastevent == I2C_EVENT)
{
/* SUCCESS: last event is equal to I2C_EVENT */
status = SUCCESS;
}
else
{
/* ERROR: last event is different from I2C_EVENT */
status = ERROR;
}
/* Return status */
return status;
}
修改后:
ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
uint32_t lastevent = 0;
uint32_t flag1 = 0, flag2 = 0;
ErrorStatus status = ERROR;
/* Check the parameters */
assert_param(IS_I2C_ALL_PERIPH(I2Cx));
assert_param(IS_I2C_EVENT(I2C_EVENT));
/* Read the I2Cx status register */
flag1 = I2Cx->SR1;
flag2 = I2Cx->SR2;
flag2 = flag2 << 16;
/* Get the last event value from I2C status register */
lastevent = (flag1 | flag2) & FLAG_Mask;
/* Check whether the last event contains the I2C_EVENT */
if ((lastevent & I2C_EVENT) == I2C_EVENT)
{
/* SUCCESS: last event is equal to I2C_EVENT */
status = SUCCESS;
}
else
{
/* ERROR: last event is different from I2C_EVENT */
status = ERROR;
}
/* Return status */
return status;
}
審核編輯:湯梓紅
評(píng)論