STM32F10X系列 RT-Thread官方库 SPI2和SPI3 频率错误的原因和解决办法

本文主要是介绍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 频率错误的原因和解决办法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/631939

相关文章

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

Mybatis官方生成器的使用方式

《Mybatis官方生成器的使用方式》本文详细介绍了MyBatisGenerator(MBG)的使用方法,通过实际代码示例展示了如何配置Maven插件来自动化生成MyBatis项目所需的实体类、Map... 目录1. MyBATis Generator 简介2. MyBatis Generator 的功能3

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题

《解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题》本文主要讲述了在使用MyBatis和MyBatis-Plus时遇到的绑定异常... 目录myBATis-plus-boot-starpythonter与mybatis-spring-b

SpringBoot实现基于URL和IP的访问频率限制

《SpringBoot实现基于URL和IP的访问频率限制》在现代Web应用中,接口被恶意刷新或暴力请求是一种常见的攻击手段,为了保护系统资源,需要对接口的访问频率进行限制,下面我们就来看看如何使用... 目录1. 引言2. 项目依赖3. 配置 Redis4. 创建拦截器5. 注册拦截器6. 创建控制器8.

SQL Server数据库磁盘满了的解决办法

《SQLServer数据库磁盘满了的解决办法》系统再正常运行,我还在操作中,突然发现接口报错,后续所有接口都报错了,一查日志发现说是数据库磁盘满了,所以本文记录了SQLServer数据库磁盘满了的解... 目录问题解决方法删除数据库日志设置数据库日志大小问题今http://www.chinasem.cn天发

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

MySQL的索引失效的原因实例及解决方案

《MySQL的索引失效的原因实例及解决方案》这篇文章主要讨论了MySQL索引失效的常见原因及其解决方案,它涵盖了数据类型不匹配、隐式转换、函数或表达式、范围查询、LIKE查询、OR条件、全表扫描、索引... 目录1. 数据类型不匹配2. 隐式转换3. 函数或表达式4. 范围查询之后的列5. like 查询6

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.