GD32F103學(xué)習(xí)筆記(2)——在GD32F103移植STM32F103代碼

一、GD32與STM32區(qū)別

1.1 內(nèi)部結(jié)構(gòu)區(qū)別

1.1.1 內(nèi)核

GD32采用二代的M3內(nèi)核臼婆,STM32主要采用一代M3內(nèi)核抒痒,下圖是ARM公司的M3內(nèi)核勘誤表,GD使用的內(nèi)核只有752419這一個(gè)BUG颁褂。

1.1.2 主頻時(shí)鐘

  • 使用HSE(高速外部時(shí)鐘):GD32的主頻最大108M故响,STM32的主頻最大72M
  • 使用HSI(高速內(nèi)部時(shí)鐘):GD32的主頻最大108M,STM32的主頻最大64M

主頻大意味著單片機(jī)代碼運(yùn)行的速度會(huì)更快颁独,GD32的_NOP()時(shí)間比STM32更加短彩届,所以不使用定時(shí)器做延時(shí)時(shí)要注意修改,項(xiàng)目中如果需要進(jìn)行刷屏誓酒,開(kāi)方運(yùn)算惨缆,電機(jī)控制等操作,GD是一個(gè)不錯(cuò)的選擇丰捷。

1.1.3 啟動(dòng)時(shí)間

GD32啟動(dòng)時(shí)間相同坯墨,由于GD運(yùn)行稍快,需要延長(zhǎng)上電時(shí)間配置(2ms)病往。

1.1.4 時(shí)序要求

GD32對(duì)時(shí)序要求嚴(yán)格捣染,配置外設(shè)需要先打開(kāi)時(shí)鐘,否則可能導(dǎo)致外設(shè)無(wú)法配置成功停巷;STM32的可以先配置再開(kāi)時(shí)鐘耍攘。

1.1.5 供電

GD32F STM32F
外部電壓 2.6-3.6V 2.0-3.6V
內(nèi)核電壓 1.2V 1.8V
  • 外部供電:GD32外部供電范圍是2.6-3.6V,STM32外部供電范圍是2.0-3.6V畔勤。GD32的供電范圍比STM32相對(duì)要窄一點(diǎn)蕾各。
  • 內(nèi)核電壓:GD32內(nèi)核電壓是1.2V,STM32內(nèi)核電壓是1.8V庆揪。GD的內(nèi)核電壓比STM32的內(nèi)核電壓要低式曲,所以GD的芯片在運(yùn)行的時(shí)候運(yùn)行功耗更低

1.2 內(nèi)部FLASH區(qū)別

1.2.1 Flash擦除時(shí)間

GD32的Flash是自主研發(fā)的,和STM32的不一樣吝羞。

  • GD Flash執(zhí)行速度:GD32 Flash中程序執(zhí)行為0等待周期兰伤。

  • STM32 Flash執(zhí)行速度:ST系統(tǒng)頻率不訪(fǎng)問(wèn)Flash等待時(shí)間關(guān)系:0等待周期,當(dāng)0<SYSCLK<24MHz钧排,1等待周期敦腔,當(dāng)24MHz<SYSCLK≤48MHz,2等待周期恨溜,當(dāng)48MHz<SYSCLK≤72MHz符衔。

Flash擦除時(shí)間:GD32的Flash擦除時(shí)間要比STM32更長(zhǎng),官方給出的數(shù)據(jù)是這樣的:GD32F103/101系列Flash 128KB 及以下的型號(hào)糟袁, Page Erase 典型值100ms判族, 實(shí)際測(cè)量60ms左右。對(duì)應(yīng)的ST 產(chǎn)品Page Erase 典型值20~40ms系吭。

1.2.2 Flash和RAM容量

GD32的Flash最大有3M五嫂,STM32最大只有1M颗品。

1.3 功耗區(qū)別

功耗區(qū)別(以128k以下容量的作為參考)

模式 GD32F10x STM32F10x
睡眠模式 Sleep 12.4mA 7.5mA
深度睡眠模式 Deep Sleep 1.4mA 24uA
待機(jī)模式 Stand By 10.5uA 3.4uA
運(yùn)行功耗 32.4mA/72M 52mA/72M

功耗上GD32的靜態(tài)功耗要相對(duì)高一點(diǎn)肯尺。從上面的表可以看出GD的產(chǎn)品在相同主頻情況下,GD的運(yùn)行功耗比STM32小躯枢,但是在相同的設(shè)置下GD的停機(jī)模式则吟、待機(jī)模式、睡眠模式比STM32還是要高的锄蹂。

1.4 外圍硬件區(qū)別

1.4.1 串口

GD在連續(xù)發(fā)送數(shù)據(jù)的時(shí)候每?jī)蓚€(gè)字節(jié)之間會(huì)有一個(gè)Bit的Idle氓仲,而STM32沒(méi)有
GD32的串口在發(fā)送的時(shí)候停止位只有1/2兩種停止位模式得糜。STM32有0.5/1/1.5/2四種停止位模式敬扛。

1.4.2 ADC

GD32的輸入阻抗和采樣時(shí)間的設(shè)置和STM32有一定差異,相同配置GD采樣的輸入阻抗相對(duì)來(lái)說(shuō)要小朝抖。
具體情況見(jiàn)下表這是跑在72M的主頻下啥箭,ADC的采樣時(shí)鐘為14M的輸入阻抗和采樣周期的關(guān)系:

1.4.3 FSMC

STM32只有100Pin以上的大容量(256K及以上)才有FSMC,GD32所有的100Pin 或 100Pin以上的都有FSMC治宣。

1.4.4 SWD接口

GD32的SWD接口驅(qū)動(dòng)能力比STM32弱急侥,可以有如下幾種方式解決:

  1. 線(xiàn)盡可能短一些;
  2. 降低SWD通訊速率侮邀;
  3. SWDIO接10k上拉坏怪,SWCLK接10k下拉。

1.4.5 BOOT0管腳

GD32的BOOT0必須接10K下拉或接GND绊茧,STM32可懸空铝宵。

1.4.6 RC復(fù)位電路

RC復(fù)位電路必須要有,否則MCU可能不能正常工作华畏,STM32有時(shí)候可以不要捉超。

二胧卤、硬件替換需要注意的地方

從上面的介紹中,我們可以看出拼岳,GD32F103系列和STM32F103系列是兼容的枝誊,但也需要一些注意的地方。

  • BOOT0必須接10K下拉或接GND惜纸,ST可懸空叶撒,這點(diǎn)很重要。
  • RC復(fù)位電路必須要有耐版,否則MCU可能不能正常工作祠够,ST的有時(shí)候可以不要。
  • 有時(shí)候發(fā)現(xiàn)用仿真器連接不上粪牲。因?yàn)镚D的SWD接口驅(qū)動(dòng)能力比ST弱古瓤,可以有如下幾種方式解決:
    1. 線(xiàn)盡可能短一些;
    2. 降低SWD通訊速率腺阳;
    3. SWDIO接10k上拉落君,SWCLK接10k下拉。
  • 使用電池供電等亭引,注意GD的工作電壓绎速,例如跌落到2.0V~2.6V區(qū)間,ST還能工作焙蚓,GD可能無(wú)法啟動(dòng)或工作異常纹冤。
  • 在GD32F103小容量產(chǎn)品中使用有源晶振,發(fā)現(xiàn)會(huì)在MCU的復(fù)位管腳一直把電平拉到0.89V购公,電平不能保持在高電平萌京。是由于部分有源晶振起振時(shí)間太快,復(fù)位信號(hào)還沒(méi)有完成導(dǎo)致的宏浩。解決方法就是在有源晶振的輸入端與地之前并上一個(gè)30pF電容知残。

三、使用ST標(biāo)準(zhǔn)庫(kù)開(kāi)發(fā)需要修改的地方

3.1 時(shí)序要求

GD32對(duì)時(shí)序要求嚴(yán)格绘闷,配置外設(shè)需要先打開(kāi)時(shí)鐘橡庞,否則可能導(dǎo)致外設(shè)無(wú)法配置成功;STM32的可以先配置再開(kāi)時(shí)鐘印蔗。

3.2 修改外部晶振啟動(dòng)時(shí)間

不用外部晶振可跳過(guò)這步扒最。
由于GD與ST的啟動(dòng)時(shí)間存在差異,為了讓GD MCU更準(zhǔn)確復(fù)位华嘹,需要對(duì)下面參數(shù)進(jìn)行修改吧趣。

stm32f10x.h 頭文件中

將宏定義:
#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500)
修改為:
#define HSE_STARTUP_TIMEOUT ((uint16_t)0xFFFF)

3.3 修改主頻

3.3.1 以72MHz運(yùn)行

只需要修改上面提到的 HSE_STARTUP_TIMEOUT 把這個(gè)從 ((uint16_t)0x0500) 改為 ((uint16_t)0xFFFF)

3.3.2 以108MHz運(yùn)行

  1. 打開(kāi) system_stm32f10x.c,將原有的宏注釋掉,然后手動(dòng)添加新的108MHz的宏

代碼如下:

#define SYSCLK_FREQ_108MHz  108000000
  1. 因?yàn)楦牧撕昵看欤旅嫱ㄟ^(guò)宏來(lái)給 SystemCoreClock 賦值也要修改

代碼如下:

#elif defined SYSCLK_FREQ_108MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_108MHz;       /*!< System Clock Frequency (Core Clock) */
  1. 然后還要修改通過(guò)宏來(lái)選擇的函數(shù)岔霸,就是用來(lái)初始化系統(tǒng)時(shí)鐘配置的,最主要的函數(shù)(這個(gè)函數(shù)是本來(lái)沒(méi)有的俯渤,自己設(shè)置的)


代碼如下:

#elif defined SYSCLK_FREQ_108MHz
  static void SetSysClockTo108(void);
  1. 同理呆细,SetSysClock() 也要修改

代碼如下:

#elif defined SYSCLK_FREQ_108MHz
  SetSysClockTo108();
  1. 最后實(shí)現(xiàn)108MHz的函數(shù) SetSysClockTo108(),可以在文件最下面實(shí)現(xiàn)八匠,注釋掉上面一行的 #endif

代碼如下:

#elif defined SYSCLK_FREQ_108MHz
/**
  * @brief  使用內(nèi)部時(shí)鐘倍頻到108MHz 
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
#define  RCC_CFGR_PLLMULL27                 ((uint32_t)0x08280000)
static void SetSysClockTo108(void)
{
    /* Enable Prefetch Buffer */
    FLASH->ACR |= FLASH_ACR_PRFTBE;

    /* Flash 2 wait state */
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    

 
    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;


    /*  PLL configuration: PLLCLK = HSI * 27 = 108 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLMULL27);


    /* Enable PLL */
    RCC->CR |= RCC_CR_PLLON;

    /* Wait till PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }
    
    /* Select PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

    /* Wait till PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
}
#endif

還沒(méi)結(jié)束絮爷,這樣的話(huà)可以實(shí)現(xiàn)108MHz,但會(huì)有串口波特率錯(cuò)誤的BUG梨树,還需要以下修改坑夯。

3.4 修改RCC文件

時(shí)鐘改為108MHz后如果不修改RCC文件會(huì)導(dǎo)致串口不合適,需要修改 stm32f10x_rcc.c 文件抡四。具體不懂可以參考GD的手冊(cè)柜蜈。

打開(kāi) stm32f10x_rcc.c,找到 RCC_GetClocksFreq() 函數(shù)


增加一段這樣的代碼就可以了

代碼如下:

/**
  * @brief  Returns the frequencies of different on chip clocks.
  * @param  RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
  *         the clocks frequencies.
  * @note   The result of this function could be not correct when using 
  *         fractional value for HSE crystal.  
  * @retval None
  */
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
  uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;

#ifdef  STM32F10X_CL
  uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
  uint32_t prediv1factor = 0;
#endif
    
  /* Get SYSCLK source -------------------------------------------------------*/
  tmp = RCC->CFGR & CFGR_SWS_Mask;
  
  switch (tmp)
  {
    case 0x00:  /* HSI used as system clock */
      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
      break;
    case 0x04:  /* HSE used as system clock */
      RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
      break;
    case 0x08:  /* PLL used as system clock */

      /* Get PLL clock source and multiplication factor ----------------------*/
      pllmull = RCC->CFGR & CFGR_PLLMull_Mask;  //倍頻系數(shù) & 0x003C0000(取18~21)
      pllsource = RCC->CFGR & CFGR_PLLSRC_Mask; //時(shí)鐘源
      
#ifndef STM32F10X_CL      
      pllmull = ( pllmull >> 18) + 2;   //看手冊(cè)里面寄存器描述
    
      if (RCC->CFGR & 0x08000000)   //取27位
      {
          pllmull += 15;
      }
      
      if (pllsource == 0x00)
      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */
        RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
      }
      else
      {
 #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
       prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;
       /* HSE oscillator clock selected as PREDIV1 clock entry */
       RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull; 
 #else
        /* HSE selected as PLL clock entry */
        if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
        {/* HSE oscillator clock divided by 2 */
          RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;
        }
        else
        {
          RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;
        }
 #endif
      }
#else
      pllmull = pllmull >> 18;
      
      if (pllmull != 0x0D)
      {
         pllmull += 2;
      }
      else
      { /* PLL multiplication factor = PLL input clock * 6.5 */
        pllmull = 13 / 2; 
      }
            
      if (pllsource == 0x00)
      {/* HSI oscillator clock divided by 2 selected as PLL clock entry */
        RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
      }
      else
      {/* PREDIV1 selected as PLL clock entry */
        
        /* Get PREDIV1 clock source and division factor */
        prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC;
        prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;
        
        if (prediv1source == 0)
        { /* HSE oscillator clock selected as PREDIV1 clock entry */
          RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull;          
        }
        else
        {/* PLL2 clock selected as PREDIV1 clock entry */
          
          /* Get PREDIV2 division factor and PLL2 multiplication factor */
          prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1;
          pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2; 
          RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         
        }
      }
#endif /* STM32F10X_CL */ 
      break;

    default:
      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
      break;
  }

  /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
  /* Get HCLK prescaler */
  tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;
  tmp = tmp >> 4;
  presc = APBAHBPrescTable[tmp];
  /* HCLK clock frequency */
  RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
  /* Get PCLK1 prescaler */
  tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;
  tmp = tmp >> 8;
  presc = APBAHBPrescTable[tmp];
  /* PCLK1 clock frequency */
  RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
  /* Get PCLK2 prescaler */
  tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;
  tmp = tmp >> 11;
  presc = APBAHBPrescTable[tmp];
  /* PCLK2 clock frequency */
  RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
  /* Get ADCCLK prescaler */
  tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;
  tmp = tmp >> 14;
  presc = ADCPrescTable[tmp];
  /* ADCCLK clock frequency */
  RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
}

原因:

STM32時(shí)鐘配置寄存器

STM32的27位28位是保留的指巡,但是GD32的是用來(lái)配合PLL倍頻的淑履。

GD32時(shí)鐘配置寄存器

全局時(shí)鐘配置寄存器在GD中命名時(shí)RCC_GCFGR,在STM32中命名為RCC_CFGR厌处,關(guān)于PLL倍頻系數(shù)配置PLLMF不同鳖谈,紅框內(nèi)是先將HSE(8兆)分頻為2得到4兆岁疼,然后27倍頻得到108兆阔涉。



這時(shí)就得到了108兆的主頻時(shí)鐘
然后修改讀取時(shí)鐘的函數(shù)void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)



當(dāng)發(fā)現(xiàn)時(shí)RCC_CFGR第27位置位了,就將倍頻數(shù)從12+15 = 27捷绒。

3.5 修改代碼執(zhí)行速度

GD采用專(zhuān)利技術(shù)瑰排,提高了相同工作頻率下的代碼執(zhí)行速度,帶來(lái)了高性能的使用體驗(yàn)暖侨。這樣一些在ST下面編寫(xiě)的程序如 While或者是For循環(huán)的延時(shí)椭住, 移植到GD上面來(lái)肯定相應(yīng)的延時(shí)會(huì)變短使用Timer定時(shí)器無(wú)影響字逗。所以有用到這種延時(shí)方法的得根據(jù)實(shí)際情況進(jìn)行一定的調(diào)整京郑。GD的代碼執(zhí)行速度比ST更快,那么在應(yīng)用中如果有一些判斷的結(jié)構(gòu)不夠嚴(yán)謹(jǐn)也可能會(huì)導(dǎo)致問(wèn)題葫掉。

案例 1:
在軟件中編寫(xiě)了一個(gè)延時(shí)函數(shù)如下:

void delay(void) 
{ 
   uint8_t i; 
   for(i = 0; i < 75; i++); 
} 

通過(guò)實(shí)測(cè)相同的這一段代碼:
ST執(zhí)行該函數(shù)的延時(shí)時(shí)間是 7.4us
GD 執(zhí)行該函數(shù)的延時(shí)時(shí)間是 5.4us 些举。

案例 2:
采用 IO模擬 I2C 的查應(yīng)答函數(shù)的編寫(xiě)如下

#define SDA_Status() GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) 
void CheckACK(void) 
{ 
    cAcknowledge = true;
    if(SDA_Status()) 
    { 
        cAcknowledge = false; 
    } 
}

ST上面執(zhí)行OK ,但是在GD上面運(yùn)行不正常俭厚, 其實(shí)這是由于GD的執(zhí)行速度更快户魏,ACK信號(hào)還出來(lái),語(yǔ)句就已經(jīng)執(zhí)行完成了。建議修改代碼:

#define SDA_Status() GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) 
void CheckACK(void) 
{ 
    uint8_t ucErrTimer = 0; 
    cAcknowledge = true;
    while(SDA_Status()) 
    { 
        ucErrTime++; 
        if(ucErrTime>250) 
        { 
            cAcknowledge = false; 
        } 
    } 
}

3.6 Flash方面

由于 GD 的 Flash 是自己的專(zhuān)利技術(shù)叼丑,ST 的 Flash 是第三方提供的关翎,所以 GD 的 Flash 和 ST 的 Flash 有些許差異。GD32F10X Flash取值零等待鸠信,而 ST 需要 2 個(gè)等待周期纵寝,但 GD 的擦除和寫(xiě)入時(shí)間會(huì)長(zhǎng)一點(diǎn)。

3.6.1 設(shè)置讀保護(hù)用法

在代碼中設(shè)置讀保護(hù)星立,如果使用外部工具讀保護(hù)比如JFLASH或脫機(jī)燒錄器設(shè)置店雅,可跳過(guò)此步驟。
在寫(xiě)完key序列后贞铣,需要讀該位闹啦,確認(rèn)key已生效,修改如下:


總共需要修改如下四個(gè)函數(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)

3.6.2 修改擦出和寫(xiě)的超時(shí)宏定義

GD與ST在Flash的Erase和Program時(shí)間上有差異辕坝,修改如下:

3.6.3 修改分區(qū)

需求Flash大于256K注意窍奋,小于256K可以忽略這項(xiàng)。
與ST不同酱畅,GD的Flash存在分區(qū)的概念琳袄,前256K,CPU執(zhí)行指令零等待纺酸,稱(chēng)code區(qū)窖逗,此范圍外稱(chēng)為dataZ區(qū)。兩者在擦寫(xiě)操作上沒(méi)有區(qū)別餐蔬,但在讀操作時(shí)間上存在較大差別碎紊,code區(qū)代碼取值零等待,data區(qū)執(zhí)行代碼有較大延遲樊诺,代碼執(zhí)行效率比code區(qū)慢一個(gè)數(shù)量級(jí)仗考,因此data區(qū)通常不建議運(yùn)行對(duì)實(shí)時(shí)性要求高的代碼,為解決這個(gè)問(wèn)題词爬,可以使用分散加載的方法秃嗜,比如把初始化代碼,圖片代碼等放到data區(qū)顿膨。

3.7 ADC方面

  • ADC通道要配置成模擬輸入锅锨,芯片默認(rèn)是浮空輸入,如果不配成模擬輸入恋沃,ST的可以正常采集必搞,GD不行
  • ADC時(shí)鐘沒(méi)有手動(dòng)配置分頻最大運(yùn)行頻率14MHz以?xún)?nèi),ST可以正常采集芽唇,GD不行顾画。
    采樣周期配置如下:RCC_ADCCLKConfig(RCC_PCLK2_Divx);
  • ADC使能后需要加不少于20us延時(shí)取劫,for(i=0;i<0x1000;i++)。
  • 采樣精度不如STM32F103研侣,GD32F103存在這個(gè)問(wèn)題谱邪,如果對(duì)ADC精度要求不高可以選用,可以選用PIN TO PIN兼容F103系列的GD32E103和GD32F303系列解決庶诡。
  • ADC輸入阻抗和采樣周期選擇
    從ST 移植到 GD, 使用到 ADC 的話(huà)需要根據(jù)具體情況相應(yīng)的修改采樣周期惦银。具體參數(shù)見(jiàn)下表:


  • ADC_CR2中的ADON使用方法
    當(dāng)ADON=0 時(shí)寫(xiě)入 1后,需要等待一段時(shí)間 t_WAIT 末誓,才能進(jìn)行后續(xù)操作扯俱。
    t_WAIT 的計(jì)算公式如下: t_WAIT≥14×t_ADCClk。參見(jiàn) AN003 文檔 Section 2.2 喇澡。
    小容量的芯片需要注意這個(gè)問(wèn)題迅栅,大容量的這個(gè)問(wèn)題當(dāng)前已經(jīng)修改過(guò)。
  • ADC_SR中的EOC標(biāo)志位使用
    GD32F103/101 系列 Flash 128KB 及以下的型號(hào) ,在 ADC 的Regular group 或Injected group 轉(zhuǎn)換完成時(shí)晴玖,由硬件自動(dòng)置 1读存;由軟件寫(xiě)入 0 清除該位。參見(jiàn) AN003 文檔 Section 3 呕屎。
  • ADC采集三角波問(wèn)題
    ADC采集三角波會(huì)出現(xiàn)橫向偏移让簿,軟件上去除軟件校準(zhǔn), GD 出廠(chǎng)的時(shí)候已經(jīng)校準(zhǔn)過(guò)秀睛。

3.8 更多內(nèi)容

查看 GD32F103x-移植指南
百度網(wǎng)盤(pán):https://pan.baidu.com/s/1cFQoJXJMDpiAH-fwsEl4eg?pwd=8dng
提取碼:8dng
阿里云盤(pán):https://www.aliyundrive.com/s/r8g21zeL3Ua


? 由 Leung 寫(xiě)于 2022 年 4 月 8 日

? 參考:GD32和STM32的區(qū)別
    淺談GD32與STM32之間的區(qū)別
    GD32F103快速替換STM32F103
    在GD32F103移植STM32F103代碼
    使用STM32固件庫(kù)開(kāi)發(fā)GD32 匯總

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尔当,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蹂安,更是在濱河造成了極大的恐慌椭迎,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件藤抡,死亡現(xiàn)場(chǎng)離奇詭異侠碧,居然都是意外死亡抹估,警方通過(guò)查閱死者的電腦和手機(jī)缠黍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)药蜻,“玉大人瓷式,你說(shuō)我怎么就攤上這事∮镌螅” “怎么了贸典?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)踱卵。 經(jīng)常有香客問(wèn)我廊驼,道長(zhǎng)据过,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任妒挎,我火速辦了婚禮绳锅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酝掩。我一直安慰自己鳞芙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布期虾。 她就那樣靜靜地躺著原朝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪镶苞。 梳的紋絲不亂的頭發(fā)上喳坠,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音茂蚓,去河邊找鬼丙笋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛煌贴,可吹牛的內(nèi)容都是我干的御板。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼牛郑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼怠肋!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起淹朋,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤笙各,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后础芍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體杈抢,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年仑性,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惶楼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诊杆,死狀恐怖歼捐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晨汹,我是刑警寧澤豹储,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站淘这,受9級(jí)特大地震影響剥扣,放射性物質(zhì)發(fā)生泄漏巩剖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一钠怯、第九天 我趴在偏房一處隱蔽的房頂上張望球及。 院中可真熱鬧,春花似錦呻疹、人聲如沸吃引。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)镊尺。三九已至,卻和暖如春并思,著一層夾襖步出監(jiān)牢的瞬間庐氮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工宋彼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弄砍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓输涕,卻偏偏與公主長(zhǎng)得像音婶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子莱坎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350