初始化引脚
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_CS_CLK|SPI_SCK_CLK|SPI_MOSI_CLK|SPI_MISO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = SPI_CS_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_CS_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = SPI_SCK_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_SCK_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = SPI_MOSI_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_MOSI_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = SPI_MISO_Pin;
GPIO_Init(SPI_MISO_PORT,&GPIO_InitStructure);
定义操作宏
#define SPI_CS_CLK RCC_APB2Periph_GPIOA
#define SPI_CS_Pin GPIO_Pin_4
#define SPI_CS_PORT GPIOA
#define SPI_SCK_CLK RCC_APB2Periph_GPIOA
#define SPI_SCK_Pin GPIO_Pin_5
#define SPI_SCK_PORT GPIOA
#define SPI_MOSI_CLK RCC_APB2Periph_GPIOA
#define SPI_MOSI_Pin GPIO_Pin_7
#define SPI_MOSI_PORT GPIOA
#define SPI_MISO_CLK RCC_APB2Periph_GPIOA
#define SPI_MISO_Pin GPIO_Pin_6
#define SPI_MISO_PORT GPIOA
#define SPI_CS_0() GPIO_ResetBits(SPI_CS_PORT,SPI_CS_Pin)
#define SPI_CS_1() GPIO_SetBits(SPI_CS_PORT,SPI_CS_Pin)
#define SPI_SCK_0() GPIO_ResetBits(SPI_SCK_PORT,SPI_SCK_Pin)
#define SPI_SCK_1() GPIO_SetBits(SPI_SCK_PORT,SPI_SCK_Pin)
#define SPI_MOSI_0() GPIO_ResetBits(SPI_MOSI_PORT,SPI_MOSI_Pin)
#define SPI_MOSI_1() GPIO_SetBits(SPI_MOSI_PORT,SPI_MOSI_Pin)
#define SPI_MISO() GPIO_ReadInputDataBit(SPI_MISO_PORT,SPI_MISO_Pin)
操作函数
u8 Software_SPI_Write_Read(u8 data)
{
u8 i;
u8 redata;
for(i=0;i<8;i++)
{
SPI_SCK_0();
//SysTick_Delay_Us(10);
delay_us(10);
if(data & 0x80)
{
SPI_MOSI_1();
}
else
{
SPI_MOSI_0();
}
data <<= 1;
SPI_SCK_1();
//SysTick_Delay_Us(10);
delay_us(10);
redata<<=1;
if(SPI_MISO())
{
redata++;
}
}
return redata;
}
spi有4种工作模式,上面只是其中一种,根据工作模式自己修改时序
工作方式1:
当CPHA=0、CPOL=0时SPI总线工作在方式1。MISO引脚上的数据在第一个SPSCK沿跳变之前已经上线了,而为了保证正确传输,MOSI引脚的MSB位必须与SPSCK的第一个边沿同步,在SPI传输过程中,首先将数据上线,然后在同步时钟信号的上升沿时,SPI的接收方捕捉位信号,在时钟信号的一个周期结束时(下降沿),下一位数据信号上线,再重复上述过程,直到一个字节的8位信号传输结束。
工作方式2:
当CPHA=0、CPOL=1时SPI总线工作在方式2。与前者唯一不同之处只是在同步时钟信号的下降沿时捕捉位信号,上升沿时下一位数据上线。
工作方式3:
当CPHA=1、CPOL=0时SPI总线工作在方式3。MISO引脚和MOSI引脚上的数据的MSB位必须与SPSCK的第一个边沿同步,在SPI传输过程中,在同步时钟信号周期开始时(上升沿)数据上线,然后在同步时钟信号的下降沿时,SPI的接收方捕捉位信号,在时钟信号的一个周期结束时(上升沿),下一位数据信号上线,再重复上述过程,直到一个字节的8位信号传输结束。
工作方式4:
当CPHA=1、CPOL=1时SPI总线工作在方式4。与前者唯一不同之处只是在同步时钟信号的上升沿时捕捉位信号,下降沿时下一位数据上线。