STM32使用前的准备

对于要使用的每个STM32芯片,首先我们手上必备的两本手册(ST官网有pdf版):

  1. 参考手册(Reference manual)
  2. 数据手册(Datasheet)

其中参考手册包括各个功能模块的具体信息、原理、各种工作模式介绍、配置方法以及寄存器相关信息;数据手册包括芯片的基本参数、引脚数量与各自功能、电气特性、封装信息等内容。一般在选型与硬件设计阶段,参考数据手册多一些,而到了程序设计阶段,参考手册就是必须的了。

以下是STM32G4系列的参考手册的“自我介绍”:

This reference manual targets application developers. It provides complete information on how to use the STM32G4 Series microcontroller memory and peripherals.

本参考手册的目标是应用程序开发人员。 它提供了关于的完整信息如何使用STM32G4系列单片机的内存和外设。

SPI相关设置

我们以STM32G系列为例,直接翻到SPI章节,SPI结构示意图如下:

一共4个引脚可与外设连接:

  • MISO(Master In / Slave Out data:该引脚在从模式下发送数据,在主模式下接收数据
  • MOSI(Master Out / Slave In data):该引脚在主模式下发送数据,在从模式下接收数据
  • SCK(Serial Clock):主设备往从设备传输的时钟信号
  • NSS(Slave select):用于主设备选择从设备

单个主设备与单个从设备全双工通信模式示意图如下:

我们采用STM32CubeMX可以方便的完成基础配置,实际只需要编写如下实际通讯需要的代码

基础通讯代码

Tx:发送缓冲区;Rx:接收缓冲区;DR:数据寄存器

状态指示标志:

  • Tx buffer empty flag (TXE):发送缓冲区为空
  • Rx buffer not empty (RXNE):接收缓冲区非空
  • Busy flag (BSY):SPI数据正在传输中

基本工作原理:主机向从机发送一个值(指令),然后从机依据接收到的指令返回一个值

常见情况我们用STM32作为主机

  1. 等待TXE标志置1(Tx空),表明此时发送缓冲区Tx中无待发送的值
  2. 将数据写入SPIx_DR寄存器,对DR的写操作将把数据写入Tx末尾
  3. 等待BSY标志置0(即busy,置1表明Tx中的数据正在传输中)。期间数据通过MOSI发送给从机,从机返回的信息通过MISO回到主机接收缓冲区Rx
  4. 等待RXNE标志置1(Rx非空),表明此时Rx存在接收到的值
  5. 读取SPIx_DR寄存器,对DR的读操作将返回Rx中最早的值
// data_in:待发送的值
// data_out:接收到的值
static int spi_transmit_receive(uint16_t data_in, uint16_t *data_out){int state = 0;*data_out = 0;uint32_t timeout_cnt;static const uint32_t timeout_cnt_num = 10000;// Wait until TXE flag is set to send data timeout_cnt = 0;while(!LL_SPI_IsActiveFlag_TXE(SPI1)){timeout_cnt ++;if(timeout_cnt > timeout_cnt_num){state = -1;break;}}// Transmit data in 16 Bit modeLL_SPI_TransmitData16(SPI1, data_in);// Check BSY flag timeout_cnt = 0;while(LL_SPI_IsActiveFlag_BSY(SPI1)){timeout_cnt ++;if(timeout_cnt > timeout_cnt_num){state = -1;break;}}// Check RXNE flag timeout_cnt = 0;while(!LL_SPI_IsActiveFlag_RXNE(SPI1)){timeout_cnt ++;if(timeout_cnt > timeout_cnt_num){state = -1;break;}}// Read 16-Bits in the data register*data_out = LL_SPI_ReceiveData16(SPI1);return state;
}

所涉及的LL库相关函数:

/*** @brief  Write 16-Bits in the data register* @rmtoll DR           DR            LL_SPI_TransmitData16* @param  SPIx SPI Instance* @param  TxData Value between Min_Data=0x00 and Max_Data=0xFFFF* @retval None*/
__STATIC_INLINE void LL_SPI_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData)
{
#if defined (__GNUC__)__IO uint16_t *spidr = ((__IO uint16_t *)&SPIx->DR);*spidr = TxData;
#elseSPIx->DR = TxData;
#endif /* __GNUC__ */
}/*** @brief  Read 16-Bits in the data register* @rmtoll DR           DR            LL_SPI_ReceiveData16* @param  SPIx SPI Instance* @retval RxData Value between Min_Data=0x00 and Max_Data=0xFFFF*/
__STATIC_INLINE uint16_t LL_SPI_ReceiveData16(SPI_TypeDef *SPIx)
{return (uint16_t)(READ_REG(SPIx->DR));
}/*** @brief  Check if Tx buffer is empty* @rmtoll SR           TXE           LL_SPI_IsActiveFlag_TXE* @param  SPIx SPI Instance* @retval State of bit (1 or 0).*/
__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXE(SPI_TypeDef *SPIx)
{return ((READ_BIT(SPIx->SR, SPI_SR_TXE) == (SPI_SR_TXE)) ? 1UL : 0UL);
}/*** @brief  Get busy flag* @note   The BSY flag is cleared under any one of the following conditions:* -When the SPI is correctly disabled* -When a fault is detected in Master mode (MODF bit set to 1)* -In Master mode, when it finishes a data transmission and no new data is ready to be* sent* -In Slave mode, when the BSY flag is set to '0' for at least one SPI clock cycle between* each data transfer.* @rmtoll SR           BSY           LL_SPI_IsActiveFlag_BSY* @param  SPIx SPI Instance* @retval State of bit (1 or 0).*/
__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_BSY(SPI_TypeDef *SPIx)
{return ((READ_BIT(SPIx->SR, SPI_SR_BSY) == (SPI_SR_BSY)) ? 1UL : 0UL);
}/*** @brief  Check if Rx buffer is not empty* @rmtoll SR           RXNE          LL_SPI_IsActiveFlag_RXNE* @param  SPIx SPI Instance* @retval State of bit (1 or 0).*/
__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXNE(SPI_TypeDef *SPIx)
{return ((READ_BIT(SPIx->SR, SPI_SR_RXNE) == (SPI_SR_RXNE)) ? 1UL : 0UL);
}

实际使用spi_transmit_receive函数时,一般需要在函数前后设置以下片选NSS输出,通讯前选中当前从机,通讯后再关闭,防止多主机或者多从机模式时的冲突。

 // NSS片选引脚置0,开启当前主从关系LL_GPIO_ResetOutputPin(GPIOx, LL_GPIO_PIN_x);spi_transmit_receive(controlword, &recbuff);// NSS置1,关闭当前主从关系LL_GPIO_SetOutputPin(GPIOx, LL_GPIO_PIN_x);

STM32LL库使用——SPI通信相关推荐

  1. 学习笔记(1)stm32h743和ADXL355的SPI通信,基于cubeMX和keil5MDK平台,采用HAL库编程,代码已模块化处理

    今天是一个特别的日子,为什么呢?哈哈,因为从大四做毕业设计的时候,接触CSDN,到现在一整年了,终于创作了我的第一篇博客,内心难念有些激动! 首先声明,我不是嵌入式领域的技术大牛,只是普通的研一新生, ...

  2. STM32LL库系列教程【二】——点亮LED小灯

    开发板:秉火-霸道V1 芯片:STM32F103ZET6 GPIO: PB0 STM32LL库系列教程--LL库工程配置流程 STM32LL库系列教程[一]--安装CubeMx软件 STM32LL库系 ...

  3. TLE5012B ESP32驱动程序、硬件电路设计、4线SPI通信,驱动完美兼容4线SPI不用改MOSI开漏推挽输出

    一.TLE5012B 简介 TLE5012B 是一种款高分辨率旋转位置传感器,用于在整个 360 度范围内进行角度测量. 它通过使用单片集成 巨磁阻 (iGMR) 元件,来测量正弦和余弦角分量,这些原 ...

  4. STM8使用SPI通信需要注意的几个问题

    概述: 在使用STM8L101F3单片机,SPI通信读取三轴传感器ADXL362数据时,出现了一系列的问题,在这里做个笔记,也希望可以给大家一个小的参考. 问题一: 在SPI初始化过程中,没有初始化M ...

  5. 单片机:STM32F4x HAL库软硬SPI驱动ST7735s 1.8寸LCD屏幕

    单片机:STM32F4x HAL库软硬SPI驱动ST7735s 1.8寸LCD屏幕 说明:此篇为学习记录.可能存在错误或者不足.如有问题请指出. 硬件环境 主控芯片:STM32F411CEU6 主控开 ...

  6. STM32F103标准库开发---SPI实验---读写 W25Q128 外部 Flash

    STM32F103标准库开发----目录 W25Q128读写----程序源码----点击下载 W25Qxx全系列数据手册-点击下载 一.实验前期准备 本次实验的 MCU 是 STM32F103C8T6 ...

  7. STM32 SPI通信(读写flash)

    SPI通信 四线制 MISO:主设备数据输入,从设备数据输出 MOSI:主设备数据输出,从设备数据输入 SCLK:时钟信号 CS:片选引脚(低电平有效) 时序图 读写程序 flash读写函数: u8 ...

  8. android spi串口调试,PIC入门3,SPI通信和串口调试实验

    原标题:PIC入门3,SPI通信和串口调试实验 MSSP模块工作于SPI主控方式,这个可以直接在实验板上执行. 程序: //适合3EPIC实验板,配置PIC的MSSP模块工作于SPI主控方式下, // ...

  9. AS5047P磁编码器ESP32驱动程序、硬件电路设计、SPI通信时序、逻辑波形分析、注意事项

    1.AS5047P硬件设计 1.1 简介.性能参数 AS5047P 是一种款高分辨率旋转位置传感器,用于在整个 360 度范围内进行高速(高达 28krpm)角度测量.这种新型位置传感器配备了革命性的 ...

  10. SPI通信实验---verilog(FPGA作为从机,使用可读可写)

    文章原地址: http://www.cnblogs.com/fhyfhy/p/4429302.html SPI通信实验---verilog(FPGA作为从机,使用可读可写) 本实验讲究实用性,故设计思 ...

最新文章

  1. Serializer序列化使用
  2. 从大厂“出逃”,今天又有三位程序员联手敲钟:市值 40 亿
  3. Win 7 隐藏小功能——屏幕录制
  4. windows下cacti的快速安装
  5. python画直方图代码-用python绘制直方图
  6. mysql errmsg unknown_详解MySQL Server 启动时出现bug的解决方法
  7. java数组缓冲_java – 何时使用数组,缓冲区或直接缓冲区
  8. 测试计划(GB8567——88)
  9. 【java】错误 找不到或无法加载主类
  10. python中with as用法_python 中关于with...as的用法
  11. HDU 5512(博弈论)
  12. ESET NOD32 升级 激活码 用户名和密码~MF111
  13. 【ELAMN预测】基于遗传算法优化ELMAN神经网络实现电力符合数据回归预测附matlab代码
  14. php 限定字符长度,php-限制字符串长度
  15. Google kickstart 2013 Practice Round Captain Hammer 题解
  16. win10计算机升级系统,win10系统升级更新方法
  17. cnpm : 无法加载文件 C:\Users\小印丶\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。
  18. 关于Keil编译程序出现“File has been changed outside the editor,reload?”的解决方法
  19. C++ opencv之像素值统计(minMaxLoc,meanStdDev)
  20. 计算机网络 —— TCP的三次握手四次挥手

热门文章

  1. 老K仿真的惊人发现|社会的阶层分化过程
  2. Java中的parallelStream
  3. 现实世界的补丁长什么样? [ICSME 18] A Closer Look at Real-World Patches (结尾附论文阅读反思)
  4. 地图“四色定理”的公式推导
  5. 谱尼测试凭借现代化的测试平台
  6. Linux_Ubuntu快捷键截屏
  7. 安装pywifi的坑
  8. p2p终结者在交换机上的机器用P2P终结者
  9. QOS概述(一)服务模型
  10. 围棋规则 - AlphaGO