番外篇:STM32之GPIO口速率配置究竟代表什么

番外篇:STM32之GPIO口速率配置究竟代表什么

用过STM32的童鞋们都知道,STM32在GPIO配置时都需要选择一个GPIO速率,对于STM32F103系列芯片来说最快的配置应该是50Mhz左右(没记错的话)。那么这个50Mhz究竟代表了什么,我们今天详细探讨。
顺便的话就是测试一些常用硬件接口(硬件SPI为例)与软件模拟(软件SPI为例)的性能差别。(之前有老师说硬件spi和软件spi速度没什么区别,在此实践论证一下)。

先论证的芯片是STM32F103C8T6
首先是GPIO口配置,这里直接测试GPIOA的PA1:

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  /*Configure GPIO pins : PA0 PA1 PA2 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出
  GPIO_InitStruct.Pull = GPIO_NOPULL;//无上拉
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;//GPIO高速
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

上述配置是用STM32CUBEMX配置的,只能配置GPIO速率为GPIO_SPEED_FREQ_HIGH,其实应该就是和库函数配置的50Mhz差不多。

GPIO配置完成开始测试,先使用HAL库的GPIO操作代码:

  while (1)
  {
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
  }

毫无疑问,这里会产生一个方波,这个方波的频率就是使用HAL库操作时GPIO的最大速率。但结果强差人意:
在这里插入图片描述
图里可以清晰看到,使用HAL库操作GPIO也就1.6M左右的速率,和50M相差甚远。查阅一番资料后发现HAL库为了可读性增加了大量冗余,因此HAL代码运行效率不如直接操作寄存器,直接操作寄存器或使用汇编语言会增加运行效率。
下面搞起寄存器:
修改主函数代码如下:

  while (1)
  {
		GPIOA->ODR=1<<1;//PA1置1
		GPIOA->ODR=0<<1;//PA1置0
  }

这下在此用示波器观察波形:
在这里插入图片描述

可以发现,速率直接快了四五倍,到了8M左右,看来确实优化挺大,但还是和50M差距甚远。
但其实自己也知道,STM32F103的通用IO口能做到这个地步也几乎是极限了,即使使用汇编提升效果也有限。
但突然之前有老师说硬件spi和软件spi速度没什么区别,在此正好实践论证一下,看看硬件SPI的SCK引脚是输出频率最大能到多少。
使用STM32CUBEMX配置硬件spi,因为使用的是STM32F103C8并且系统频率为72M,所以SPI的时钟频率最大只能设置为18M。STM32CUBEMX配置硬件spi的图如下:
在这里插入图片描述
主循环里面代码也很简单,不停用SPI传输就行了:

  while (1)
  {
		HAL_SPI_Transmit(&hspi1,&test,1,1);
  }

好啊,下面来看看硬件SPI性能怎么样,下面是SPI的SCK的示波器观察图片:
在这里插入图片描述

大概18M左右,这比只有8M左右的GPIO速率快的多的多。因此硬件SPI的上限速率无疑比软件模拟SPI快不少。但即使这样,大多数传感器类的SPI通信器件支持的SPI时钟也大多在10M以下,只有一些FLASH等芯片(如W25Q128)会支持20M以上的SPI时钟。所以一般情况下软件SPI确实够用,虽然软件SPI用DMA比较麻烦。
再论证的芯片是STM32H743
H743是个极品,我的测试结果居然表明它的性能和F103的性能相差没有我想象的那么大。(没有打开mpu和cache等辅助)

先上时钟配置,时钟我直接拉到最大的480M。
在这里插入图片描述
然后就是配置GPIO,依旧是把PA1的性能拉满,代码如下:

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA1 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

这里速率是GPIO_SPEED_FREQ_VERY_HIGH,是所能配置的最快的了,应该50Mhz快不少,具体是多少没了解过,知道的可以评论区告诉我。
先试试HAL库操作:

  while (1)
  {
		
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
  }

下面放实际的IO口波形图:
在这里插入图片描述
大概2.39MHZ,比F103快了几乎一倍不到,但就这???毕竟主频快了6倍左右,APB时钟也快了近3倍,结果IO速率就快一倍也有点强差人意,不知道是不是有什么错误如果大家发现可以指正。

下面测试STM32H743直接寄存器操作IO口,代码依旧简单:

  while (1)
  {
		GPIOA->ODR=1<<1;
		GPIOA->ODR=0<<1;

  }

在这里插入图片描述
大概20M左右,比F103快了2倍多,也一般般。

下面测试一下这个24M的硬件SPI的SCK,配置如下。在这里插入图片描述
这个SPI时钟最高可以配置到96M,但是配置24M以上的波形几乎不能看,可能是手里H743板子设计有问题。
依旧是简单的代码:

while1{
		
	HAL_SPI_Transmit(&hspi1,&test,1,1);

  }

看下波形吧:在这里插入图片描述
就是24M,还挺准不错,就是波形比较差,可能是硬件设计问题。

STM32F103C8和STM32H743都测试结束,结果强差人意。

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怡步晓心l

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值