1、CC2530和STM32嵌入式接口技术开发6.3 STM32 SPI通信技术应用开发EducationSolutions目录ContentsInternet+SPI协议库函数的使用Flash芯片介绍项目实践23:55/3SPI总线介绍SPI协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD等设备与MCU间,要求通讯速率较高的场合。23:55/4SPI物理层 从设备选择信号线,常称为片选信号线。SS(Slave Select)时钟信号线,用于通讯数据同步。SCK(Serial
2、 Clock)主设备输出/从设备输入引脚。MOSI(Master Output,Slave Input)主设备输入/从设备输出引脚。MISO(Master Input,Slave Output)23:55/5SPI通讯流程在图中的标号1处,NSS信号线由高变低,是SPI通讯的起始信号。在图中的标号6处,NSS信号由低变高,是SPI通讯的停止信号。图中的2、3、4和5标号处,MOSI及MISO的数据在SCK的上升沿期间变化输出,在SCK的下降沿时被采样。即在SCK的下降沿时刻,MOSI及MISO的数据有效,高电平时表示数据“1”,为低电平时表示数据“0”。23:55/6SPI通讯模式(奇数边)奇
3、数边模式主要是时钟信号采样的位置在时钟信号的奇数边进行采集。23:55/7SPI通讯模式(偶数边)偶数边模式主要是时钟信号采样的位置在时钟信号的偶数边进行采集。23:55/8STM32的SPI硬件框架1.通讯引脚主要的引脚是MOSI、MISO、SCK、NSS。2.时钟控制逻辑通过时钟控制器控制SPI速率。3.数据控制逻辑此处控制数据的发送。4.整体控制逻辑对SPI的收发进行监控。23:55/9STM32的SPI通讯流程23:55/10STM32的SPI的配置流程 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);/使能SPI1时钟1.配置相关
4、引脚的复用功能,使能SPI1时钟 void SPI_Init(SPI_TypeDef*SPIx,SPI_InitTypeDef*SPI_InitStruct);2.初始化SPI1,设置SPI1工作模式等 SPI_Cmd(SPI1,ENABLE);/使能SPI1外设3.使能SPI1 void SPI_I2S_SendData(SPI_TypeDef*SPIx,uint16_t Data);uint16_t SPI_I2S_ReceiveData(SPI_TypeDef*SPIx);4.SPI传输数据 SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE);5.
5、查看SPI传输状态23:55/11SPI管脚的复用配置GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;/复用功能GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1);/PB3复用为SPI1GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1);/PB4复用为SPI1GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1);/PB5复用为SPI1SPI的MISO、MOSI和SCK引脚与GPIO引脚共用,要在GPI
6、O引脚上使用SPI的外设功能,需要使用GPIO引脚相关的复用功能,配置复用功能后就可以使用GPIO作为SPI总线的输入输出引脚了。23:55/12SPI的配置参数typedefstructuint16_t SPI_Direction;/SPI的通信方式配置参数uint16_t SPI_Mode;/SPI的主从模式配置参数uint16_t SPI_DataSize;/SPI的数据格式配置uint16_t SPI_CPOL;/SPI的时钟极性配置参数uint16_t SPI_CPHA;/SPI的时钟相位配置参数uint16_t SPI_NSS;/硬件NSS配置参数uint16_t SPI_Baud
7、RatePrescaler;/SPI的传输速率配置参数uint16_t SPI_FirstBit;/SPI的数据传输方配置参数uint16_t SPI_CRCPolynomial;/SPI的CRC校验模式SPI_InitTypeDef;SPI结构体中重点配置的几个参数有SPI的通信方式、主从模式、数据格式、传输速率和传输方向。23:55/13SPI的参数配置SPI_InitTypeDefSPI_InitStructure;/初始化SPI结构体SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;/配置全双工模式SPI_I
8、nitStructure.SPI_Mode=SPI_Mode_Master;/配置为主机模式SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;/配置数据位为8位SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;/配置时钟极性为高SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;/配置时钟相位为偶数位SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;/配置设备选择线为软件配置SPI_InitStructure.SPI_BaudRatePrescaler=SPI
9、_BaudRatePrescaler_256;/速度256分频SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;/配置高位在前数据发送SPI_InitStructure.SPI_CRCPolynomial=7;/配置CRC值计算的多项式SPI_Init(SPI2,&SPI_InitStructure);/使能SPISPI速率配置为256分频的时钟速率为45M/256=175.781KHz,45M的来源为APB2的时钟速率为45MHz。23:55/14Flash芯片介绍W25X64基本知识W25X64 系列 Flash 存储器与普通串行 FLASH
10、相比,使用更灵活,性能更出色。它非常适合应用,例如存储声音,文本和数据。W25X64有32768 可编程页,每页 256 字节。23:55/15W25X64功能引脚W25X16、W25X32 和 W25X64 支持标准的 SPI 接口,传输速率最大 75MHz。四线制:串行时钟引脚 CLK;芯片选择引脚 CS;串行数据输出引脚 DO;串行数据输入输出引脚 DIO。23:55/16项目场景系统生成的工作日志,电子设备中存储的字库,物联网安全系统中存储的动态密钥等都需要随时快速的存储和获取。而通常对这些数据存储的存储其为了兼顾大容量、节约硬件资源和低成本,往往使用SPI通信的高速flash。23:
11、55/17任务目标考勤机生产企业,要对原有产品进行升级,扩充设备存储容量,以实现更多功能与数据记录,要求使用STM32处理器的SPI接口去扩展 Flash芯片。23:55/18项目分析本项目设计采用STM32F407的SPI外设与W25Q64的Flash进行交互,程序主要注意两个方面,以方面是STM32F407的SPI的参数配置,另一方面是对Flash的读写操作,读写操作主要按照W25Q64 的控制寄存器来配置即可。STM32F407串口W25Q64Plus节点23:55/19项目硬件连接图W25Q64的Flash原理图23:55/20程序逻辑图23:55/21项目实现void SPI3_In
12、it(void)GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);/使能GPIOB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3,ENABLE);/使能SPI3时钟lSPI3初始化,配置成主机模式 23:55/22项目实现/GPIOB3,4,5初始化设置 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_4|GPI
13、O_Pin_5;/PB35复用功能输出 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;/复用功能 GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;/推挽输出 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;/100MHz GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;/上拉 GPIO_Init(GPIOB,&GPIO_InitStructure);/初始化 GPIO_PinAFConfig(GPIOB,GPIO_PinSource3
14、,GPIO_AF_SPI3);/PB3复用为 SPI3 GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI3);/PB4复用为 SPI3 GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI3);/PB5复用为 SPI3 lSPI3初始化,配置成主机模式23:55/23项目实现/这里只针对SPI口初始化 RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3,ENABLE);/复位SPI3 RCC_APB1PeriphResetCmd(RCC_APB1Periph_S
15、PI3,DISABLE);/停止复位SPI3 SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;/设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode=SPI_Mode_Master;/设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;/设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;/串行同步时
16、钟的空闲状态为高电平 SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;/串行同步时钟的第二个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;/NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;/定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_M
17、SB;/指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial=7;/CRC值计算的多项式 SPI_Init(SPI3,&SPI_InitStructure);/根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI3,ENABLE);/使能SPI外设 SPI3_ReadWriteByte(0 xff);/启动传输 lSPI3初始化,配置成主机模式23:55/24项目实现void SPI3_SetSpeed(u8 SPI_BaudRatePrescaler)assert_par
18、am(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler);/判断有效性 SPI3-CR1&=0XFFC7;/位3-5清零,用来设置波特率 SPI3-CR1|=SPI_BaudRatePrescaler;/设置SPI1速度 SPI_Cmd(SPI2,ENABLE);/使能SPI1lSPI3速度设置函数23:55/25项目实现u8 SPI3_ReadWriteByte(u8 TxData)while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE)=RESET)/等待发送区空 SPI_I2S_SendData(SPI3,TxData);/通过外设SPIx发送一个byte 数据 while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE)=RESET)/等待接收完一个byte return SPI_I2S_ReceiveData(SPI3);/返回通过SPIx最近接收的数据 lSPI3 读写一个字节23:55/26项目思考SPI总线有哪几根信号线组成,这些信号线的作用是什么?请列举几个使用SPI总线的设备。Flash存储器基本原理是什么?