hk32(航顺)标准库使用spi3复用功能的问题

简介: hk32(航顺)标准库使用spi3复用功能的问题

前言:

今天给大家介绍一下自己在使用航顺32芯片中遇到的一些问题。我用的是航顺的HK32f103VET6的一颗芯片,其中使用其中SPI3外设复用功能时,发现对应官方库的宏定义有些错误。遂给大家分享一下使用修改过程。

顺带给大家介绍一下航顺公司。4edc953e2c684bbe819ffa954c899c08.png

作者:良知犹存

转载授权以及围观:欢迎关注微信公众号:羽林君

或者添加作者个人微信:become_me


情节介绍:

我们使用MCU过程中会遇到一些IO外设进行复用 (为了优化64脚或100脚封装的外设数目,可以把一些复用功能重新映射到其他引脚上。设置复用重映射和调试I/O配置寄存器(AFIO_MAPR)实现引脚的重新映射。这时,复用功能不再映射到它们的原始分配上) 到非默认的引脚。

我在使用航顺芯片时候想把PD3、PD4、PD5、PD6使用为SPI引脚。4edc953e2c684bbe819ffa954c899c08.png

手册配置查询

经过查询对应的数据手册之后:(这是我查看手册对应的版本)

4edc953e2c684bbe819ffa954c899c08.png

可以看到 PD3、PD4、PD5、PD6可以复用为SPI3功能引脚

4edc953e2c684bbe819ffa954c899c08.png

一般我们都是看AFIO功能开发手册说明,看对应的IO的复用选项。

ST示例如下:

4edc953e2c684bbe819ffa954c899c08.png

航顺在开发手册中也有描述,但是没有描述SPI3复用选项4edc953e2c684bbe819ffa954c899c08.png

所以紧接着我又去查看航顺开发手册,看里面AFIO的寄存器详细描述:

其中SPI3归属在 航顺新增的AFIO_MAPR2 复用寄存器中:

4edc953e2c684bbe819ffa954c899c08.png

详细对应的关系可以看到, AFIO_MAPR2  是一个32位的寄存器,其中SPI3 在23位进行配置,其中我需要进行把 PD3、PD4、PD5、PD6可以复用为SPI3功能引脚,在此位进行设置,只需要 把此位设置1

4edc953e2c684bbe819ffa954c899c08.png

函数对应

我使用的航顺的V1.0.4库函数版本:

4edc953e2c684bbe819ffa954c899c08.png

使用复用功能 我需要用到 void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)  这个函数。

我使用

GPIO_PinRemapConfig(GPIO_Remap_SPI3,ENABLE);

发现该SPI功能无法实现。

所以我们需要更加深入的查看代码:

在官方提供的hk32f10x_gpio .c 文件中你可以看到函数原型:

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 参数有个掩码,最高位是1的情况下,配置 MAPR2寄存器,否则就去配置 MAPR寄存器。

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

通过IS_GPIO_REMAP

IS_GPIO_REMAP(GPIO_Remap)

我们可以看一下 对应的GPIO_Remap参数定义。4edc953e2c684bbe819ffa954c899c08.png

这样查看完,发现MAPR2寄存器对应的SPI3宏定义最高位是0,中间填充的数据也是有问题的。

因为我们需要调用GPIO_PinRemapConfig函数配置MAPR2寄存器的情况下,需要最高位是1

#define GPIO_Remap_SPI3             ((uint32_t)0x00201100)

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

这样我们使用 GPIO_PinRemapConfig(GPIO_Remap_SPI3,ENABLE); 复用配置SPI3就会失败

修改建议:

库函数出现问题,那我们就直接配置寄存器吧。4edc953e2c684bbe819ffa954c899c08.png

查看对应的SPI3_REMAP对应位,我们可以算出来32位为1对应的16进制值为 0x800000

4edc953e2c684bbe819ffa954c899c08.png

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;  //串行同步时钟的空闲状态为高电平
 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
 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; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
 SPI_Init(FLASH_SPI, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 SPI_Cmd(FLASH_SPI, ENABLE); //使能SPI外设
 FLASH_SPI_ReadWriteByte(0xff);//启动传输

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


结语

这就是我分享的项目中遇到一个HK官方库使用的问题,希望官方也可以查看一下,如果大家有更好的想法和需求,也欢迎大家加我好友交流分享哈。


作者:良知犹存,白天努力工作,晚上原创公号号主。公众号内容除了技术还有些人生感悟,一个认真输出内容的职场老司机,也是一个技术之外丰富生活的人,摄影、音乐 and 篮球。关注我,与我一起同行。

目录
相关文章
|
Linux 芯片
Linux内核学习(六):linux kernel的Kconfig分析
Linux内核学习(六):linux kernel的Kconfig分析
1252 0
|
传感器 调度 开发者
【Freertos基础入门】freertos任务的优先级
【Freertos基础入门】freertos任务的优先级
1844 0
|
12月前
|
搜索推荐 API 开发者
京东商品视频数据接口(JD.item_video)丨京东 API 接口指南
京东商品视频数据接口(JD.item_video)是京东开放平台提供的API,开发者可通过指定商品ID(num_iid)获取商品视频资源,用于丰富电商平台展示、提升用户体验。该接口适用于电商平台建设、商品推荐系统、市场研究与竞品分析及价格监测平台等场景,帮助用户更直观了解商品,提高购买转化率。示例代码展示了如何使用Python调用此接口并解析返回的JSON数据。
511 16
|
12月前
|
算法 Java 编译器
深入理解 Java JDK —— 让我们从基础到进阶
JDK(Java Development Kit)是 Java 开发的核心工具包,包含编译、运行和调试 Java 程序所需的所有工具和库。它主要由 JVM(Java 虚拟机)、JRE(Java 运行时环境)和 Java 核心类库组成。JVM 是跨平台运行的基础,负责字节码的加载、执行和内存管理;JRE 提供运行 Java 应用的环境;核心类库则提供了丰富的 API 支持。通过编写、编译和运行一个简单的 Java 程序,可以深入理解 JDK 的工作原理。此外,JDK 还提供了 JIT 编译、垃圾回收优化和并发工具包等高级功能,帮助开发者提高程序性能和稳定性。
1378 10
|
芯片
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
stm32f407探索者开发板(十二)——Systick滴答定时器-延时函数讲解
1532 0
|
机器学习/深度学习 计算机视觉
YOLOv8改进 | 卷积模块 | 用坐标卷积CoordConv替换Conv
💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡
|
编译器 调度
FreeRTOS任务的创建(动态方法和静态方法)
FreeRTOS任务的创建(动态方法和静态方法)
2747 0
|
测试技术 Linux Android开发
i2c总线及设备测试工具i2ctools:i2cdetect、i2cdump、i2cget、i2cset
本文介绍了i2ctools工具集的使用,包括i2cdetect、i2cdump、i2cget和i2cset,这些工具有助于I2C设备的开发和调试,通过检测设备、读写寄存器和数据块来提高开发效率。
3659 1
|
人工智能 开发者 芯片
【51单片机】单片机开发者的福音: 让AI看电路图帮你编写程序(使用ChatGPT 中训练好的单片机工程师模型)
使用AI大语言模型编写 单片机程序. 使用的是 OpenAI公司发布的 ChatGPT .在ChatGPT上有别人训练好的 单片机工程师 with Keil uVision 5 - C Code Explainer模型, 可以上传电路图改模型可以通过这个用户所给的电路图进行编程.
3504 0
【51单片机】单片机开发者的福音: 让AI看电路图帮你编写程序(使用ChatGPT 中训练好的单片机工程师模型)
USB Type-C引脚解析 && CC、DFP、UFP、DRP用途解析
USB Type-C引脚解析 && CC、DFP、UFP、DRP用途解析