STM32F05X移植GD32F1X0注意事项1、安装GD_MDK补丁到MDK的安装⽬录下
2、FLASH算法⽂件在“GD32F10xxx Keil IDE Config”⽂件夹中,算法⽂件需要复拷贝到“ D:\\Keil\\ARM\\Flash ”中;3、选择算法⽂件(xxx.FLM)
For GD32F10xx4,GD32F10xx6,GD32F10xX8,GD32F10xxB, Please select GD32F10xx468B.FLM as Flash programming algorithm.
For GD32F10xxC,GD32F10xxD,GD32F10xxE,GD32F10xxF,GD32F10xxG, Please select GD32F10xxCDEFGIK.FLM as Flash programming algorithm.For GD32F10xxI,GD32F10xxK, Pls select the relevant P/N of \"32F10xxG\" firstly and then select GD32F10xxCDEFGIK.FLM as Flash programming algorithm.For GD32F1x0x4,GD32F1x0x6,GD32F1x0x8 value line series of MCU, Please select the relevant P/N of \"32F103xx\" firstly and then selectGD32F1x0468.FLM asFlash programming algorithm.
4、使⽤GD 150的demo程序中的外设库替换F030⼯程中的外设固件,同时替换掉F030⼯程中的启动⽂件,并正确选择GD32驱动芯⽚类型
5、修改中断向量设置,因为GD使⽤的是M3内核所以中断分成抢占优先级和⼦优先级,程序中需要进⾏中断分组和中断向量的重新配置,程序中的⼏个中断向量都需要调整。6、GD的内核是M3的,有两条APB总线所以⽐ST要多配置⼀条APB总线,ADC外设
使⽤M3内核的⽤法,所以ADC的函数使⽤与参数传送不同于M0,参考M3内核ADC使⽤⽅法。需要正确配置系统时钟,以及APB1和APB2时钟,否则时钟会不正常。
7、HSE相关内容修改
在V3.x的库,启动时间宏定义在xxx32f10x.h头⽂件中;
在V3.0以前的库,其启动时间宏定义在xxx32f10x_rcc.c中(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 */修改原因:
GD和STM32的晶振部分电路设计有⼀定的差异,两者对外部⾼速晶振的参数要求也不⼀样,修改HSE_STARTUP_TIMEOUT宏定义可以保证晶振正常起振。当然你会在应⽤中发现有⼀些应⽤不修改也能照常跑,这是由于晶振的参数差异造成了,为了保证程序的正常运⾏还是修改该宏定义。8、代码执⾏速度⽅⾯的修改
GD32采⽤专利技术,提⾼了相同⼯作频率下的代码执⾏速度,带来了⾼性能的使⽤体验。这样⼀些在ST下⾯编写的程序如While或者是For循环的延时,移植到GD上⾯来肯定相应的延时会变短。所以如果客户的应⽤有⽤到这种延时⽅法的得根据实际情况进⾏⼀定的调整。GD的代码执⾏速度⽐ST更快,那么在客户的应⽤中如果有⼀些判断的结构不够严谨也可能会导致问题。9、BOOT管脚注意事项
BOOT0及BOOT1管脚在芯⽚复位时的电平状态决定了复位后从哪个区域开始执⾏程序。典型情况下,BOOT0需外接10K下拉电阻,就可以从Flash启动。如BOOT0悬空,则不能从Flash启动。
10、由于GD32芯⽚不够完全成熟,有些外设有需要注意的细节问题,请参考《GD32F103X-移植指南》
11、使⽤GD-LINK烧录时,不需要给芯⽚另外供电。
12、不能使⽤ST-LINK官⽅上位机烧录,但可使⽤ST-LINK、JLINK等烧录⼯具移植过程
A0:在Keil中,Device选型:
A0:GD32f130c6应当选择STM32F101C6/8,因为该系列寄存器与GD130最接近。左图为100,右图为101,实际130的SPI包含I2SCFGR与I2SPR寄存器。
另外使⽤STLINK读取的Device,如图:
Q1、EXTI中断⽆效?A1:
[cpp]view plain copy
1.RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
2.SYSCFG_EXTILineConfig(PWR_EXTI_PORT_SOURCE, PWR_EXTI_PIN_SOURCE);
其中在操作SYSCFG寄存器时,必须先使能SYSCFG的CLK,这个问题在M0上也是⼀样的,但是我在移植过程中,忽略了这点。
导致花了⼀些时间才找到这个问题。找类似这种bug,两⽅⾯着⼿,⼀⽤硬件仿真,看外设寄存器是否与预设⼀直;⼆设置完后直接串⼝打印出来。Q2、NVIC配置部分需要增加下⾯两句,M0⽆此配置,M3则有。A2:
[cpp]view plain copy
1./* NVIC configuration for priority grouping */2.NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);3./*定位中断向量表*/
4.NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0);[cpp]view plain copy
1.
另外中断优先级配置因为有组的概念,所以也有所不同,如;STM32F051:[cpp]view plain copy
1.NVIC_InitStructure.
NVIC_IRQChannelPriority = 0x03; //0x03,与IRRec保持⼀致GD130:
[cpp]view plain copy
1.NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
2.NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
Q3、EXTI在handler mode进⼊stop mode后不能唤醒,在thread mode中进⼊可以唤醒?A3:
如果在Handler mode进⼊STOP mode,需要唤醒,则唤醒源的中断优先级必须必进⼊stop mode的handler 优先级更⾼。否则同级或更低级的中断⽆法唤醒,除⾮退出中断。这也是在thread mode进⼊可以被唤醒的原因。如在timer2中进⼊stopmode,在exti按键唤醒。demo:[cpp]view plain copy
1.static void PWR_NVIC_Configuration(void)2.{
3. NVIC_InitTypeDef NVIC_InitStructure;4.
5./* Enable the EXTIx global Interrupt */
6. NVIC_InitStructure.NVIC_IRQChannel = PWR_EXTI_IRQn;7. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;8. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;9. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;10. NVIC_Init(&NVIC_InitStructure);11.}12.13.
14.static void TIM2_NVIC_Configuration(void)15.{
16. NVIC_InitTypeDef NVIC_InitStructure;17.
18./* Enable the TIM global Interrupt */
19. NVIC_InitStructure.NVIC_IRQChannel = KEY_TIM_IRQn;20. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;21. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;22. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;23. NVIC_Init(&NVIC_InitStructure);24.}
Q4:SPI寄存器区别:
A4:SPIx_CR1 Bit11,051中该bit(CRCL)是CRC length,130是FF16(FF16)是data frame formate;
SPIx_CR2 bit15-bit8,130中⾼8位为保留字节,051则有其他定义,如fifo触发值与data size。因此130中没有该库函数:[cpp]view plain copy
1.SPI_RxFIFOThresholdConfig(LT8900SPI, SPI_RxFIFOThreshold_QF); //8bitsize->QF,16bit->HF通讯库函数区别:M0:
[cpp]view plain copy
1./* Send byte through the SPI1 peripheral */2.SPI_SendData8(LT8900SPI, *pu32Data);3./* Wait to receive a byte */
4.while (SPI_I2S_GetFlagStatus(LT8900SPI, SPI_I2S_FLAG_RXNE) == RESET);5./* Return the byte read from the SPI bus */6.return SPI_ReceiveData8(LT8900SPI);
GD130:
[cpp]view plain copy
1./* Send byte through the SPI1 peripheral */2.SPI_I2S_SendData(LT8900SPI, *pu32Data);3./* Wait to receive a byte */
4.while (SPI_I2S_GetFlagStatus(LT8900SPI, SPI_I2S_FLAG_RXNE) == RESET);5./* Return the byte read from the SPI bus */6.return SPI_I2S_ReceiveData(LT8900SPI);Q5:使⽤HSE时,有效采样数的区别:A5:
[cpp]view plain copy
1.ST
2.#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE startup */3.GD130:
4.#define HSE_STARTUP_TIMEOUT ((uint16_t)0x5000) /*!< Time out for HSE startup */
Q6:中断向量表区别,GD兼容051,但⼜涵盖M3的中断⼊⼝。另外051不⽀持⾃定义中断⼊⼝偏移地址。A6:
[cpp]view plain copy
1./* ⾃动重定位中断向量表 */
2./ NVIC_SetVectorTable(NVIC_VectTab_FLASH, (BaseOfROM - NVIC_VectTab_FLASH)); //CM0不⽀持该功能Q7:GPIO区别:
A7:虽然130为M3,但是GPIO部分与M0的寄存器结构完全⼀致。Q8:Flash区别:
A8:虽然130为M3,但是Flash部分与M0结构⼤概相同,包含对OB区域的读写与读保护等级,多了⼀个烧断功能,此时不能还原为保护或⽆保护状态。加读保护功能与M0⼀致,在使⽤JLink Flash中使⽤去除读保护是,device必须选择STM32F101系列,否则去除保护功能⽆效。但有部分寄存器位有所不同,如:[cpp]view plain copy
1.FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; //M3不⽀持该设置Q9:RCC区别:
A9:M0中只有APB总线给外设提供CLK,但是M3中分了两组不同的CLK对应不同的外设,分别为APB1,APB2。如下:M0:
[cpp]view plain copy
1. uint32_t SYSCLK_Frequency;2. uint32_t HCLK_Frequency;3. uint32_t PCLK_Frequency;
4. uint32_t ADCCLK_Frequency;/* PCLK = HCLK */5.
[cpp]view plain copy
1.RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;GD130:
[cpp]view plain copy
1. uint32_t SYSCLK_Frequency; /*!< returns SYSCLK clock frequency expressedin Hz */
2. uint32_t HCLK_Frequency; /*!< returns HCLK clock frequency expressed inHz */
3. uint32_t PCLK1_Frequency; /*!< returns PCLK1 clock frequency expressed in Hz */
4. uint32_t PCLK2_Frequency; /*!< returns PCLK2 clock frequency expressed in Hz */
5. uint32_t ADCCLK_Frequency; /*!< returns ADCCLK clock frequency expressedin Hz [cpp]view plain copy
1.2.
[cpp]view plain copy
1./* PCLK2 = HCLK */
2. RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;3./* PCLK1 = HCLK */
4. RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;Q10:ID读取位置:
Flashsize位置不同,130与M3⼀致,但UID却与M0⼀致。如:M0:[cpp]view plain copy
1.#define rFlashSizeReg (*((uint16_t *)(0x1ffff7cc)))2.#define Stm32_UIDBase (uint8_t *)(0x1ffff7ac)GD130:
[cpp]view plain copy
1.#define rFlashSizeReg (*((uint16_t *)(0x1ffff7e0)))2.#define Stm32_UIDBase (uint8_t *)(0x1ffff7ac)Q11:电源特性区别:A11:
(1)⼯作电压2.6-3.6V,待机时电流为250uA;;
(2)由于mcu启动功耗⼤于st,因此mcu稳压电容验证将1uF改为47uF,解决上电瞬间电流过⼤,电源特性不稳定,电压输出被拉低⾄2V被强制关机问题;如下图:
(1)进⼊stopmode休眠后,sensorpwr关闭,中断唤醒后启动,下图为电源端与sensorpwr端电压图形。GD32端稳压电容为1uF。同样由于上电瞬间电压不稳导致⽆法启动芯⽚,区别图(3)。
sensorpwr端电压图形。STM32端稳压电容为1uF。
正常启动,但是睡眠后唤醒会出现电压过低关机的现象。
sensorpwr端电压图形。GD32端稳压电容为47uF,Sensor端为1uF电容。
综上,由于GD32启动电压较ST⾼0.6V,导致开机或休眠被唤醒瞬间电压不稳导致关机,图中多次启动是因为按键开关抖动导致多次触发。(5)待机功耗,如图:
因篇幅问题不能全部显示,请点此查看更多更全内容