在国内芯片紧张的情况下,目前如果项目没有成型可以安装官方提供的GD32的pack,选择相关的pack即可正常编程。若程序已经成型,需要移植,首先就要考虑芯片类型(stm32系列)的选择。
选择过程中首先要根据已用stm32单片机的封装和引脚定义去对应相关的gd32芯片类型。
这里我选用的是GD32f305芯片替换stm32f103rc,所作设置如下:
1.点击魔术棒选择stm32f103芯片
2.根据晶振设置晶振,这里设置72MHz
3.根据芯片flash大小设置STM32F10X_LD、STM32F10X_MD、STM32F10X_HD,不知道的可以查手册,实在不行就一个一个去试。
4.Debug中设置,如果用的是jlink仿真器就选择jlink仿真器,其他的就选用其他的,这里选择SW方式。
另外注意:如果右边框读取不到单片机信息,或者下载不了程序可以把速度降低一些,设置10k或者5k基本可以解决!
Device芯片选型
C++内容设置
Debug内容设置
1.软件移植注意事项
1.1系统方面的注意事项
stm32移植到GD32上芯片选择上的问题:
1.1.1 HSE相关内容修改
在V3.x的库,启动时间宏定义在xxx32f10x.h头文件中;
在V3.0以前的库,其启动时间宏定义在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 */
这里我使用的库是stm32f10x.h里面,位置如图所示。
修改原因:
GD和STM32的晶振部分电路设计有一定的差异,两者对外部高速晶振的参数要求也不一样,
修改HSE_STARTUP_TIMEOUT宏定义可以保证晶振正常起振。当然你会在应用中发现有一些应用
不修改也能照常跑,这是由于晶振的参数差异造成了,为了保证程序的正常运行还是修改该宏定义。
1.1.2 BOOT管脚注意事项
BOOT0及BOOT1管脚在芯片复位时的电平状态决定了复位后从哪个区域开始执行程序。一般情况下,BOOT0需外接10K下拉电阻就可。
如果程序从Flash启动把BOOT0悬空,则不能保证一定从Flash启动。
1.1.3 低功耗注意事项
如果在STOP模式设置低功耗需要将C口和E口也设置成模拟输入,因为GD的MCU内部没有将C口和E口拉至默认的电平,为了实现低功耗
只能是增加相关的配置C口和E口模拟输入的语句。
1.1.4 功耗注意事项
MCU上电所有IO口默认是浮空输入,IO口的高低电平会受到外界影响,从而影响MCU的功耗。为了芯片能够获得一致的功耗性能,需要将
所有用不到的IO口都配置成模拟输入。
1.2ADC配置问题
1.2.1ADC输入通道模式配置
更换为GD芯片,输入通道必须配制成模拟输入的模式GPIO_Mode_AIN,配制成其他模式不能正
常工作。
1.2.2 ADC时钟配置问题
使用GD的MCU的时候,需要ADC的采样配置时钟(特别是小容量,一定要配置采样时钟),
而且不能大于14M Hz。采样周期配置如下:
RCC_ADCCLKConfig(RCC_PCLK2_Divx);
1.3关于I2C配置
函数I2C_CheckEvent修改
使用V3.5.0之前的固件库需要修改I2C_CheckEvent函数。
修改前:
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;
}