hk32(航順)標準庫使用spi3復用功能的問題

2021/10/06
378
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

前言:

今天給大家介紹一下自己在使用航順32芯片中遇到的一些問題。我用的是航順的HK32f103VET6的一顆芯片,其中使用其中SPI3外設復用功能時,發(fā)現(xiàn)對應官方庫的宏定義有些錯誤。遂給大家分享一下使用修改過程。

順帶給大家介紹一下航順公司。

 

情節(jié)介紹:

我們使用MCU過程中會遇到一些IO外設進行復用 (為了優(yōu)化64腳或100腳封裝的外設數(shù)目,可以把一些復用功能重新映射到其他引腳上。設置復用重映射和調試I/O配置寄存器(AFIO_MAPR)實現(xiàn)引腳的重新映射。這時,復用功能不再映射到它們的原始分配上) 到非默認的引腳。

我在使用航順芯片時候想把PD3、PD4、PD5、PD6使用為SPI引腳。

 

手冊配置查詢

經(jīng)過查詢對應的數(shù)據(jù)手冊之后:(這是我查看手冊對應的版本)

 

可以看到 PD3、PD4、PD5、PD6可以復用為SPI3功能引腳

 

一般我們都是看AFIO功能開發(fā)手冊說明,看對應的IO的復用選項。

ST示例如下:

 

航順在開發(fā)手冊中也有描述,但是沒有描述SPI3復用選項

 

所以緊接著我又去查看航順開發(fā)手冊,看里面AFIO的寄存器詳細描述:

其中SPI3歸屬在 航順新增的AFIO_MAPR2 復用寄存器中:

 

詳細對應的關系可以看到, AFIO_MAPR2  是一個32位的寄存器,其中SPI3 在23位進行配置,其中我需要進行把 PD3、PD4、PD5、PD6可以復用為SPI3功能引腳,在此位進行設置,只需要 把此位設置 為 1 。

 

函數(shù)對應

我使用的航順的V1.0.4庫函數(shù)版本:

 

使用復用功能 我需要用到 void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)  這個函數(shù)。

我使用

GPIO_PinRemapConfig(GPIO_Remap_SPI3,ENABLE);

發(fā)現(xiàn)該SPI功能無法實現(xiàn)。

所以我們需要更加深入的查看代碼:

在官方提供的hk32f10x_gpio .c 文件中你可以看到函數(shù)原型:

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)
{
  uint32_t tmp = 0x00, tmp1 = 0x00, tmpreg = 0x00, tmpmask = 0x00;

  /* Check the parameters */
  assert_param(IS_GPIO_REMAP(GPIO_Remap));
  assert_param(IS_FUNCTIONAL_STATE(NewState));  
  
  if((GPIO_Remap & 0x80000000) == 0x80000000)
  {
    tmpreg = AFIO->MAPR2;
  }
  else
  {
    tmpreg = AFIO->MAPR;
  }

  tmpmask = (GPIO_Remap & DBGAFR_POSITION_MASK) >> 0x10;
  tmp = GPIO_Remap & LSB_MASK;

  if ((GPIO_Remap & (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) == (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK))
  {
    tmpreg &= DBGAFR_SWJCFG_MASK;
    AFIO->MAPR &= DBGAFR_SWJCFG_MASK;
  }
  else if ((GPIO_Remap & DBGAFR_NUMBITS_MASK) == DBGAFR_NUMBITS_MASK)
  {
    tmp1 = ((uint32_t)0x03) << tmpmask;
    tmpreg &= ~tmp1;
    tmpreg |= ~DBGAFR_SWJCFG_MASK;
  }
  else
  {
    tmpreg &= ~(tmp << ((GPIO_Remap >> 0x15)*0x10));
    tmpreg |= ~DBGAFR_SWJCFG_MASK;
  }

  if (NewState != DISABLE)
  {
    tmpreg |= (tmp << ((GPIO_Remap >> 0x15)*0x10));
  }

  if((GPIO_Remap & 0x80000000) == 0x80000000)
  {
    AFIO->MAPR2 = tmpreg;
  }
  else
  {
    AFIO->MAPR = tmpreg;
  }  
}

其中最重要對MAPR2 對應寄存器配置的是此處代碼:

if((GPIO_Remap & 0x80000000) == 0x80000000)
{
 AFIO->MAPR2 = tmpreg;
}
else
{
 AFIO->MAPR = tmpreg;
} 

GPIO_Remap 參數(shù)有個掩碼,最高位是1的情況下,配置 MAPR2寄存器,否則就去配置 MAPR寄存器。

而我們需要去操作MAPR2寄存器配置SPI3復用功能。

通過IS_GPIO_REMAP

IS_GPIO_REMAP(GPIO_Remap)

我們可以看一下 對應的GPIO_Remap參數(shù)定義。

 

這樣查看完,發(fā)現(xiàn)MAPR2寄存器對應的SPI3宏定義最高位是0,中間填充的數(shù)據(jù)也是有問題的。

因為我們需要調用GPIO_PinRemapConfig函數(shù)配置MAPR2寄存器的情況下,需要最高位是1

#define GPIO_Remap_SPI3             ((uint32_t)0x00201100)

而我們可以看到官方提供的hk32f10x_gpio .h文件中GPIO_Remap_SPI3的宏定義最高位不是1

這樣我們使用 GPIO_PinRemapConfig(GPIO_Remap_SPI3,ENABLE); 復用配置SPI3就會失敗

修改建議:

庫函數(shù)出現(xiàn)問題,那我們就直接配置寄存器吧。

 

查看對應的SPI3_REMAP對應位,我們可以算出來32位為1對應的16進制值為 0x800000

 

AFIO->MAPR2 |= 0x00800000;

最終代碼如下:

  GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;

 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE );
 RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI3,  ENABLE );
 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOB

  GPIO_SetBits(GPIOD,GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);  
  
  
// GPIO_PinRemapConfig(GPIO_Remap_SPI3,ENABLE);
 AFIO->MAPR2 |= 0x00800000;
 
 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  
 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  
 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  
 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  //串行同步時鐘的空閑狀態(tài)為高電平
 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步時鐘的第二個跳變沿(上升或下降)數(shù)據(jù)被采樣
 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  //NSS信號由硬件(NSS管腳)還是軟件(使用SSI位)管理:內部NSS信號有SSI位控制
 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;  //定義波特率預分頻的值:波特率預分頻值為256
 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定數(shù)據(jù)傳輸從MSB位還是LSB位開始:數(shù)據(jù)傳輸從MSB位開始
 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值計算的多項式
 SPI_Init(FLASH_SPI, &SPI_InitStructure);  //根據(jù)SPI_InitStruct中指定的參數(shù)初始化外設SPIx寄存器
 SPI_Cmd(FLASH_SPI, ENABLE); //使能SPI外設
 
 FLASH_SPI_ReadWriteByte(0xff);//啟動傳輸  
 

最后代碼可以正常的使用。

結語

這就是我分享的項目中遇到一個HK官方庫使用的問題,希望官方也可以查看一下,如果大家有更好的想法和需求,也歡迎大家加我好友交流分享哈。

作者:良知猶存
航順芯片

航順芯片

深圳市航順芯片技術研發(fā)有限公司做中國最大微處理器MCU/SOC原廠。2014年在科技之城深圳成立,專注科技攻關微處理器,存儲器。先后獲得深圳市高新技術企業(yè)及國家高新技術企業(yè)認證,連續(xù)多年獲評中國集成電路設計百強企業(yè),獲發(fā)明專利、軟件著作等幾十項知識產(chǎn)權,并于 2017年11月作為深圳龍華八大重點引進企業(yè)簽約入駐龍華智慧谷。 航順HK核心管理團隊來自國內外知名半導體公司,MCU/SOC研發(fā)核心成員均來自原日本富士通MCU團隊。

深圳市航順芯片技術研發(fā)有限公司做中國最大微處理器MCU/SOC原廠。2014年在科技之城深圳成立,專注科技攻關微處理器,存儲器。先后獲得深圳市高新技術企業(yè)及國家高新技術企業(yè)認證,連續(xù)多年獲評中國集成電路設計百強企業(yè),獲發(fā)明專利、軟件著作等幾十項知識產(chǎn)權,并于 2017年11月作為深圳龍華八大重點引進企業(yè)簽約入駐龍華智慧谷。 航順HK核心管理團隊來自國內外知名半導體公司,MCU/SOC研發(fā)核心成員均來自原日本富士通MCU團隊。收起

查看更多

相關推薦

登錄即可解鎖
  • 海量技術文章
  • 設計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

一個程序員,喜歡寫文章,還喜歡打籃球,也喜歡吉他鋼琴的駁雜之人。日常更新自己,分享包括但不限于C/C++、嵌入式、物聯(lián)網(wǎng)、Linux等編程學習筆記,同時,公眾號內包含大量的學習資源。歡迎關注,一同交流學習,共同進步!