|
|
#include "MYSPI.h"
|
|
|
//SPI2初始化函数:配置成主机模式,访问W25Q128//
|
|
|
void SPI1_Init(void)
|
|
|
{
|
|
|
GPIO_InitTypeDef GPIO_InitStructure; //GPIO初始化结构体,选择SPI2,对应PB12,PB13,PB14,PB15//
|
|
|
SPI_InitTypeDef SPI_InitStructure; //SPI初始化结构体//
|
|
|
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); //GPIOB时钟使能//
|
|
|
RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE ); //SPI2时钟使能//
|
|
|
//初始化GPIOB,PB13/14/15都设置复用推挽输出,PB14对应MISO,最好设为带上拉输入//
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
|
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
|
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PB13/14/15置高电平//
|
|
|
//初始化SPI函数//
|
|
|
//设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工//
|
|
|
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
|
|
//针对SPI_CR1寄存器的SSI位和MSTR为,均设置1,即SPI工作模式为主SPI//
|
|
|
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
|
|
//针对SPI_CR1寄存器的DFF位,设置数据帧大小为8位//
|
|
|
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
|
|
//针对SPI_CR1寄存器的CPOL位,串行同步时钟的空闲状态为高电平//
|
|
|
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
|
|
|
//针对SPI_CR1寄存器的CPHA位,串行同步时钟的第二个跳变沿(上升沿)数据被采样//
|
|
|
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
|
|
|
//针对SPI_CR1寄存器的SSM位,NSS信号由软件(使用SSI位)管理//
|
|
|
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
|
|
//针对SPI_CR1寄存器的BR位,波特率预分频值为256//
|
|
|
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
|
|
|
//针对SPI_CR1寄存器的LSBFIRST位,数据传输从MSB位开始//
|
|
|
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
|
|
//针对SPI_CRCPR寄存器的CRCPOLY位,设为0x0007,为复位值//
|
|
|
SPI_InitStructure.SPI_CRCPolynomial = 7;
|
|
|
SPI_Init(SPI1, &SPI_InitStructure);
|
|
|
SPI_Cmd(SPI1, ENABLE); //使能SPI外设//
|
|
|
//启动传输,目的是让MOSI维持高。因为一般空闲状态电平都是高,这样不容易出问题//
|
|
|
SPI1_ReadWriteByte(0xff);
|
|
|
}
|
|
|
//SPI2速度设置函数//
|
|
|
void SPI1_SetSpeed(u16 SPI_BaudRatePrescaler)
|
|
|
{
|
|
|
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); //有效性判断//
|
|
|
SPI2->CR1&=0XFFC7; //先将SPI_CR1寄存器的BR位置000//
|
|
|
SPI2->CR1|=SPI_BaudRatePrescaler; //再设置SPI2速度//
|
|
|
SPI_Cmd(SPI1,ENABLE);
|
|
|
}
|
|
|
//u8 SPI2_ReadWriteByte(u8 TxData)读写一个字节函数,TxData:要写入的字节,返回值:读取到的字节//
|
|
|
u8 SPI1_ReadWriteByte(u16 TxData)
|
|
|
{
|
|
|
u8 retry=0;
|
|
|
//检查SPI_SR寄存器的TXE位(发送缓冲为空),其值0时为非空,1时为空//
|
|
|
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
|
|
|
{
|
|
|
retry++; //发送缓冲为空时,retry++//
|
|
|
if(retry>200)return 0;
|
|
|
}
|
|
|
SPI_I2S_SendData(SPI1, TxData); //通过外设SPI2发送一个数据//
|
|
|
retry=0;
|
|
|
//检查SPI_SR寄存器的RXNE位(接收缓冲为空),其值0时为空,1时为非空//
|
|
|
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
|
|
|
{
|
|
|
retry++; //当接收缓冲为非空时,retry++//
|
|
|
if(retry>200)return 0;
|
|
|
}
|
|
|
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据//
|
|
|
}
|
|
|
|