学习HAL库QSPI时对配置寄存器CPOL与CPHA的探究
学习STM32H7系列时对QSPI时对配置结构体中CLKPolarity = SPI_POLARITY_HIGH;的初始化参数的宏定义产生好奇,遂对HAL_SPI_Init()函数中的配置部分进行了深入一些的研究。
配置CPOL的宏定义在库文件中如下:
define SPI_POLARITY_LOW (0x00000000UL)
define SPI_POLARITY_HIGH SPI_CFG2_CPOL
我们都知道CPOL代表SPI通信过程中时钟空闲时的极性,CPOL=0代表空闲时为低电平,CPOL=1代表空闲时为高电平,那么SPI_POLARITY_HIGH为什么不干脆赋值0x00000001UL?
我们继续深入SPI_CFG2_CPOL,转到其定义位置发现三个相关的定义:
define SPI_CFG2_CPOL_Pos (25U)
define SPI_CFG2_CPOL_Msk (0x1UL << SPI_CFG2_CPOL_Pos) /*!< 0x02000000 */
define SPI_CFG2_CPOL SPI_CFG2_CPOL_Msk
SPI_CFG2_CPOL实际上是SPI_CFG2_CPOL_Msk的值,而SPI_CFG2_CPOL_Msk实际上是0x1UL向左偏移了25位,即SPI_POLARITY_HIGH值实际为0x02000000。
这是怎么回事?不应该CPOL=1才对吗,为什么赋值0x02000000,而且该值还是0x1左移后得到的值?
为了解答这个问题,我对HAL_SPI_Init()函数进行了一点研究,该函数中配置SPI的部分主要以下代码:
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef hspi)中配置SPI相关的部分如下:
对SPI配置寄存器1的配置,包括波特率、CRC计算使能、CRC帧长度、FIFO阈值级别、单个 SPI 数据帧的位数
/ SPIx CFG1 Configuration /
WRITE_REG(hspi->Instance->CFG1, (hspi->Init.BaudRatePrescaler | hspi->Init.CRCCalculation | crc_length |
hspi->Init.FifoThreshold | hspi->Init.DataSize));
对SPI配置寄存器2的配置包括片选模式、帧格式、SS输入/输出极性、NSS信号控制、CPOL、CPHA、数据传输首位、SPI工作模式、主模式数据间空闲时间、数据传输方向、主模式 SS 空闲时间、交换 MISO 和 MOSI 引脚
/ SPIx CFG2 Configuration */
WRITE_REG(hspi->Instance->CFG2, (hspi->Init.NSSPMode | hspi->Init.TIMode |
hspi->Init.NSSPolarity | hspi->Init.NSS |
hspi->Init.CLKPolarity | hspi->Init.CLKPhase |
hspi->Init.FirstBit | hspi->Init.Mode |
hspi->Init.MasterInterDataIdleness | hspi->Init.Direction |
hspi->Init.MasterSSIdleness | hspi->Init.IOSwap));
该配置函数为一个宏定义
define WRITE_REG(REG, VAL) ((REG) = (VAL))
很明显是将各配置值逻辑或的结果VAL赋给REG,也就是hspi->Instance->CFG1与hspi->Instance->CFG2,CFG1与CFG2有以下宏定义
__IO uint32_t CFG1; /*!< SPI Configuration register 1, Address offset: 0x08 /
__IO uint32_t CFG2; /!< SPI Configuration register 2, Address offset: 0x0C */
该宏定义可在参考手册中查到解释
SPI 配置寄存器 1 (SPI_CFG1)偏移地址0x08
SPI 配置寄存器 2 (SPI_CFG2)偏移地址0x0C
因此很明显,上文中的两个 WRITE_REG()函数,将我们配置好的SPI参数逻辑或合成一个32位数后赋给了相应的SPI配置寄存器,而SPI_POLARITY_HIGH赋值0x02000000也呼之欲出:
CPOL位在SPI控制寄存器2的第25位
所以才赋值0x1<<25。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)