1. 需要的资源
2. 基本知识点
- SPI是什么:SPI是Serial Peripheral Interface的缩写,串行外围设备接口。是一种告诉的,全双工,同步的通信总线。
- SPI接口四条通讯线:
- MISO 主设备数据输入,从设备数据输出。
- MOSI 主设备数据输出,从设备数据输入。
- SCLK 时钟信号,由主设备产生。
- CS 从设备片选信号。由主设备控制。
- 支持在同一个协议总线上,挂在一个主设备多个从设备。
- 外设的读操作和写操作是可以同时进行的,也可以分开。
- SPI四种工作模式:
- 时钟极性(CPOL),是指SPI通讯设备处于空闲状态时,SCK信号线的电平信号(即SPI通讯开始前,CS片选信号为高时,SCLK的状态)。CPOL=0,SCLK为低;CPOL=1,SCLK为高
- 时钟相位(CPHA),是指数据的采样的时刻,当CPHA=0时,数据线上的信号将会在SCK时钟线的“奇数边沿”被采样;当CPHA=1时,数据线上的信号将会在SCK时钟线的“偶数边沿”被采样
- CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,在第一个边沿(上升沿)读取数据,在第二个边沿(下降沿)发送数据。 注意:因为在第一个边沿就会读取数据,所以在第一个边沿到来之前就要把第一位数据输出出来并保持稳定。
- CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,在第一个边沿(下降沿)读取数据,在第二个边沿(上升沿)发送数据。 注意:因为在第一个边沿就会读取数据,所以在第一个边沿到来之前就要把第一位数据输出出来并保持稳定。
- CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,在第一个边沿(上升沿)发送数据,在第二个边沿(下降沿)读取数据。
- CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,在第一个边沿(下降沿)发送数据,在第二个边沿(上升沿)读取数据。
- 注意:数据的读取和发送时序并不是针对主设备或者从设备,而是同时进行的,就是说在主设备读取数据的同时,从设备也是出于读取设备的状态。
3. 定义结构体
typedef struct _SPI_CONFIG_t
{
unsigned int Delay;
unsigned char (*MISO_STA)(void); //获取MISO的IO状态
void (*MOSI_IO_HIGH)(void); //MOSI的IO设置成高
void (*MOSI_IO_LOW)(void); //MOSI的IO设置成低
void (*CS_IO_HIGH)(void); //CS的IO设置成高
void (*CS_IO_LOW)(void); //CS的IO设置成低
void (*CLK_IO_HIGH)(void); //CLK的IO设置成高
void (*CLK_IO_LOW)(void); //CLK的IO设置成低
}SPI_CONFIG_t;
4. 函数功能
void _SPI_Delay(unsigned int n)
{
unsigned int t;
t=n;
while(t--);
}
#if SPI_CPOL==0 && SPI_CPHA==0
/*
*********************************************************************************************************
* 函 数 名: CS_Enable
* 形 参: spi
* 返 回 值: 无
* 功能说明: 片选使能
*********************************************************************************************************
*/
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
/*
*********************************************************************************************************
* 函 数 名: CS_Disable
* 形 参: spi
* 返 回 值: 无
* 功能说明: 片选失能
*********************************************************************************************************
*/
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WriteByte
* 形 参: spi; dat:写入的数据
* 返 回 值: 无
* 功能说明: spi写入一个字节的时序
*********************************************************************************************************
*/
void SPI_WriteByte(SPI_CONFIG_t spi, unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
if(dat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
}
/*
*********************************************************************************************************
* 函 数 名: SPI_ReadByte
* 形 参: spi;
* 返 回 值: spi读一个字节
* 功能说明: spi读一个字节的时序
*********************************************************************************************************
*/
unsigned char SPI_ReadByte(SPI_CONFIG_t spi)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
dat<<=1;
if(spi.MISO_STA())
dat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
return dat;
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WRByte
* 形 参: spi; wdat:写入的数据
* 返 回 值: spi读一个字节
* 功能说明: spi同时读写一个字节的时序
*********************************************************************************************************
*/
unsigned char SPI_WRByte(SPI_CONFIG_t spi, unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
wdat<<=1;
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(spi.MISO_STA())
rdat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
return rdat;
}
#endif
#if SPI_CPOL==1 && SPI_CPHA==0
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
void SPI_WriteByte(SPI_CONFIG_t spi, unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
if(dat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_ReadByte(SPI_CONFIG_t spi)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
if(spi.MISO_STA())
dat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
return dat;
}
unsigned char SPI_WRByte(SPI_CONFIG_t spi, unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
wdat<<=1;
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(spi.MISO_STA())
rdat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
return rdat;
}
#endif
#if SPI_CPOL==0 && SPI_CPHA==1
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
void SPI_WriteByte(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_ReadByte(void)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
if(MISO_STA)
dat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_WRByte(unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(MISO_STA)
rdat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
#endif
#if SPI_CPOL==1 && SPI_CPHA==1
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
void SPI_WriteByte(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_ReadByte(void)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
dat<<=1;
if(MISO_STA)
dat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_WRByte(unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(MISO_STA)
rdat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
#endif
/*
*********************************************************************************************************
* 函 数 名: SPI_WriteOneData
* 形 参: spi; wdat:写入的数据
* 返 回 值: 无
* 功能说明: spi写入一个字节
*********************************************************************************************************
*/
void SPI_WriteOneData(SPI_CONFIG_t spi, unsigned char wdat)
{
CS_Enable(spi);
SPI_WriteByte(spi,wdat);
CS_Disable(spi);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_ReadOneData
* 形 参: spi;
* 返 回 值: 读取一个字节
* 功能说明: spi读取一个字节
*********************************************************************************************************
*/
unsigned char SPI_ReadOneData(SPI_CONFIG_t spi)
{
unsigned char rdat=0;
CS_Enable(spi);
rdat = SPI_ReadByte(spi);
CS_Disable(spi);
return rdat;
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WROneData
* 形 参: spi; wdat:写入的数据
* 返 回 值: spi读一个字节
* 功能说明: spi同时读写一个字节
*********************************************************************************************************
*/
unsigned char SPI_WROneData(SPI_CONFIG_t spi, unsigned char wdat)
{
unsigned char rdat=0;
CS_Enable(spi);
rdat = SPI_WRByte(spi,wdat);
CS_Disable(spi);
return rdat;
}
/*
*********************************************************************************************************
* 函 数 名: SPI_Write_Buf
* 形 参: spi; wdat:写入的数据; len:读取写入字节数
* 返 回 值: 无
* 功能说明: spi写多个字节
*********************************************************************************************************
*/
void SPI_Write_Buf(SPI_CONFIG_t spi, unsigned char* wdat, unsigned char len)
{
unsigned char i=0;
CS_Enable(spi);
for(i=0;i
SPI_WriteByte(spi,wdat
);
CS_Disable(spi);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_Read_Buf
* 形 参: spi; rdat:读取的数据; len:读取字节数
* 返 回 值: 无
* 功能说明: spi读多个字节
*********************************************************************************************************
*/
void SPI_Read_Buf(SPI_CONFIG_t spi, unsigned char* rdat, unsigned char len)
{
unsigned char i=0;
CS_Enable(spi);
for(i=0;i
rdat = SPI_ReadByte(spi);
CS_Disable(spi);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WR_Buf
* 形 参: spi; wdat:写入的数据; rdat:读取的数据; len:读取写入字节数
* 返 回 值: 无
* 功能说明: spi同时读写多个字节
*********************************************************************************************************
*/
void SPI_WR_Buf(SPI_CONFIG_t spi, unsigned char* wdat,unsigned char* rdat, unsigned char len)
{
unsigned char i=0;
CS_Enable(spi);
for(i=0;i
rdat = SPI_WRByte(spi,wdat);
CS_Disable(spi);
}
1. 需要的资源
2. 基本知识点
- SPI是什么:SPI是Serial Peripheral Interface的缩写,串行外围设备接口。是一种告诉的,全双工,同步的通信总线。
- SPI接口四条通讯线:
- MISO 主设备数据输入,从设备数据输出。
- MOSI 主设备数据输出,从设备数据输入。
- SCLK 时钟信号,由主设备产生。
- CS 从设备片选信号。由主设备控制。
- 支持在同一个协议总线上,挂在一个主设备多个从设备。
- 外设的读操作和写操作是可以同时进行的,也可以分开。
- SPI四种工作模式:
- 时钟极性(CPOL),是指SPI通讯设备处于空闲状态时,SCK信号线的电平信号(即SPI通讯开始前,CS片选信号为高时,SCLK的状态)。CPOL=0,SCLK为低;CPOL=1,SCLK为高
- 时钟相位(CPHA),是指数据的采样的时刻,当CPHA=0时,数据线上的信号将会在SCK时钟线的“奇数边沿”被采样;当CPHA=1时,数据线上的信号将会在SCK时钟线的“偶数边沿”被采样
- CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,在第一个边沿(上升沿)读取数据,在第二个边沿(下降沿)发送数据。 注意:因为在第一个边沿就会读取数据,所以在第一个边沿到来之前就要把第一位数据输出出来并保持稳定。
- CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,在第一个边沿(下降沿)读取数据,在第二个边沿(上升沿)发送数据。 注意:因为在第一个边沿就会读取数据,所以在第一个边沿到来之前就要把第一位数据输出出来并保持稳定。
- CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,在第一个边沿(上升沿)发送数据,在第二个边沿(下降沿)读取数据。
- CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,在第一个边沿(下降沿)发送数据,在第二个边沿(上升沿)读取数据。
- 注意:数据的读取和发送时序并不是针对主设备或者从设备,而是同时进行的,就是说在主设备读取数据的同时,从设备也是出于读取设备的状态。
3. 定义结构体
typedef struct _SPI_CONFIG_t
{
unsigned int Delay;
unsigned char (*MISO_STA)(void); //获取MISO的IO状态
void (*MOSI_IO_HIGH)(void); //MOSI的IO设置成高
void (*MOSI_IO_LOW)(void); //MOSI的IO设置成低
void (*CS_IO_HIGH)(void); //CS的IO设置成高
void (*CS_IO_LOW)(void); //CS的IO设置成低
void (*CLK_IO_HIGH)(void); //CLK的IO设置成高
void (*CLK_IO_LOW)(void); //CLK的IO设置成低
}SPI_CONFIG_t;
4. 函数功能
void _SPI_Delay(unsigned int n)
{
unsigned int t;
t=n;
while(t--);
}
#if SPI_CPOL==0 && SPI_CPHA==0
/*
*********************************************************************************************************
* 函 数 名: CS_Enable
* 形 参: spi
* 返 回 值: 无
* 功能说明: 片选使能
*********************************************************************************************************
*/
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
/*
*********************************************************************************************************
* 函 数 名: CS_Disable
* 形 参: spi
* 返 回 值: 无
* 功能说明: 片选失能
*********************************************************************************************************
*/
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WriteByte
* 形 参: spi; dat:写入的数据
* 返 回 值: 无
* 功能说明: spi写入一个字节的时序
*********************************************************************************************************
*/
void SPI_WriteByte(SPI_CONFIG_t spi, unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
if(dat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
}
/*
*********************************************************************************************************
* 函 数 名: SPI_ReadByte
* 形 参: spi;
* 返 回 值: spi读一个字节
* 功能说明: spi读一个字节的时序
*********************************************************************************************************
*/
unsigned char SPI_ReadByte(SPI_CONFIG_t spi)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
dat<<=1;
if(spi.MISO_STA())
dat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
return dat;
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WRByte
* 形 参: spi; wdat:写入的数据
* 返 回 值: spi读一个字节
* 功能说明: spi同时读写一个字节的时序
*********************************************************************************************************
*/
unsigned char SPI_WRByte(SPI_CONFIG_t spi, unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
wdat<<=1;
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(spi.MISO_STA())
rdat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
return rdat;
}
#endif
#if SPI_CPOL==1 && SPI_CPHA==0
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
void SPI_WriteByte(SPI_CONFIG_t spi, unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
if(dat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_ReadByte(SPI_CONFIG_t spi)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
if(spi.MISO_STA())
dat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
return dat;
}
unsigned char SPI_WRByte(SPI_CONFIG_t spi, unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
wdat<<=1;
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(spi.MISO_STA())
rdat |= 0x01;
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
return rdat;
}
#endif
#if SPI_CPOL==0 && SPI_CPHA==1
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
void SPI_WriteByte(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_ReadByte(void)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
if(MISO_STA)
dat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_WRByte(unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(MISO_STA)
rdat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
#endif
#if SPI_CPOL==1 && SPI_CPHA==1
void CS_Enable(SPI_CONFIG_t spi)
{
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CS_IO_LOW();
_SPI_Delay(spi.Delay);
}
void CS_Disable(SPI_CONFIG_t spi)
{
spi.CS_IO_HIGH();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
void SPI_WriteByte(unsigned char dat)
{
unsigned char i=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
dat<<=1;
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_ReadByte(void)
{
unsigned char i=0,dat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
dat<<=1;
if(MISO_STA)
dat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
unsigned char SPI_WRByte(unsigned char wdat)
{
unsigned char i=0,rdat=0;
for(i=0;i<8;i++)
{
spi.CLK_IO_LOW();
_SPI_Delay(spi.Delay);
if(wdat&0x80)
spi.MOSI_IO_HIGH();
else
spi.MOSI_IO_LOW();
_SPI_Delay(spi.Delay);
spi.CLK_IO_HIGH();
_SPI_Delay(spi.Delay);
rdat<<=1;
if(MISO_STA)
rdat |= 0x01;
_SPI_Delay(spi.Delay);
}
}
#endif
/*
*********************************************************************************************************
* 函 数 名: SPI_WriteOneData
* 形 参: spi; wdat:写入的数据
* 返 回 值: 无
* 功能说明: spi写入一个字节
*********************************************************************************************************
*/
void SPI_WriteOneData(SPI_CONFIG_t spi, unsigned char wdat)
{
CS_Enable(spi);
SPI_WriteByte(spi,wdat);
CS_Disable(spi);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_ReadOneData
* 形 参: spi;
* 返 回 值: 读取一个字节
* 功能说明: spi读取一个字节
*********************************************************************************************************
*/
unsigned char SPI_ReadOneData(SPI_CONFIG_t spi)
{
unsigned char rdat=0;
CS_Enable(spi);
rdat = SPI_ReadByte(spi);
CS_Disable(spi);
return rdat;
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WROneData
* 形 参: spi; wdat:写入的数据
* 返 回 值: spi读一个字节
* 功能说明: spi同时读写一个字节
*********************************************************************************************************
*/
unsigned char SPI_WROneData(SPI_CONFIG_t spi, unsigned char wdat)
{
unsigned char rdat=0;
CS_Enable(spi);
rdat = SPI_WRByte(spi,wdat);
CS_Disable(spi);
return rdat;
}
/*
*********************************************************************************************************
* 函 数 名: SPI_Write_Buf
* 形 参: spi; wdat:写入的数据; len:读取写入字节数
* 返 回 值: 无
* 功能说明: spi写多个字节
*********************************************************************************************************
*/
void SPI_Write_Buf(SPI_CONFIG_t spi, unsigned char* wdat, unsigned char len)
{
unsigned char i=0;
CS_Enable(spi);
for(i=0;i
SPI_WriteByte(spi,wdat
);
CS_Disable(spi);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_Read_Buf
* 形 参: spi; rdat:读取的数据; len:读取字节数
* 返 回 值: 无
* 功能说明: spi读多个字节
*********************************************************************************************************
*/
void SPI_Read_Buf(SPI_CONFIG_t spi, unsigned char* rdat, unsigned char len)
{
unsigned char i=0;
CS_Enable(spi);
for(i=0;i
rdat = SPI_ReadByte(spi);
CS_Disable(spi);
}
/*
*********************************************************************************************************
* 函 数 名: SPI_WR_Buf
* 形 参: spi; wdat:写入的数据; rdat:读取的数据; len:读取写入字节数
* 返 回 值: 无
* 功能说明: spi同时读写多个字节
*********************************************************************************************************
*/
void SPI_WR_Buf(SPI_CONFIG_t spi, unsigned char* wdat,unsigned char* rdat, unsigned char len)
{
unsigned char i=0;
CS_Enable(spi);
for(i=0;i
rdat = SPI_WRByte(spi,wdat);
CS_Disable(spi);
}
举报