spi
SPI是一种全双工串行同步通信协议,用于主控和外设之间的快速、可靠的数据传输。
spi有四种模式(0~3):由时钟极性(Clock Polarity CPOL)和时钟相位(Clock Phase CPHA)决定。
时钟极性(CPOL)定义了时钟空闲状态电平:
CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时
时钟相位(CPHA)定义数据的采集时间:
CPHA=0,在时钟的第一个跳变沿(上升沿或下降沿)进行数据采样。,在第2个边沿发送数据
CPHA=1,在时钟的第二个跳变沿(上升沿或下降沿)进行数据采样。,在第1个边沿发送数据
模式 | 时钟极性 | 时钟相位 | ||
mode 0 | 0 | 0 |
CPOL为0表示时钟空闲状态为低电平; CPHA为0表示数据在时钟的上升沿采样,数据在时钟的下降沿输出; |
|
mode 1 | 0 | 1 | CPHA为1表示数据在时钟的下降沿采样,数据在时钟的上升沿输出; | |
mode 2 | 1 | 0 |
CPOL为1表示时钟空闲状态为高电平; CPHA为0表示数据在时钟的下降沿采样,数据在时钟的上升沿输出; |
|
mode 3 | 1 | 1 | CPHA为1表示数据在时钟的上升沿采样,数据在时钟的下降沿输出; |
1 void master_Send_Dat(char dat) 2 { 3 char i; 4 CS = 0;//拉低片选信号 5 for(i = 0; i < 8; i++){ 6 if((dat & 0x80) == 0x80) 7 MOSI = 1;//将数据线拉高,准备发送 8 else 9 MOSI = 0;//将数据线拉低,准备发送 10 11 dat = dat <<1;//传输下一位 12 13 CLK = 1;//上升沿,即往数据线MOSI上放数据。这里就相当于iic的时钟线为低电平,数据线允许变化 14 _nop_(); 15 _nop_(); 16 CLK = 0;//下降沿,在下降沿数据保持稳定,MOSI上的数据要发送出去。这里就相当于iic的时钟线高电平,数据线要保持稳定 17 _nop_(); 18 _nop_(); 19 } 20 21 return ; 22 } 23 24 char slave_Receive_Dat() 25 { 26 char i,dat = 0; 27 while(CS);//等待片选信号线被拉低 28 for(i = 0; i <8; i++){ 29 while(CLK == 0);//clk为低电平的时间,即clk被拉高时,低电平的持续时间, 这里会产生一个上升沿 30 while(CLK == 1);//clk为高电平的时间,即clk被拉低时,高电平的持续时间,这里会产生一个下降沿 31 dat = dat << 1; 32 dat = dat|MOSI; 33 } 34 35 return dat; 36 } 37 38 char master_Receive_Dat() 39 { 40 char i, dat = 0; 41 CS = 0;//拉低片选信号 42 43 for(i = 0; i <8; i++){ 44 dat = dat << 1; 45 46 CLK = 1;//上升沿,允许数据变化 47 _nop_(); 48 _nop_(); 49 50 CLK = 0;//下降沿,数据保持稳定,读数据 51 dat = dat|MISO; //上升沿过后两个nop,MISO变化2nop()后保持稳定 52 _nop_(); 53 _nop_(); 54 } 55 56 return dat; 57 } 58 59 void slave_Send_Dat(char dat) 60 { 61 char i; 62 for(i = 0; i < 8; i++){ 63 while(CLK == 0);//clk为低电平的时间,即clk被拉高时,低电平的持续时间, 这里会产生一个上升沿 64 if((dat & 0x80) == 0x80) 65 MISO = 1; 66 else 67 MISO = 0; 68 dat = dat << 1; 69 while(CLK == 1);//clk为高电平的时间,即clk被拉低时,高电平的持续时间,这里会产生一个下降沿 70 } 71 return ; 72 }