当前位置: 首页 > news >正文

26.STM32 SPI通信接口

1.SPI通信接口

一种全双工,同步的,一种通信接口。故至少有2根数据线,1根时钟线,但还有一根片选的线,主要应用在EEPPOM,FLASH,实时时钟,AD转换器等。
这里复习一下,IIC接口,同步半双工。
USART接口,异步全双工。

2.SPI接口原理

1.SPI框图
作为主机
MOSI接口为输出接口,地址和数据总线写入发送缓冲区,到移位寄存器,移出一位到MOSI,这时MISO接口就会输入一位数据到移位寄存器进行数据交互。
就是发送一个位时同时会接收一位
请添加图片描述
2.SPI框图
SPI接口一般使用4条线通信:
MISO 主设备数据输入,从设备数据输出。
MOSI 主设备数据输出,从设备数据输入。
SCLK时钟信号,由主设备产生。
CS从设备片选信号,由主设备控制。
从机主机都有一个移位寄存器,用于一位一位数据的移动与填入
请添加图片描述
3.SPI工作原理
1.硬件上为4根线。
2.主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。
3.串行移位寄存器通过MOSI信号线将字节传送给从机,从机也将自己的串行移位寄存器中的内容通过MISO信号线返回给主机。这样,两个移位寄存器中的内容就被交换。
4.外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输
4.从器件引脚管理
SPI可以一个主机接入多个从机,如何确定与那个设备通信,有硬件管理和软件管理
软件管理
从器件选择信息在内部将SPI_CR1寄存器的SSI为的值驱动。外部NSS引脚空闲,可供其它应用使用。
就是SPI寄存器可以控制SPI是否工作。
硬件管理
就是SPI有一根片选择的线,想用就拉低,禁止就拉高。
5.时钟信号的相位与极性
SPI_CR寄存器的CPOI与CPHA,能够有四种组合。
CPHA为1时,
CPOL为1下,空闲状态为高电平
CPOL为0下,空闲状态为低电平
第二个边沿被采集
CPHA为0时,
CPOL为1下,空闲状态为高电平
CPOL为0下,空闲状态为低电平
第一个边沿被采集
主机与从设备这两个参数要匹配
请添加图片描述
6.数据发送接收格式
输出数据位可以控制高位在前或低位在前,可以控制数据一帧为8位或16位
7.状态标志
发送缓冲器空闲标志TXE
为1时表示发送缓冲器为空,可以写入。写入后置0。
接收缓冲器非空RXNE
为1时表示接收缓冲有数据,可以读出来。读出后置0
忙标志Busy
标志现在是否在通信
8.SPI寄存器
SPI控制寄存器1(SPI_CR1)
SPI控制寄存器2(SPI_CR2)
SPI状态寄存器(SPI_SR)
SPI数据寄存器(SPI_DR)
SPI_I2S配置寄存器(SPI_I2S_CFGR)
SPI_I2S预分频寄存器(SPI_I2SPR)

3.SPI的HAL相关函数

1.初始化函数
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
SPI_HandleTypeDef *hspi,主要有用的为instan与Init初始化参数结构体
请添加图片描述请添加图片描述
2.SPI发送与接收函数
请添加图片描述
3.SPI中断函数
请添加图片描述
4.SPI设置速度函数(波特率)
请添加图片描述

4.SPI的HAL设置步骤

请添加图片描述

5.SPI的HAL库函数代码

#include"spi.h"
SPI_HandleTypeDef spi5;
void Spi_Init()
{
	spi5.Instance=SPI5;
	spi5.Init.Mode = SPI_MODE_MASTER;  //主模式
	spi5.Init.Direction = SPI_DIRECTION_2LINES;//发送与接收
	spi5.Init.DataSize = SPI_DATASIZE_8BIT;   //8位数据格式

	spi5.Init.CLKPolarity = SPI_POLARITY_HIGH;    //极性,空闲状态为高电平
	spi5.Init.CLKPhase = SPI_PHASE_2EDGE;			//两个跳变沿读取数据
	
	spi5.Init.NSS = SPI_NSS_SOFT;          //选择为软件管理
	spi5.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256;      //波特率预分频
	
	spi5.Init.FirstBit=SPI_FIRSTBIT_MSB;    //高位首位
	spi5.Init.TIMode=SPI_TIMODE_DISABLE;        //TIMode不开启
	spi5.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;;//关闭CRC校验                                 
	spi5.Init.CRCPolynomial=7;  //CRC值计算的多项式,多少无所谓,已经关闭了

	HAL_SPI_Init(&spi5);
	__HAL_SPI_ENABLE(&spi5);
	//SPI5_ReadWriteByte(0xff);
}
void SPI5_SetSpeed(u8 SPI_BaudRatePrescaler)
{
    assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性
    __HAL_SPI_DISABLE(&spi5);            //关闭SPI
		spi5.Instance->CR1&=0XFFC7;          //位3-5清零,用来设置波特率
    spi5.Instance->CR1|=SPI_BaudRatePrescaler;//设置SPI速度
    __HAL_SPI_ENABLE(&spi5);             //使能SPI
    
}

void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
	__HAL_RCC_GPIOF_CLK_ENABLE();   //时钟使能
	__HAL_RCC_SPI5_CLK_ENABLE();
	GPIO_InitTypeDef GPIO_Initure;
	if(hspi->Instance==SPI5)
	{
		
		GPIO_Initure.Pin=GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速
		GPIO_Initure.Alternate=GPIO_AF5_SPI5;	//复用为USART1
		HAL_GPIO_Init(GPIOF,&GPIO_Initure);	   	//初始化PA9
	}
			
}
u8 SPI5_ReadWriteByte(u8 TxDate)
{
	u8 RxDate;
	HAL_SPI_TransmitReceive(&spi5,&TxDate,&RxDate,sizeof(TxDate),1000);
	//发送TxDate,存在Rxdate
	return RxDate;
}

6.SPI的应用(W25QXX)

W25Q256是华邦公司生产的一颗容量为32M字节的串行FLASH芯片,它将32M的容量分为512个块(Block),每个块大小为64K字节,每个块又分为16个扇区(Sector),每个扇区4K个字节。W25Q256的最小擦除单位为一个扇区,也就是每次必须擦除4K个字节。这样我们需要给W25Q256开辟一个至少4K的缓存区,这样对SRAM要求比较高,要求芯片必须有4K以上SRAM才能很好的操作。
注:32M>分为16块>每块分为16个扇区(4K)
每次写入芯片时,先要根据地址找到扇区,然后将高扇区内容移到4k的缓存,才能写入数据,所以需要芯片有至少4k的缓存。

7.(W25QXX)引脚

8个引脚,输入输出引脚,片选,时钟,CVV,GND,
HOLD 保持断输入
WP 写保护
请添加图片描述

请添加图片描述

8.(W25QXX)指命

常用指命
请添加图片描述

相关文章:

  • [JS] node.js 入门
  • 卸载mysq并重新安装教程
  • 合并后 ETH 的供应变化以及是否会出现通缩
  • 装饰器模式【Java设计模式】
  • Qt 学习(四) —— qrc资源文件介绍与使用
  • 【云原生之Docker实战】使用Docker部署Alist网盘直链程序
  • 数据结构与算法——左程云05
  • STM32——2.4G无线通信实验
  • 【C语言数据结构】03.双链表
  • 非零基础自学Java (老师:韩顺平) 第23章 反射(reflection) 23.2 反射机制
  • (一)Java算法:二分查找
  • [前缀和]Tokitsukaze and Strange Inequality Codeforces1678C
  • Stl中map、set 容器(数据结构:AVL树、红黑树)--C++
  • Chapter20: Machine Learning for In Silico ADMET Prediction
  • Ubuntu下安装Miniconda
  • [译]如何构建服务器端web组件,为何要构建?
  • ➹使用webpack配置多页面应用(MPA)
  • FastReport在线报表设计器工作原理
  • Invalidate和postInvalidate的区别
  • isset在php5.6-和php7.0+的一些差异
  • Objective-C 中关联引用的概念
  • PAT A1120
  • php中curl和soap方式请求服务超时问题
  • SpingCloudBus整合RabbitMQ
  • Vue 2.3、2.4 知识点小结
  • 成为一名优秀的Developer的书单
  • 给Prometheus造假数据的方法
  • 关于extract.autodesk.io的一些说明
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 聚簇索引和非聚簇索引
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 小程序开发中的那些坑
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • #android不同版本废弃api,新api。
  • #define 用法
  • #define与typedef区别
  • #include到底该写在哪
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (007)XHTML文档之标题——h1~h6
  • (70min)字节暑假实习二面(已挂)
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (十一)c52学习之旅-动态数码管
  • (转)Linux下编译安装log4cxx
  • (转)我也是一只IT小小鸟
  • (转)用.Net的File控件上传文件的解决方案
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .net core 控制台应用程序读取配置文件app.config
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .NET轻量级ORM组件Dapper葵花宝典
  • .net项目IIS、VS 附加进程调试
  • .考试倒计时43天!来提分啦!