东莞哪家网站营销公司好seo的收费标准
1、原理
1、硬件电路
相比I2C,SPI传输更快,没有严格规定最大传输速度。硬件开销大,通信线个数多,并且通信过程中会出现资源浪费的现象。
全双工MOSI、MISO可同时向通信双方发送数据,从机上可能表示为DI、DO。
SPI只支持一主多从,不支持多主机。
SS、CS专门用来指定通信的从机
SPI所有通信线都是单端信号,它们的高低电平都是相对GND的电压差,并且所有设备都要共地;如果从机没有独立供电,主机还要额外引出电源正极。
SCK时钟线,完全由主机掌控,对于主机时钟线为输出,对于从机时钟线为输入。
SS选择线,低电平有效,同时只能选中一个;为了防止一条线有多个输出,而导致电平冲突的问题,高电平时,MISO引脚必须切换为高阻态。
SPI高位先行,每来一个时钟,主机、从机移位寄存器都会向左进行移位。
波特率发生器:提供移位寄存器的时钟源,驱动主机的移位寄存器移位,同时通过SCK引脚输出到从机的移位寄存器里。
交换字节时序:上升沿时把主机和从机移位寄存器的最高位,分别放到MOSI和MISO通信线上;下降沿时主机和从机内都会进行数据采样输入,分别将MISO和MOSI通信线上的数据放到主机和从机的最低位。
2、SPI基本时序单元
从机整个选中状态中,SS要始终保持低电平。
模式0,SS下降沿时,主机、从机同时移出数据。
上升沿,主机、从机同时移入数据;下降沿,主机、从机同时移出数据。
SS下降沿之后,从机的MISO被允许开启输出;上升沿后,必须关闭,即置高阻态,此时如果主机的MISO为上拉输入的话,MISO引脚的电平默认为高电平;如果MISO为浮空输入,那MISO引脚的电平不确定。
3、时序
1、发送
指令码+读写数据+地址
主机要发送数据1,下降沿将数据1移到MOSI,MOSI变为高电平
2、指定地址写
连发三个字节,指定在24位存储器的地址。
SPI没有应答机制。
3、指令地址读
使用交换字节的时序,向从机任意发送一个数据(一般为FF),主机只接受从机的数据就可以了。
4、代码
void MySPI_W_CS(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}
void MySPI_W_SCK(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);
}
void MySPI_W_MOSI(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);
}
void MySPI_W_MISO(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)BitValue);
}
uint8_t MySPI_R_MISO()
{return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
}
void MySPI_Init()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_5|GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//默认不选中从机MySPI_W_CS(1);//模式0,SCK默认低电平MySPI_W_SCK(0);
}
void MySPI_Start()
{MySPI_W_CS(0);
}
void MySPI_End()
{MySPI_W_CS(1);
}
uint8_t MyI2C_SwapByte(uint8_t ByteSend)
{uint8_t ByteReceive;uint8_t i;for(i=0;i<8;i++){MySPI_W_MOSI(ByteSend&(0x80>>i));MySPI_W_SCK(1);if(MySPI_R_MISO()==1){ByteReceive|=(0x80>>i);}MySPI_W_SCK(0);}return ByteReceive;
}