本文主要是介绍STM32F10X系列 RT-Thread官方库 SPI2和SPI3 频率错误的原因和解决办法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
STM32F10X SPI1挂接在ABP2时钟总线,SPI2和SPI3挂接在ABP1时钟总线。ABP1速率最大36M,ABP2速率最大72M。如下图所示。
SPI2和SPI3速率错误原因
RT-Thread基于芯片建立的工程,官方驱动库drv_spi.c中,stm32_spi_init()函数设置SPI速率部分程序如下所示。
uint32_t SPI_APB_CLOCK;#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)SPI_APB_CLOCK = HAL_RCC_GetPCLK1Freq();
#elif defined(SOC_SERIES_STM32H7)SPI_APB_CLOCK = HAL_RCC_GetSysClockFreq();
#elseSPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq();
#endifif (cfg->max_hz >= SPI_APB_CLOCK / 2){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;}else if (cfg->max_hz >= SPI_APB_CLOCK / 4){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;}else if (cfg->max_hz >= SPI_APB_CLOCK / 8){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;}else if (cfg->max_hz >= SPI_APB_CLOCK / 16){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;}else if (cfg->max_hz >= SPI_APB_CLOCK / 32){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;}else if (cfg->max_hz >= SPI_APB_CLOCK / 64){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;}else if (cfg->max_hz >= SPI_APB_CLOCK / 128){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;}else{/* min prescaler 256 */spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;}
也就是说RT-Thread官方库中并没有对STM32F10X的SPI1和SPI2,3作区分,统一用ABP2时钟频率做分频。这会导致SPI2和SPI3实际频率是设置频率的一半。
解决办法
在设置分频前判断一下当前是哪个SPI接口,并读取不同的时钟总线频率即可。修改后的stm32_spi_init()函数如下。只是增加了if判断。
uint32_t SPI_APB_CLOCK;#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)SPI_APB_CLOCK = HAL_RCC_GetPCLK1Freq();
#elif defined(SOC_SERIES_STM32H7)SPI_APB_CLOCK = HAL_RCC_GetSysClockFreq();
#elseif(spi_handle->Instance==SPI1)//增加对SPI接口号的判断{SPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq();}else{SPI_APB_CLOCK = HAL_RCC_GetPCLK1Freq();}
#endifif (cfg->max_hz >= SPI_APB_CLOCK / 2){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;}else if (cfg->max_hz >= SPI_APB_CLOCK / 4){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;}else if (cfg->max_hz >= SPI_APB_CLOCK / 8){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;}else if (cfg->max_hz >= SPI_APB_CLOCK / 16){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;}else if (cfg->max_hz >= SPI_APB_CLOCK / 32){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;}else if (cfg->max_hz >= SPI_APB_CLOCK / 64){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;}else if (cfg->max_hz >= SPI_APB_CLOCK / 128){spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;}else{/* min prescaler 256 */spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;}
这篇关于STM32F10X系列 RT-Thread官方库 SPI2和SPI3 频率错误的原因和解决办法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!