SPI协议(Serial Peripheral Interface )中文名称为串行外围设备接口,是由Motorola公司提出的高速全双工通信总线。普遍用于MCU与EEPROM,FLASH,ADC等PCB上电路间的通信场合。SPI通信采用主—从的控制方式,可由一个主机(Master)控制多个设备(Device)。采用同步传输的数据通信方式(由主机产生时钟信号)。
SPI协议的物理连接包含四条信号线,分别为:
(1)SS:片选信号线。当主机连接多个设备时,各个SS信号线单独占一个接口,由主机选通设备进行通信。
(2)SCK:时钟信号线。由主机产生,用于同步通信。
(3)MOSI:主设备输出/从设备输入信号线。用于主机发送数据,并读取从机发送的数据。
(4)MISO:主设备输入/从设备输出信号线。用于从机接收主机数据,并向主机发数据。
基于时钟极性(CPOL)和时钟相位(CPHA)的配置,SPI可分为四种模式:
(1)CPOL=0,CPHA=0。SCL空闲时为低电平,SPI在时钟线的奇数边缘被采样。
(2)CPOL=0,CPHA=1。SCL空闲时为低电平,SPI在时钟线的偶数边缘被采样。
(3)CPOL=1,CPHA=0。SCL空闲时为高电平,SPI在时钟线的奇数边缘被采样。
(4)CPOL=1,CPHA=1。SCL空闲时为高电平,SPI在时钟线的偶数边缘被采样。
四种模式的通信时序如下图所示(摘自网络--百度百科):
图1SPI通信时序
以模式0为例,当从机片选信号被选中,由于时钟空闲信号为低电平,所以每次低电平过后每个奇数时刻的时钟信号沿被采样。即每个低电平后的上升沿被采样(时钟信号为规则的方波)。
基于以上分析,可以使用单片机的IO口来模拟SPI通信的接口函数,函数的实现如下所示(基于stm32f103):
以下是代码片段: #define SPI_FLASH_CS_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_4) #define GPIO_SPI_CLK(a) if (a) \ GPIO_SetBits(SPI_CLK_PORT,SPI_CLK_PIN); \ else \ GPIO_ResetBits(SPI_CLK_PORT,SPI_CLK_PIN) #define GPIO_SPI_WRITE(a) if (a) \ GPIO_SetBits(SPI_MOSI_PORT,SPI_MOSI_PIN); \ else \ GPIO_ResetBits(SPI_MOSI_PORT,SPI_MOSI_PIN) static uint8_t SPI_Trans(uint8_t dat) { uint8_t i,w_buf,r_buf = 0;
Delay_us(2); SPI_FLASH_CS_LOW(); for(i=0;i<8;i++) { w_buf = (dat>>(7-i)) & 0x01; //MSB先行 if(w_buf) GPIO_SPI_WRITE(1); Else { GPIO_SPI_WRITE(0); GPIO_SPI_CLK(1); Delay_us(2); r_buf = (r_buf << 1) | GPIO_SPI_READ(); GPIO_SPI_CLK(0); //奇数边缘采样 Delay_us(2); } } return r_buf; } |
用户425606 2016-5-30 17:20
用户3749647 2016-5-24 16:58
您好 弱弱的问您一下 不同的微处理器在进行spi通信时 处理初始化不同 其他的代码是一样的吗?