SPI—— Serial Peripheral interface

来源:互联网 发布:怎么在ubuntu上装jdk 编辑:程序博客网 时间:2024/04/27 20:11
SPI,一种高速、全双工,同步通信总线
SPI 主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可 编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等
如果只进行写操作, 主机只需忽略接收到的字节; 反之, 若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。



SPI 接口一般使用 4 条线通信:
MISO 主设备数据输入,从设备数据输出。
MOSI 主设备数据输出,从设备数据输入。
SCLK 时钟信号,由主设备产生。
CS 从设备片选信号,由主设备控制。





CPOL  :时钟极性,决定串行同步时钟的空闲状态为低电平
CPOL = 1,高   ;  CPOL = 0,低

CPHA :决定数据采集的位置
CPHA = 0,第一个跳变沿; CPHA = 1,第二个跳变沿




配置:

第一步就要使能 SPI1 的时钟,SPI1 的时钟通过 APB2ENR 的第 12 位来设 置。其次要设置 SPI1 的相关引脚为复用(AF5)输出,这样才会连接到 SPI1 上。这里我们使用的 是 PB3、4、5 这 3 个(SCK.、MISO、MOSI,CS 使用软件管理方式) ,所以设置这三个为复用 IO,复用功能为 AF5。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能 SPI1 时钟
GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1); //PB3 复用为 SPI1
GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1); //PB4 复用为 SPI1
GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1); //PB5 复用为 SPI1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能



第二步、初始化SPI1,设置SPI1工作模式
这一步全部是通过 SPI1_CR1 来设置,我们设置 SPI1 为主机模式,设置数据格式为 8 位, 然后通过 CPOL 和 CPHA 位来设置 SCK 时钟极性及采样方式。并设置 SPI1 的时钟频率(最大 37.5Mhz) ,以及数据的格式(MSB 在前还是 LSB 在前) 。

typedef struct
{
uint16_t SPI_Direction; //设置 SPI 的通信方式,可以选择为半双工,全双工,以及串行 发和串行收方式
uint16_t SPI_Mode; //用来设置 SPI 的主从模式
uint16_t SPI_DataSize;// 为 8 位还是 16 位帧格式选择项
uint16_t SPI_CPOL;//设置时钟极性
uint16_t SPI_CPHA;//选择在串行同步时钟的第几个跳变沿(上升 或下降)数据被采样
uint16_t SPI_NSS;// 设置 NSS 信号由硬件(NSS 管脚)还是软件控制
uint16_t SPI_BaudRatePrescaler;//设置 SPI 波特率预分频值也就是决定 SPI 的时钟的参数
uint16_t SPI_FirstBit;//设置数据传输顺序是 MSB 位在前还是 LSB 位在前 
uint16_t SPI_CRCPolynomial;//设置 CRC 校验多项式, 提高通信可靠性, 大于 1 即可
}SPI_InitTypeDef;

SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //主 SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI 发送接收 8 位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//第二个跳变沿数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  //NSS 信号由软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //预分频 256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从 MSB 位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC 值计算的多项式
SPI_Init(SPI2, &SPI_InitStructure); //根据指定的参数初始化外设 SPIx 寄存器


第三步、使能SPI1
这一步通过 SPI1_CR1 的 bit6 来设置,以启动 SPI1,在启动之后,我们就可以开始 SPI 通 讯了
SPI_Cmd(SPI1, ENABLE); //使能 SPI1 外设

第四步、SPI传输数据
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) ;

第五步、我们经常要判断数据是否传输完成,发送区是否为空等等状态,这是 通过函数 SPI_I2S_GetFlagStatus 实现的


SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE);


















0 0
原创粉丝点击