SPI协议简介 SPI接口介绍 CS:片选信号,由主设备控制从设备,,所以主设备CS信号为输出模式,从设备的CS信号为输入模式。 MISO:主设备数据输入,从设备数据输出,所以主设备MISO信号为输入模式,从设备的MISO信号为输出模式。
SPI数据传输方向 SPI总线传输一共有4种模式,这4种模式分别由时钟极性(CPOL)和时钟相位(CPHA)来定义。 CPOL:规定了SCK时钟信号空闲状态的电平 模式1:CPOL=0,CPHA =1 SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据) 模式3:CPOL=1,CPHA =1 SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)
MOSI上数据为1,则在此边沿从机采样(提取)数据为1,采样点在MOSI数据线的中间。
◐在时钟的第1个下降沿(游标2处)(切换点)
MISO上数据由0切换为1,,数据在时钟下降沿时切换数据。
◐在时钟的第2~8个下降沿(切换点),主机在MISO上切换数据,从机在MOSI上切换数据
首先来看主器件,主器件的输出口(MOSI)输出的数据bit1,在时钟的前沿被从器件采样,那主器件是在何时刻输出bit1的呢?bit1的输出时刻实际上在SCK信号有效以前,比 SCK的上升沿还要早半个时钟周期。bit1的输出时刻与SSEL信号没有关系。 关于上面的主器件和从器件输出bit1位的时刻,可以从以下两图中得到验证。 注意上图中,CS信号有效后(低电平有效,注意CS下降沿后发生的情况),故意用延时程序延时了一段时间,之后再向数据寄存器写入了要发送的数据,来观察主器件输出bit1的情况(MOSI)。 通常我们进行的spi操作都是16位的。下图记录了第一个字节和第二个字节间的相互衔接的过程。 Soft_SPI.c void SPI_Delay() //每步的间隔 用于等待电平稳定和控制通讯速率 }
void MOSI_H() SOFT_SPI_MOSI = 1; //MOSI拉低 移植时需修改 { }
void MISO_H() SOFT_SPI_MISO = 1; //MISO拉低 移植时需修改 { }
void SPI_SCK_H() SOFT_SPI_SCK = 1; //SCK拉低 移植时需修改 { }
uint8_t MISO_Read() SOFT_SPI_MISO = 1; return SOFT_SPI_MISO; //空闲时时钟极性(CPOL) 0为低电平 1为高电平 /* CPOL = 0, CPHA = 0, MSB first */ { SPI_SCK_L(); { read_dat |= MISO_Read(); MOSI_H(); MOSI_L(); SPI_Delay(); SPI_Delay(); } }
uint8_t SOFT_SPI_RW_MODE1(uint8_t write_dat) uint8_t i, read_dat = 0;
for(i = 0; i < 8; i++) //循环8次 if(write_dat & 0x80) else write_dat <<= 1; //低一位移位到最高位 SPI_SCK_H(); //拉高时钟 read_dat <<= 1; //数据左移 SPI_SCK_L(); //拉低时钟 return read_dat; //返回数据 /* CPOL=1,CPHA=0, MSB first */ { SPI_SCK_H(); { read_dat |= MISO_Read(); MOSI_H(); //若最到位为高,则输出高 MOSI_L(); //若最到位为低,则输出低 SPI_Delay(); SPI_Delay(); } }
uint8_t SOFT_SPI_RW_MODE3(uint8_t write_dat) uint8_t i, read_dat = 0;
for( i = 0; i < 8; i++ ) if(write_dat & 0x80) else write_dat <<= 1; SPI_SCK_L(); read_dat <<= 1; SPI_SCK_H(); return read_dat; Soft_SPI.h #define SOFT_SPI_H_
#include "stdint.h"
sbit SOFT_SPI_MOSI = P1^0; //MOSI拉高 移植时需修改 //MOSI拉低 移植时需修改 //MISO拉高 移植时需修改 //MISO拉低 移植时需修改 //SCK拉高 移植时需修改 //SCK拉低 移植时需修改 //读取MISO电平 移植时需修改 void SPI_Delay(); //每步的间隔 用于等待电平稳定和控制通讯速率
uint8_t SOFT_SPI_RW_MODE1(uint8_t write_dat); uint8_t SOFT_SPI_RW_MODE3(uint8_t write_dat);
#endif
|