STM32—cubeMX+HAL库的SPI接口使用

2023-05-16

摘要:

 本文主要介绍STM32的SPI接口、cubeMX软件配置SPI接口和分析SPI相关代码。

STM32之SPI简介:

(1)SPI协议【Serial Peripheral Interface】

   串行外围设备接口,是一种高速全双工的通信总线。主要用在MCU与FLASH\ADC\LCD等模块之间的通信。

 

(2)SPI信号线

       SPI 共包含 4 条总线。

SS(Slave Select):片选信号线,当有多个SPI 设备与 MCU 相连时,每个设备的这个片选信号线是与 MCU 单独的引脚相连的,而其他的 SCK、MOSI、MISO 线则为多个设备并联到相同的 SPI 总线上,低电平有效。

SCK (Serial Clock):时钟信号线,由主通信设备产生,不同的设备支持的时钟频率不一样,如 STM32 的 SPI 时钟频率最大为 f PCLK /2。

MOSI (Master Output Slave Input):主设备输出 / 从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入数据,即这条线上数据的方向为主机到从机。

MISO(Master Input Slave Output):主设备输入 / 从设备输出引脚。主机从这条信号线读入数据,从机的数据则由这条信号线输出,即在这条线上数据的方向为从机到主机。

下图是主器件与多个从器件通信图。其中SCKMOSIMISO是接在一起的,NSS分别接到不同的IO管脚控制。主器件要和从器件通信就先拉低对应从器件的NSS管脚使能。默认状态IO1,IO2,IO3全为高电平,当主器件和从器件1通信时,拉低IO1管脚使能从器件1。而从器件2,3不使能,不作响应。

(3)SPI特性

 

单次传输可选择为 8 或 16 位。

波特率预分频系数(最大为 fPCLK/2) 。

时钟极性(CPOL)和相位(CPHA)可编程设置。

数据顺序的传输顺序可进行编程选择,MSB 在前或 LSB 在前。

注:MSB(Most Significant Bit)最高有效位”,LSB(Least Significant Bit)是“最低有效位”。

可触发中断的专用发送和接收标志。

可以使用 DMA 进行数据传输操作。

   下图是STM32的SPI框架图。

如上图,MISO数据线接收到的信号经移位寄存器处理后把数据转移到接收缓冲区,然后这个数据就可以由我们的软件从接收缓冲区读出了。

当要发送数据时,我们把数据写入发送缓冲区,硬件将会把它用移位寄存器处理后输出到 MOSI数据线。

SCK 的时钟信号则由波特率发生器产生,我们可以通过波特率控制位(BR)来控制它输出的波特率。

控制寄存器 CR1掌管着主控制电路,STM32 SPI模块的协议设置(时钟极性、相位等)就是由它来制定的。而控制寄存器 CR2则用于设置各种中断使能。

最后为 NSS引脚,这个引脚扮演着 SPI协议中的SS片选信号线的角色,如果我们把 NSS引脚配置为硬件自动控制,SPI模块能够自动判别它能否成为 SPI的主机,或自动进入 SPI从机模式。但实际上我们用得更多的是由软件控制某些 GPIO引脚单独作为SS信号,这个 GPIO引脚可以随便选择。

(4)SPI时钟时序

 

根据时钟极性(CPOL)及相位(CPHA)不同,SPI有四种工作模式。

时钟极性(CPOL)定义了时钟空闲状态电平:

    CPOL=0为时钟空闲时为低电平

    CPOL=1为时钟空闲时为高电平

时钟相位(CPHA)定义数据的采集时间。

    CPHA=0:在时钟的第一个跳变沿(上升沿或下降沿)进行数据采样。

    CPHA=1:在时钟的第二个跳变沿(上升沿或下降沿)进行数据采样。

cubeMX软件配置SPI:

下面继续介绍cubeMX软件配置STM32L152的SPI接口方法。

(1)打开软件,选择对应芯片后,配置好时钟源;

(2)勾选SPI1为全双工,硬件NSS关闭,如下图:

(3)勾选好后,PA5、PA6、PA7如下图,在配置PA4为普通io口,gpio_output

(4)SPI1的参数配置选择默认,如下图所示

(5)生成代码,保存即可。

HAL库的SPI函数分析:

下面具体分析下生成的SPI函数和函数调用。

 

SPI_HandleTypeDef hspi1; //SPI结构体类定义,下面看其结构体内部的声明。

 

下面分析SPI的初始化函数:

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{


  GPIO_InitTypeDef GPIO_InitStruct;
  if(hspi->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspInit 0 */
  /* USER CODE END SPI1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_SPI1_CLK_ENABLE();//使能SPI1时钟
  
    /**SPI1 GPIO Configuration    
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);//配置SPI的数据线和时钟线
  /* USER CODE BEGIN SPI1_MspInit 1 */
  /* USER CODE END SPI1_MspInit 1 */
  }

static void MX_SPI1_Init(void)
{
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;//主模式
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;//全双工
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;//数据位为8位
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;//CPOL=0,low
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;//CPHA为数据线的第一个变化沿
  hspi1.Init.NSS = SPI_NSS_SOFT;//软件控制NSS
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;//2分频,32M/2=16MHz
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;//最高位先发送
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;//TIMODE模式关闭
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;//CRC关闭
  hspi1.Init.CRCPolynomial = 10;//默认值,无效
  if (HAL_SPI_Init(&hspi1) != HAL_OK)//初始化
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}



利用SPI接口发送和接收数据主要调用以下两个函数:

HAL_StatusTypeDef  HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//发送数据
HAL_StatusTypeDef  HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//接收数据

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32—cubeMX+HAL库的SPI接口使用 的相关文章

  • 139-基于stm32单片机老人居家监护报警系统Proteus仿真+源程序

    资料编号 139 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 MQ4传感器 电位器模拟 MQ2传感器 电位器模拟 蜂鸣器 电机 制作一个基于stm32单片机老人居家监护报警系统Proteus仿真 2 通过MQ2传
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • 137-基于stm32单片机智能保温杯控制装置Proteus仿真+源程序

    资料编号 137 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DS18B20传感器 电机 制作一个基于stm32单片机智能保温杯控制装置Proteus仿真 2 通过DS18b20传感器检测当前保温杯水的温度 并且
  • STM32F4 通过软复位跳转到引导加载程序,无需 BOOT0 和 BOOT1 引脚

    我问这个问题是因为可以在这里找到类似问题的答案 通过应用程序跳转到 STM32 中的引导加载程序 即从用户闪存在引导模式下使用引导 0 和引导 1 引脚 用户 JF002 JF002回答 当我想跳转到引导加载程序时 我在其中一个备份寄存器中
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • 硬件基础-电容

    电容 本质 电容两端电压不能激变 所以可以起到稳定电压作用 充放电 电容量的大小 想使电容容量大 使用介电常数高的介质 增大极板间的面积 减小极板间的距离 品牌 国外 村田 muRata 松下 PANASONIC 三星 SAMSUNG 太诱
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • STM32的HAL中实现单按、长按和双按功能

    我正在尝试实现单击 双击和长按功能来执行不同的功能 到目前为止 我已经理解了单击和长按的逻辑 但我不知道如何检测双击 至于代码 我使用计数器实现了单击和长按 但代码仅停留在第一个 if 条件上 bool single press false
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT
  • 在 ARM 处理器上执行存储在外部 SPI 闪存中的程序

    我有一个 ARM 处理器 能够与外部闪存芯片连接 写入芯片的是为 ARM 架构编译的程序 可供执行 我需要知道如何将这些数据从外部闪存获取到 ARM 处理器上以供执行 我可以提前运行某种复制例程 将数据复制到可执行内存空间吗 我想我可以 但
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re

随机推荐

  • win下使用Python获取串口列表

    背景 一个工具需要使用串口 可是计算机中有时候又不仅有一个串口接口 因此需要获取串口列表并且区分那个是串口接口 代码 span class token comment coding utf 8 span span class token k
  • Vim快捷键-键位图

    背景 嵌入式linux开发中 经常接触linux环境 最方便的莫过于使用vi 功能强大 适用范围广 因此了解一些vim中常见的命令对于日常工作学习大有裨益 针对于不同阶段 可以参考学习一下vim中的快捷键 提升工作效率 版本一 版本二 版本
  • P通道MOSFET简介

    A P Channel MOSFET is a type of MOSFET in which the channel of the MOSFET is composed of a majority of holes as current
  • Gcc编译优化等级介绍

    Gcc 编译优化简介 gcc 提供了为了满足用户不同程度的的优化需要 xff0c 提供了近百种优化选项 xff0c 用来对 编译时间 xff0c 目标文件长度 xff0c 执行效率 这个三维模型进行不同的取舍和平衡 优化的方法不一而足 xf
  • inline关键字的用法

    C代码可以在代码大小和执行时间两个方便优化 inline函数 gcc gnu org 这样描述 By declaring a function inline you can direct GCC to make calls to that
  • printf使用占位符控制输出格式

    printf 函数提供丰富的占位符参数以便精细地控制输出格式 xff0c 再进行字符操作的时候我们可能会使用到sprintf类函数进行处理 xff0c 因此这里对printf 函数的格式化输出控制进行较为 详细 讨论 简单的printf 语
  • 单片机main函数在中断函数里执行?

    引言 为什么复位中断服务程序里面直接调用的main函数 xff0c 难道所有程序都在复位中断里面执行的 xff1f 首先 xff0c Reset Handler 是单片机的一个中断 xff0c 其次 xff0c main 函数也确实被 Re
  • linux应用移植问题

    背景 公司设备降成本 xff0c 设备运行平台从armv7架构mpu换成了armv5架构的mpu xff0c 应用移植过程都挺顺利的 xff0c 只是牵涉到一个引用外部库的应用时 xff0c 运行该应用到引用库中的函数时 xff0c 应用抛
  • VSCode中格式化代码快捷键

    Shift 43 Alt 43 F
  • openwrt 时区设置无效问题

    最近在使用 openwrt 时发现在 web 控制台设置好时区后 xff0c 系统日志依然显示的是 UTC 时间 xff0c 慢了 8 小时 查了下原来是 openwrt 默认没有安装 zoneinfo xff0c 安装后即可 首先在 we
  • 修改weston桌面背景

    背景 linux开发板采用weston桌面系统 xff0c 希望修改默认桌面图片 xff1b 结果 在 etc xdg weston weston ini中新增 xff1a span class token punctuation span
  • 交叉编译构建GDB和GDBServer

    1 Problem statement I have a ARM GNU Linux board and I want to be able to debug programs running in it from the comfort
  • Linux获取库文件中的函数列表

    背景 函数库有些功能是可选的 xff0c 如果编译时没有开启特定选项 xff0c 编译生成函数库中就没有对应的接口函数 xff0c 一些依赖这些接口函数的应用执行时就会出现异常 xff0c 因此为了排查函数库是否包括特定函数 xff0c 我
  • 液晶屏接口介绍:8080接口详述,其他常用接口简介

    序言 本文的标题虽说是液晶屏的接口介绍 xff0c 但液晶屏的种类繁多 xff0c 种类大小尺寸不同 xff0c 液晶屏所用的接口也不同 恕本文实在无法把所有接口种类包含全面 比如说 xff0c 按尺寸大小来区分液晶屏的话 xff0c 有7
  • 移远EC20设置RNDIS模式拨号上网

    背景 4G模块原本使用QMI方式拨号上网 xff0c 客户反馈某种定制卡不能上网 xff0c 切换下拨号模式看下设备能不能正常上网 xff1b 过程 openwrt中如果使用RNDIS模式上网需要在kernel配置中使能以下项 xff1a
  • 波形分析--串口数据波形、DSRC 时间窗测量

    目录 串口数据波形TTL和RS232 485 DSRC 时间窗测量 串口数据波形 串口工具设置和发送的数据如下图所示 xff1a 串口数据波形如下 xff1a 起始位为1b的低电平 xff0c 如下图所示 xff1a 可以看到1b为8 68
  • C语言:结构体的空间分配和位定义

    目录 概述空间分配位定义 概述 本文收录结构体相关的知识点 xff0c 将遇到的相关问题和找到的解释说明集中在一起 xff0c 便于需要时快速查找 空间分配 请计算以下两个结构体所占用的空间大小 xff1a span class token
  • Android ndk开发C调用C++

    1 C 43 43 文件暴露给C的方法需要在前面加上 extern span class hljs string 34 C 34 span char getJsonStr span class hljs keyword span span
  • ROS智能车定位导航仿真(已实现)

    前提 xff1a 操作系统 xff1a ubuntu16 04 ROS版本 xff1a kinetic Gazebo版本 xff1a 7 0 0 参考 xff1a https blog csdn net lxzysx article det
  • STM32—cubeMX+HAL库的SPI接口使用

    摘要 xff1a 本文主要介绍STM32的SPI接口 cubeMX软件配置SPI接口和分析SPI相关代码 STM32之SPI简介 xff1a xff08 1 xff09 SPI协议 Serial Peripheral Interface 串