spi

发布时间 2023-11-30 17:39:39作者: 踏浪而来的人

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 master_Receive_Dat()
25 {
26     char i, dat = 0;
27     CS = 0;//拉低片选信号
28     
29     for(i = 0; i <8; i++){
30         dat = dat << 1;
31         
32         CLK = 1;//上升沿,允许数据变化
33         _nop_();
34         _nop_();        
35         dat = dat|MISO; //上升沿过后两个nop,MISO变化后保持稳定
36         
37         CLK = 0;//下降沿,数据保持稳定,读数据
38         _nop_();
39         _nop_();        
40     }
41 
42     return dat;
43 }
44 
45 char slave_Receive_Dat()
46 {
47     char i,dat = 0;
48     while(CS);//等待片选信号线被拉低
49     for(i = 0; i <8; i++){
50         while(CLK == 0);//clk为低电平的时间,即clk被拉高时,低电平的持续时间
51         while(CLK == 1);//clk为高电平的时间,即clk被拉低时,高电平的持续时间,这里会产生一个下降沿
52         dat = dat << 1;
53         dat = dat|MOSI;
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 }