1. 前言
 
 对于使用微控制器进行产品开发的设计人员来说,因产品及功能升级,往往需要将一种微控制器替  
 
 
 换成另一种微控制器,在保留既有功能的情况下增加新功能。为了更快地推出新产品,设计人员经  
 
 
 常要将应用程序移植到新的微控制器。  
 
 
 本应用笔记旨在帮助您快速将应用程序从 STM32F10x  
 系列微控制器移植到  
 GD32E103  
 系列微控  
 
 
 制器 
 ( 
 基于  
 STM32F10x  
 标准库  
 V3.5.0) 
 。  
 
 
 GD32E103  
 和  
 STM32F10x  
 系列相比,考虑软硬件兼容性,从  
 Flash  
 和  
 SRAM  
 容量,包括外设  
 
 
 模块的增强性能上来看, 
 GD32E103  
 最接近  
 STM32F10x  
 互联性。  
 
 
 开始前您需要安装  
 GD32E103  
 关于  
 KEIL  
 或  
 IAR  
 的插件,在工程选项的器件条目中选 
 GD32E103  
 
 
 对应型号,添加  
 GD32E103  
 的  
 Flash  
 下载算法。  
 
 
 GD32E103  
 较  
 STM32F10x  
 具有以下优点:  
 
 
 1、更高的主频(120MHz VS 72MHz)  
 
 
 2、更高版本的内核(Cortex M4 VS M3)  
 
 
 3、更低的功耗(Run Mode 
 : 
 28.6mA@120MHz VS 50mA@72MHz 
 ; Sleep Mode: 
 20.8mA@120MHz VS 30mA@72MHz )  
 
 
 但需要注意的是, 
 GD32E103  
 较  
 STM32F10x  
 少了  
 SDIO  
 功能,如果用户使用到  
 SDIO  
 功能,从  
 
 
 STM32F10x  
 到  
 GD32E103  
 的移植,显然是不合适的。  
 
2. 引脚兼容性
 
 STM32F10x  
 与  
 GD32E103  
 在相同封装下是  
 Pin To Pin  
 兼容的。但由于外设功能上的细微差别,两 者引脚定义有少许不同,如表 1  
 所示。 
 注意: 
 STM32F10x  
 外设编号从  
 1  
 开始, 
 GD32E103  
 外设编 
 号从  
 0  
 开始 
 ,且命名有差异。  
 
 
 表  
 1 STM32F10x  
 系列和  
 GD32E103  
 系列引脚区别  
 
 
 
 
 
 
 
3. 内部资源兼容性
 
 下表给出了  
 STM32F10x  
 与  
 GD32E103  
 的资源对比总览 
 ( 
 以  
 STM32F103V8 
 、 
 STM32F105V8  
 和  
 
 
 GD32E103V8  
 对比为例 
 ) 
 :  
 
 
 表  
 2 STM32F105  
 系列和  
 GD32E103  
 系列内部资源对比总览 
 
 
 
4. 程序移植
4.1 时钟移植
 
 GD32E103  
 时钟设置与  
 STM32F10x  
 互联系列兼容,如从  
 STM32F103  
 移植到  
 GD32E103 
 , 
 IDE  
 需 要做相关调整,具体过程如下:  
 
 
 (1)  
 使用  
 MDK  
 环境时:  
 
 
 在工程选项  
 C/C++ 
 选项卡中  
 Preprocessor Symbol Define  
 中加入  
 GD32F10X_CL  
 的宏定义;  
 
 
 在工程选项  
 Device  
 中选择原  
 MCU  
 对应的互联性型号,或对应的  
 GD32E103  
 型号。  
 
 
 (2)  
 使用  
 IAR  
 环境时:  
 
 
 在 工 程 选 项  
 C/C++ Compiler  
 项 中  
 Preprocessor  
 选项卡下  
 Define Symbol  
 中加入 GD32F10X_CL 的宏定义。 
 
 
  在工程选项  
  Device  
  中选择原  
  MCU  
  对应的互联性型号,或对应的  
  GD32E103  
  型号。  
 
 
 4.2 Flash 操作相关软件移植
4.2.1 FLash 编程操作
 
  STM32F10x  
  系列  
  MCU  
  仅支持  
  16  
  位半字编程,而  
  GD32E103  
  仅支持  
  32  
  位字和  
  64  
  位双字编程,  
 
 
  
  所以需要对  
  Flash  
  编程相关库函数进行更改。  
 
 
  
  (1) FLASH_ProgramWord  
  函数 
 
 
  
 
  
   说明:由原来的两次半字编程改为一次字编程。  
  
 
   
   (2) FLASH_EnableWriteProtection  
   函数 
  
 
   
 
   
    (3) FLASH_ProgramOptionByteData  
    函数  
   
 
    
 
     
     说明:由原来的半字编程改为字编程,用户需注意,选项字节需至少一次写一个字,且目标地址必须是  
     4  
     的整数倍。 
    
 
     
      (4) FLASH_EraseOptionBytes  
      函数 
     
 
      
 
     (5) FLASH_ReadOutProtection 函数

(6) FLASH_UserOptionByteConfig 函数

 
 注:以上代码中的  
 CR_OPTWRE_Set  
 的定义是  
 STM32  
 固件库中没有的,需要用户自行定义为:  
 
 
 #define CR_OPTWRE_Set  
 
 
 ((uint32_t)0x00000200)  
 
4.2.2 注意事项
 
 STM32F10x  
 的互联型和大容量型 
 ( 
 因为  
 GD32E103  
 没有大容量型,所以可不考虑 
 ) 
 的  
 Flash  
 闪存页  
 
 
 大小为  
 2K 
 ,而  
 GD32E103  
 为  
 1K 
 ,所以用户在调用页擦除时要注意页地址范围。  
 
5. 外设差异性
 
 STM32F10x  
 与  
 GD32E103  
 在外设上基本是兼容的,但  
 GD32E103  
 较  
 STM32F10x  
 在很多外设上  
 
 
 增加了部分功能,用户可根据以下罗列出的外设差异性选择是否使用这些功能。  
 
5.1 模数转换器 ADC
 
  为减轻  
  CPU  
  的负担, 
  GD32E103  
  较  
  STM32F10x  
  增加了片上硬件过采样单元。它能够处理多个转  
 
 
  
  换,并将多个转换的结果取平均,得出一个  
  16  
  位宽的数据。 片上硬件过采样单元是以降低数据  
 
 
  
  输出率为代价,换取较高的数据分辨率。 具体功能以及寄存器设置,请用户参考  
  GD32E10x  
  用户  
 
 
  
  手册。  
 
 
  
  另外,由于两款芯片的在  
  ADC  
  设计上的差异性,在移植到  
  GD32E103  
  时, 
  ADC  
  使能之后,校准  
 
 
  
  之前,需加入  
  1ms  
  的延时,以便  
  ADC  
  稳定后再进行校准。  
 
 
 5.2 通用同步异步收发器 USART
 
  GD32E103  
  较  
  STM32F10x  
  在  
  USART  
  上增加了块模式 
  (STM32F10x  
  只支持字节模式 
  ) 
  、数据极性  
 
 
  
  设置、数据位反转以及  
  TX 
  、 
  RX  
  引脚电平反转等功能,因此, 
  GD32E103  
  多了四个寄存器,分别  
 
 
  
  为: 
  USART_CTL3 
  、 
  USART_RT 
  、 
  USART_STAT1 
  、 
  USART_CHC 
  。具体功能以及寄存器设置,  
 
 
  
  请用户参考  
  GD32E10x  
  用户手册。  
 
 
 5.3 内部集成电路总线接口 I²C
 
  GD32E103 
  和 
  STM32F10x 
  的 
  I 
  ² 
  C 
  都支持标速 
  ( 
  最高 
  100KHz) 
  和快速 
  ( 
  最高 
  400KHz) 
  ,同时 
  GD32E103  
 
 
  
  可支持高速模式 
  ( 
  最高  
  1MHz) 
  ,要使能高速模式,需将  
  I2C_FMPCFG  
  寄存器的  
  FMPEN  
  置  
  1 
  。具  
 
 
  
  体功能以及寄存器设置,请用户参考  
  GD32E10x  
  用户手册。  
 
 
 5.4 串行外设接口/片上音频接口 SPI/I²S
 
  GD32E103  
  和  
  STM32F10x  
  的  
  SPI/I 
  ² 
  S  
  模块差异性主要表现在  
  GD32E103  
  支持  
  SPI TI  
  模式、 
  SPI  
 
 
  
  NSS  
  脉冲模式和  
  SPI  
  四线功能 
  ( 
  只有  
  SPI1) 
  ,其中  
  SPI  
  的四线模式是用于控制四线  
  SPI Flash  
  外设,此模式下,数据传输速率是普通模式下的 4  
  倍。具体功能以及寄存器设置,请用户参考 
  GD32E10x用户手册。  
 
 
 5.5 通用串行总线全速设备接口 USBFS
 
  GD32E103  
  和  
  STM32F105/107  
  的  
  USBFS  
  一致,同时  
  GD32E103  
  较  
  STM32F105/107  
  相比多了  
 
 
  
  IRC48M  
  的时钟源可选择。具体功能以及寄存器设置,请用户参考  
  GD32E103  
  用户手册。  
 
 
  
  GD32E103  
  和  
  STM32F103  
  的  
  USB  
  模块是不兼容的,如果用户是从  
  STM32F103  
  移植而来,需要  
 
 
  
  进行代码移植,具体请参考  
  STM32F103  
  与  
  STM32F105/107  
  的  
  USB  
  差异性。 
 
 
 6. 附录:
 
   (Flash  
   更改后的程序,用户可直接复制替换原库函数 
   )  
  
 
   
   --------------------------------------------------------------------------------------------------------------------------------- 
  
 
   
    0 
    、在  
    stm32f10x_flash.c  
    中添加 
   
 
   #define CR_OPTWRE_Set ((uint32_t)0x00000200) 
     --------------------------------------------------------------------------------------------------------------------------------- 
    
 
     
     1 
     、  
    
 
    FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
{
 FLASH_Status status = FLASH_COMPLETE;
 __IO uint32_t tmp = 0;
 /* Check the parameters */
 assert_param(IS_FLASH_ADDRESS(Address));
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 if(status == FLASH_COMPLETE)
 {
 FLASH->CR |= CR_PG_Set;
 *(__IO uint32_t*)Address = (uint32_t)Data;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 /* Disable the PG Bit */
 FLASH->CR &= CR_PG_Reset;
 } 
 /* Return the Program Status */
 return status;
}2、
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
{
 uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
 uint32_t temp1,temp2;
 FLASH_Status status = FLASH_COMPLETE; 
 /* Check the parameters */
 assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages));
 FLASH_Pages = (uint32_t)(~FLASH_Pages);
WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);
 WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);
 WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);
 WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24); 
 temp1 = (((uint32_t)WRP1_Data)<<16) | ((uint32_t)WRP0_Data);
 temp2 = (((uint32_t)WRP3_Data)<<16) | ((uint32_t)WRP2_Data);
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout); 
 if(status == FLASH_COMPLETE)
 {
 /* Authorizes the small information block programming */
 FLASH->OPTKEYR = FLASH_KEY1;
 FLASH->OPTKEYR = FLASH_KEY2;
 while((FLASH->CR&CR_OPTWRE_Set)!=CR_OPTWRE_Set )
 {}
 FLASH->CR |= CR_OPTPG_Set;
 if(temp1 != 0xFFFF)
 {
 //OB->WRP0 = temp1;
 *(__IO uint32_t*)0X1ffff808=temp1;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 }
 if((status == FLASH_COMPLETE) && (temp2 != 0xFFFF))
 {
 //OB->WRP1 = temp2;
 *(__IO uint32_t*)0X1ffff80c=temp2;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 }
 if(status != FLASH_TIMEOUT)
 {
 /* if the program operation is completed, disable the OPTPG Bit */
 FLASH->CR &= CR_OPTPG_Reset;
 }
 } 
 /* Return the write protection operation Status */
 return status; 
} 
      --------------------------------------------------------------------------------------------------------------------------------- 
     
 
      
      3、 
     
 
     FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint32_t Data)
{
 FLASH_Status status = FLASH_COMPLETE;
 /* Check the parameters */
 assert_param(IS_OB_DATA_ADDRESS(Address));
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 if(status == FLASH_COMPLETE)
 {
 /* Authorize the small information block programming */
 FLASH->OPTKEYR = FLASH_KEY1;
 FLASH->OPTKEYR = FLASH_KEY2;
 while((FLASH->CR&CR_OPTWRE_Set)!=CR_OPTWRE_Set )
 {}
 /* Enables the Option Bytes Programming operation */
 FLASH->CR |= CR_OPTPG_Set; 
 *(__IO uint32_t*)Address = Data;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 if(status != FLASH_TIMEOUT)
 {
 /* if the program operation is completed, disable the OPTPG Bit */
 FLASH->CR &= CR_OPTPG_Reset;
 }
 }
 /* Return the Option Byte Data Program Status */
 return status;
} 
       --------------------------------------------------------------------------------------------------------------------------------- 
      
 
      
        4、 
      
 
      FLASH_Status FLASH_EraseOptionBytes(void)
{
 uint16_t temp_spc = RDP_Key;
 uint32_t temp;
 FLASH_Status status = FLASH_COMPLETE;
 /* Get the actual read protection Option Byte value */ 
 if(FLASH_GetReadOutProtectionStatus() != RESET){
 temp_spc = 0xbb; 
 }
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(EraseTimeout);
 if(status == FLASH_COMPLETE){
 /* Authorize the small information block programming */
 FLASH->OPTKEYR = FLASH_KEY1;
 FLASH->OPTKEYR = FLASH_KEY2; 
 while((FLASH->CR&CR_OPTWRE_Set)!=CR_OPTWRE_Set ) {}
/* if the previous operation is completed, proceed to erase the option bytes */
 FLASH->CR |= CR_OPTER_Set;
 FLASH->CR |= CR_STRT_Set;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(EraseTimeout); 
 if(status == FLASH_COMPLETE)
 {
 /* if the erase operation is completed, disable the OPTER Bit */
 FLASH->CR &= CR_OPTER_Reset; 
 /* Enable the Option Bytes Programming operation */
 FLASH->CR |= CR_OPTPG_Set;
 /* Restore the last read protection Option Byte value */
 // OB->RDP = (uint16_t)rdptmp; 
 temp = ((uint32_t)temp_spc)|0xffff0000;
 *(__IO uint32_t*)0X1ffff800=temp;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout); 
 if(status != FLASH_TIMEOUT)
 {
 /* if the program operation is completed, disable the OPTPG Bit */
 FLASH->CR &= CR_OPTPG_Reset;
 }
 }
 else{
 if (status != FLASH_TIMEOUT){
 /* Disable the OPTPG Bit */
 FLASH->CR &= CR_OPTPG_Reset;
 }
 } 
 }
 /* Return the erase status */
 return status;
} 
        --------------------------------------------------------------------------------------------------------------------------------- 
       
 
        
        5、 
       
 
       FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)
{
uint16_t temp_spc; uint32_t temp;
 FLASH_Status status = FLASH_COMPLETE;
 /* Check the parameters */
 assert_param(IS_FUNCTIONAL_STATE(NewState));
 status = FLASH_WaitForLastOperation(EraseTimeout);
 if(status == FLASH_COMPLETE)
 {
 /* Authorizes the small information block programming */
 FLASH->OPTKEYR = FLASH_KEY1;
 FLASH->OPTKEYR = FLASH_KEY2;
 while((FLASH->CR&CR_OPTWRE_Set)!=CR_OPTWRE_Set )
 {}
 FLASH->CR |= CR_OPTER_Set;
 FLASH->CR |= CR_STRT_Set;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(EraseTimeout);
 if(status == FLASH_COMPLETE)
 {
 /* if the erase operation is completed, disable the OPTER Bit */
 FLASH->CR &= CR_OPTER_Reset;
 /* Enable the Option Bytes Programming operation */
 FLASH->CR |= CR_OPTPG_Set; 
 if(NewState != DISABLE){
temp_spc = 0xBB;
 temp = ((uint32_t)temp_spc)|0xffff0000;
 }
 else{
temp_spc = (uint16_t)RDP_Key;
 temp = ((uint32_t)temp_spc)|0xffff0000; 
 }
*(__IO uint32_t*)0x1ffff800=temp;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(EraseTimeout); 
 if(status != FLASH_TIMEOUT){
 FLASH->CR &= CR_OPTPG_Reset;
 }
 }
 else {
 if(status != FLASH_TIMEOUT){
 /* Disable the OPTER Bit */
 FLASH->CR &= CR_OPTER_Reset;
 }
 }
 }
 /* Return the protection operation Status */
 return status; 
} 
         ----------------------------------------------------------------------------------------------------------------------------- 
        
 
         
         6、 
        
 
        FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG,uint16_t OB_STOP, uint16_t OB_STDBY)
{
 FLASH_Status status = FLASH_COMPLETE; 
 uint16_t temp_spc = RDP_Key;
 uint32_t temp; 
/* Get the actual read protection Option Byte value */ 
 if(FLASH_GetReadOutProtectionStatus() != RESET)
 {
 temp_spc = 0xbb; 
 }
 /* Check the parameters */
 assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
 assert_param(IS_OB_STOP_SOURCE(OB_STOP));
 assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
 /* Authorize the small information block programming */
 FLASH->OPTKEYR = FLASH_KEY1;
 FLASH->OPTKEYR = FLASH_KEY2;
 while((FLASH->CR&CR_OPTWRE_Set)!=CR_OPTWRE_Set )
 {}
 /* if the previous operation is completed, proceed to erase the option bytes */
 FLASH->CR |= CR_OPTER_Set;
 FLASH->CR |= CR_STRT_Set;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 if(status == FLASH_COMPLETE)
 { 
/* if the erase operation is completed, disable the OPTER Bit */
 FLASH->CR &= CR_OPTER_Reset; 
 /* Enable the Option Bytes Programming operation */
 FLASH->CR |= CR_OPTPG_Set; 
 temp =OB_IWDG | (uint16_t)(OB_STOP | (uint16_t)(OB_STDBY | ((uint16_t)0xF8)));
temp=temp<<16;
 temp = ((uint32_t)temp|temp_spc); 
*(__IO uint32_t*)0x1ffff800=temp;
 /* Wait for last operation to be completed */
 status = FLASH_WaitForLastOperation(ProgramTimeout);
 if(status != FLASH_TIMEOUT)
 {
 /* if the program operation is completed, disable the OPTPG Bit */
 FLASH->CR &= CR_OPTPG_Reset;
 }
 } 
 /* Return the Option Byte program Status */
 return status;
}更多 GD32 MCU相关咨询: https://www.gd32bbs.com/




![【PWN · 栈迁移 | one-read】[羊城杯 2024]pstack](https://i-blog.csdnimg.cn/direct/9e2c9f9e81864b768c1e92284c336b22.png)














