原创 SPI通信协议简介及STM32的GPIO模拟实现

2016-3-23 23:46 1713 16 18 分类: MCU/ 嵌入式

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在时钟线的偶数边缘被采样。

四种模式的通信时序如下图所示(摘自网络--百度百科):

spi通信时序.jpg

图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;

}

 

文章评论2条评论)

登录后参与讨论

用户425606 2016-5-30 17:20

具体的代码可能不一样,但时序都是一样的

用户3749647 2016-5-24 16:58

您好   弱弱的问您一下   不同的微处理器在进行spi通信时 处理初始化不同  其他的代码是一样的吗?

相关推荐阅读
我要评论
2
16
关闭 站长推荐上一条 /2 下一条