STM使用SPI协议通信-基础(标准库)

2023-10-26

SPI协议是摩托罗拉公司开发的协议,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,至少需要下列4根线:

(1)MISO– Master Input Slave Output,主设备数据输入,从设备数据输出;

(2)MOSI– Master Output Slave Input,主设备数据输出,从设备数据输入;

(3)SCLK – Serial Clock,时钟信号,由主设备产生;

(4)CS – Chip Select,从设备使能信号,由主设备控制。

SPI协议时序图

tips:不是每个器件的时序图都一样的,需要查看数据手册

使用STM32来做SPI协议可以通过IO模拟SPI和标准库SPI这两种方式实现SPI通信

IO模拟SPI

void SPI_Write(u8 Data)
{
   CS_CLR;  //拉低CS,SPI通信开始
   SPI_WriteData(Data);
   CS_SET;  //拉高CS,SPI通信结束
}

void  SPI_WriteData(u8 Data)
{
	unsigned char i=0;
	for(i=8;i>0;i--)
	{
		if(Data&0x80)
    {SDA_SET; //判断该位为1,输出高电平}
      else 
    {SDA_CLR;//判断该位为0,输出低电平}
	//需要根据器件的数据手册来决定时钟设置的先后顺序
      SCL_SET; //数据采样
      SCL_CLR; //数据输出
      
      Data<<=1; //数据左移一位,准备下一位数据的发送
	}
}

标准库SPI

void SPI_Init(void)
{

	GPIO_InitTypeDef  GPIO_InitStructure;
	SPI_InitTypeDef SPI1_InitStructure;
	      
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB ,ENABLE);
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_10| GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5| GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
	
	SPI1_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex; 
// 设置SPI 的通信方式
  SPI1_InitStructure.SPI_Mode=SPI_Mode_Master;
// 设置SPI 的主从模式
  SPI1_InitStructure.SPI_DataSize=SPI_DataSize_8b;
// 选择8 位还是16 位帧格式
  SPI1_InitStructure.SPI_CPOL=SPI_CPOL_High ;
// 设置时钟极性
  SPI1_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;
// 设置时钟相位
  SPI1_InitStructure.SPI_NSS=SPI_NSS_Soft;
//设置NSS 信号由硬件(NSS管脚)还是软件控制
  SPI1_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;
//设置SPI 波特率预分频值
  SPI1_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
//设置数据传输顺序是MSB 位在前还是LSB 位在前
  SPI1_InitStructure.SPI_CRCPolynomial=7;
//设置CRC 校验多项式,提高通信可靠性,大于1 即可
	SPI_Init( SPI1, &SPI1_InitStructure); 
//初始化SPI
	
	SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);
	SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
  SPI_Cmd( SPI1, ENABLE );//命令使能SPI
}

u8 SPI_ReadWriteData(u8 Data)
{

	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
	
  SPI_I2S_SendData(SPI1, Data);

  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);


  return SPI_I2S_ReceiveData(SPI1);
}

SPI1_InitStructure结构体按实际情况选择所需要的模式,值得注意的是SPI_CPOLSPI_CPHL

SPI_CPOL设置的是SCK时钟线空闲时是什么电平状态

SPI_CPHL设置的是SCK时钟线的第几个跳变沿采样数据

这两个设置需要认真看使用SPI协议模块的数据手册,设置不正确会导致写入代码不正确。

 

这是个大坑,坑了我一上午`(*>﹏<*)′)

(实在不想看可以4种情况都是一下,总有一个合适的( ̄︶ ̄)↗ )

(ST7735R显示芯片的时钟极性为高电平,时钟相位为第二个跳变沿)

发送及接收数据

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);检测发送缓冲区是否为空

为空时SPI_I2S_GetFlagStatus函数返回SET,结束循环,运行下一步发送数据(SPI_I2S_GetFlagStatus函数可以换成SPI_I2S_GetITStatus,效果相同)

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);检测接收缓冲区是否填满,填满时SPI_I2S_GetFlagStatus函数返回SET,结束循环,运行下一步接收数据

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

STM使用SPI协议通信-基础(标准库) 的相关文章

随机推荐

  • 51单片机智能蓝牙小车

    作为大一电子小趴菜 在和队友学习制作蓝牙小车过程中遇到了许多困难 本文既为大家避坑 也作为团队总结 这篇文章分为两部分 1 组装篇 2 代码篇 思维导图 组装篇 先准备好一块电源拓展板 用于为电机驱动模块和降压模块连接电源 小车底盘可淘宝定
  • element ui 表单验证触发方式:trigger: ‘change‘和trigger: ‘blur‘区别

    推荐阅读 Vue2 7正式发布 代号为 Naruto 火影忍者 原生支持 Composition API 终于可以在Vue2项目中使用Vue3的新特性了 真香 南北极之间的博客 CSDN博客今天 Vue 创始人尤雨溪刚刚正式发布了 Vue
  • HTML+CSS+JavaScript复习笔记持更(十)——CSS3常用属性之定位

    定位 定位主要是用来设定元素在页面上的位置的 其代码为 position 定位有三种定位方式 static 无特殊定位 按照dom排序 absolute 绝对定位 往前面找最近的 有定位属性的元素 以该元素的起点为起点 绝对定位 脱离文档流
  • JS中sort()方法原理及使用

    sort 方法用于对数组的元素进行排序 并返回数组 默认排序顺序是根据字符串UniCode码 因为排序是按照字符串UniCode码的顺序进行排序的 所以首先应该把数组元素都转化成字符串 如有必要 以便进行比较 语法 arrayObject
  • 计算机组成原理(1)-软件设计(二十二)

    程序设计语言 软件设计 二十一 https blog csdn net ke1ying article details 129344983 计算机组成原理在软件设计考试分值占比较高 主要会考 1 数据的表示 数据进制转化 日常生活中使用的都
  • MAC 下 OpenCV4 配置 VScode 失败 Xcode 成功记录(2021年12月)

    2022 1 22更新 VScode 设置成功 详情请见 https blog csdn net qq 42067550 article details 122634801 问题描述 安装好了 OpenCV 但是在 VScode 里面花了3
  • 线程的状态及阻塞

    之前提到了线程和进程 那就提一下线程的状态吧 线程状态通常分为五种 New 新建状态 创建线程对象 该线程的生命周期开始 此时该线程已经有了相应的内存空间和其他资源 Runnable 就绪状态 线程对象创建后 调用该线程的start 方法就
  • 去哪儿,模拟登录(扫码登录)

    声明 本文仅限交流学习使用 请勿使用在任何非法商业活动 禁止用于非法用途 否则后果自负 如有侵权 请告知删除 谢谢 一 去哪儿 出行类大厂 为了安全 查询很多信息需要身份校验 有多种登陆方式 1 1 如查询航班信息时 自动弹出登录窗口 会有
  • MySQL常用函数、关键词

    一 关键词 1 unsigned 非负数 定义非负 可以在定义主键的自增列时使用 column name int UNSIGNED AUTO INCREMENT 2 desc 降序 从大到小 asc 或 缺省 为升序 从小到大 和order
  • 微信小程序之地理位置授权 wx.getLocation

    1 授权地理位置 点击按钮 弹出授权弹窗 点击允许后 在以后的操作中可以随时获取到用户地理位置 点击拒绝后 将无法获取到地理位置 也无法再次点击弹出弹窗
  • TortoiseGit使用详解(1)

    一 版本回退和本地分支推送 1 版本回退 假如我们在develop分支上进行开发 当我们想要将代码回退到之前提交的某一版本时 使用TortoiseGit如何进行操作呢 1 第一步 进入工作空间 右键 TortoiseGit Show log
  • Spring知识点小结

    1 Spring是什么 Spring是一个轻量级的IoC和AOP容器框架 目的是用于简化企业应用程序的开发 它使得开发者只需要关心业务需求 常见的配置方式有三种 基于XML的配置 基于注解的配置 基于Java的配置 主要由以下几个模块组成
  • Jemdoc+Github.io +Mac搭建个人学术主页

    一直想做一个个人学术主页 试过Github Pages的各种模版 也用过知乎里一个高票答案Hugo 但总觉得不够简洁 直到遇到Jemdoc 顿觉这才是学术主页该有的样子 作为Web小白 Mac用户 结合网上搜到的零碎的答案 终于捣鼓成功 看
  • Matlab绘制直方图、概率密度函数、累积分布函数

    视频学习 https www bilibili com video BV1HK411T76d from search seid 16338053070486680597 spm id from 333 337 0 0 总结如下 绘制直方图
  • 人工智能数学基础--概率与统计7:学习中一些术语的称呼或表示变化说明以及独立事件的一些补充推论

    一 概念表示变化说明 笔者最开始学习概率论时 是以美版M R 斯皮格尔等著作的 概率与统计 作为教材学习 学习过程中发现部分内容理解困难 之所以这样 一是这本书的内容太古老 教材是2002年翻译出版的 二是部分内容翻译不是很好 后来感谢AI
  • 【C++OJ2】字符串的倒置 &排列子序列

    愿我们 都能成为可爱又有趣的大人呀 目录 每日总结 排序子序列 字符串的倒置 gt gt 1 每日总结 当一个类对象的生命周期结束后 关于调用析构函数 先调用派生类的析构函数 后调用基类的析构函数 关于一个类的静态成员描述 该类的静态成员变
  • org.springframework.boot.builder.SpringApplicationBuilder.([Ljava/lang/Class;)V

    拆分项目为微服务时候 然后启动报了上面的错误 经过查找资料是pom文件中引入的springboot版本兼容性导致的 进行修改pom文件 修改前 pom部分代码
  • 网络部分问题

    HTTP协议 端口80 工作在应用层 不安全 不需要加密不需要证书 URL以http开头 请求包 请求行 请求头标 空行 请求数据 请求行由 请求方法 请求的URL HTTP版本构成 请求方法 get post head put optio
  • Unity脚本中枚举类型在inspector面板中文显示

    效果 工具脚本 ChineseEnumTool cs using System using UnityEngine if UNITY EDITOR using UnityEditor using System Reflection usin
  • STM使用SPI协议通信-基础(标准库)

    SPI协议是摩托罗拉公司开发的协议 它以主从方式工作 这种模式通常有一个主设备和一个或多个从设备 至少需要下列4根线 1 MISO Master Input Slave Output 主设备数据输入 从设备数据输出 2 MOSI Maste