精华内容
下载资源
问答
  • 标准SPI通信协议

    2019-11-28 13:20:48
    初始化模块的时候,经常会用到SPI通信,整理了一下SPI通信的代码;移植后修改宏定义就可使用; 第一种规格,地址和数据先整合为short类型,之后连续发送16bits 使用时: devices_spi_write_byte(addr, data); #...

    初始化模块的时候,经常会用到SPI通信,整理了一下SPI通信的代码;移植后修改宏定义就可使用;

    第一种规格,地址和数据先整合为short类型,之后连续发送16bits
    使用时:
    devices_spi_write_byte(addr, data);

    #define	SPI_IO_SDA				(GPIO_0)
    #define	SPI_IO_SCL				(GPIO_1)
    #define	SPI_IO_CS				(GPIO_2)
    
    #define SPI_SCL_OUT				gpio_setDir(SPI_IO_SCL, GPIO_DIR_OUTPUT)
    #define SPI_SCL_IN				gpio_setDir(SPI_IO_SCL, GPIO_DIR_INPUT)
    #define SPI_SCL_HIGH			gpio_setPin(SPI_IO_SCL)
    #define SPI_SCL_LOW				gpio_clearPin(SPI_IO_SCL)
    
    #define SPI_SDA_OUT				gpio_setDir(SPI_IO_SDA, GPIO_DIR_OUTPUT)
    #define SPI_SDA_IN				gpio_setDir(SPI_IO_SDA, GPIO_DIR_INPUT)
    #define SPI_SDA_HIGH 			gpio_setPin(SPI_IO_SDA)
    #define SPI_SDA_LOW  			gpio_clearPin(SPI_IO_SDA)
    #define SPI_SDA_DETECT			gpio_getPin(SPI_IO_SDA)
    
    #define SPI_CS_OUT				gpio_setDir(SPI_IO_CS, GPIO_DIR_OUTPUT)
    #define SPI_CS_IN				gpio_setDir(SPI_IO_CS, GPIO_DIR_INPUT)
    #define SPI_CS_HIGH				gpio_setPin(SPI_IO_CS)
    #define SPI_CS_LOW				gpio_clearPin(SPI_IO_CS)
    
    #define SPI_DELAY_US(x)         Delay_DelayUs(x)
    
    void devices_spi_write_byte(unsigned char addr, unsigned char value)
    {
        unsigned char	j;
    	unsigned int	commond;
    
    	SPI_SCL_OUT;
    	SPI_SDA_OUT;
    	SPI_CS_OUT;
    	
    	SPI_CS_HIGH;
    	SPI_SCL_HIGH;
    	SPI_SDA_HIGH;
    	
    	commond = addr;
    	commond = commond << 8;
    	commond |= value;
    
        SPI_DELAY_US(500);
    
        SPI_CS_LOW;
    
        for(j = 16; j > 0; j--)
        {
            if(((commond >> (j - 1)) & 0x01))
                SPI_SDA_HIGH;
            else
                SPI_SDA_LOW;
    
            SPI_DELAY_US(100);
            SPI_SCL_LOW;
            SPI_DELAY_US(200);
            SPI_SCL_HIGH;
            SPI_DELAY_US(100);
        }
    
        SPI_DELAY_US(500);
        SPI_CS_HIGH;
    }
    

    第二种规则,地址和数据分开发送,使用时一般需:
    devices_spi_write_byte(addr);
    devices_spi_write_byte(data);

    #define	SPI_IO_SDA			(GPIO_0)
    #define	SPI_IO_SCL			(GPIO_1)
    #define	SPI_IO_CS			(GPIO_2)
    
    #define SPI_SCL_OUT				gpio_setDir(SPI_IO_SCL, GPIO_DIR_OUTPUT)
    #define SPI_SCL_IN				gpio_setDir(SPI_IO_SCL, GPIO_DIR_INPUT)
    #define SPI_SCL_HIGH			gpio_setPin(SPI_IO_SCL)
    #define SPI_SCL_LOW				gpio_clearPin(SPI_IO_SCL)
    
    #define SPI_SDA_OUT				gpio_setDir(SPI_IO_SDA, GPIO_DIR_OUTPUT)
    #define SPI_SDA_IN				gpio_setDir(SPI_IO_SDA, GPIO_DIR_INPUT)
    #define SPI_SDA_HIGH 			gpio_setPin(SPI_IO_SDA)
    #define SPI_SDA_LOW  			gpio_clearPin(SPI_IO_SDA)
    #define SPI_SDA_DETECT			gpio_getPin(SPI_IO_SDA)
    
    #define SPI_CS_OUT				gpio_setDir(SPI_IO_CS, GPIO_DIR_OUTPUT)
    #define SPI_CS_IN				gpio_setDir(SPI_IO_CS, GPIO_DIR_INPUT)
    #define SPI_CS_HIGH				gpio_setPin(SPI_IO_CS)
    #define SPI_CS_LOW				gpio_clearPin(SPI_IO_CS)
    
    #define SPI_DELAY_US(x)         Delay_DelayUs(x)
    
    void devices_spi_write_byte(unsigned char value)
    {
        unsigned char	j;
    
    	SPI_SCL_OUT;
    	SPI_SDA_OUT;
    	SPI_CS_OUT;
    	
    	SPI_CS_HIGH;
    	SPI_SCL_HIGH;
    	SPI_SDA_HIGH;
    
        SPI_DELAY_US(500);
    
        SPI_CS_LOW;
    
        for(j = 8; j > 0; j--)
        {
            if(((value >> (j - 1)) & 0x01))
                SPI_SDA_HIGH;
            else
                SPI_SDA_LOW;
    
            SPI_DELAY_US(100);
            SPI_SCL_LOW;
            SPI_DELAY_US(200);
            SPI_SCL_HIGH;
            SPI_DELAY_US(100);
        }
    
        SPI_DELAY_US(500);
        SPI_CS_HIGH;
    }
    
    展开全文
  • SPI(Serial Peripheral Interface)总线是主要应用于嵌入式系统内部通信的串行同步传输总线协议。通常为四线制的SPI总线支持全双工通信SPI最初由Motorola在2000年提出,Motorola所定义的SPI标准为业界广泛引用,...

    1. SPI介绍

            SPI(Serial Peripheral Interface)总线是主要应用于嵌入式系统内部通信的串行同步传输总线协议。通常为四线制的SPI总线支持全双工通信。SPI最初由Motorola在2000年提出,Motorola所定义的SPI标准为业界广泛引用,但不同半导体公司的实施细节可能有所不同,这些区别体现在寄存器设置、信号定义、数据格式等。业界没有统一的SPI标准,具体应用需要参考特定器件手册。

            SPI协议特点包括主从模式、全双工通信、片选功能、模式错误标识及CPU中断、缓冲数据寄存器和可配置时钟相位极性等。SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。

     

    2. SPI的应用

    SPI以其简单高效应用于绝大多数SoC系统上,这些SoC通常同时支持作为主模式或从模式(二选一)。

    FPGAs和其它专用芯片也广泛使用SPI传输数据。比如:

    • 传感器:温度、压力传感器等
    • 控制设备:音频编解码器等
    • 通信设备:USB、以太网设备等
    • 存储器FlashEEPROM
    • RTC时钟
    • LCD设备
    • MMCSD

            在高性能系统中,FPGAs通常使用SPI连接主从设备,比如连接外部传感器,和应用SPI加载配置。相比于JTAG,SPI定位用于高速配置(初始化)板上设备;而JTAG的初衷是为控制设备以相对低的准确度扫描和检测板上IO,在严格要求的场合,JTAG协议支持改变时钟占空比以满足建立和保持时间的要求。因此,JTAG并不定位于高速数据传输的场合。

    3. SPI的优点与缺点

    优点:

    • 支持全双工通信
    • Push-Pull驱动性能相比Open Drain信号完整性更好,支持高速应用(100MHz以上)
    • 协议支持字长不限于8bits,可根据应用特点灵活选择消息字长
    • 硬件连接简单
      • 只需要四根信号线(部分应用可以缩减到三根)
      • 相比I2CSMbus节省上拉电阻
      • 相比I2CSMbus不需要仲裁机制
      • 从设备使用主设备时钟,节约时钟要求
      • 从设备无需地址寻址
      • 无需收发器

    缺点:

    • 相比I2C两根线,SPI四根线更多
    • 没有寻址机制,只能靠设备片选(chip select)选择不同从设备
    • 没有数据流控制(但主设备可以通过延缓时钟边缘降低传输速度)
    • 没有从设备接收数据ACK,主设备对于发送成功与否不得而知
    • 典型应用只支持单主控
    • 没有定义数据校验机制
    • 没有统一的国际组织维护,变种多不利于不同厂商设备的互操作性(interoperability
    • 相比于RS232RS422RS485CANSPI传输距离短
    • 不支持热插拔
    • 中断操作只能通过额外的信号线,或类似USB 1.1 and 2.0Periodic Polling实现

    4. SPI的硬件连接

            SPI总线定义两个及以上设备间的数据传输,提供时钟的设备为主设备(Master),接收时钟的设备为从设备(Slave)。下图为单个Master与单个SlaveSPI连接:

    http://www.wangdali.net/wp-content/uploads/2016/04/p2_spi_ms_mod_hw.png

    4.1 SPI引脚定义

    SPI协议定义四根信号线,分别为:

    1. SCK : Serial Clock 串行时钟
    2. MOSI : Master Output, Slave Input 主发从收信号
    3. MISO : Master Input, Slave Output 主收从发信号
    4. SS : Slave Select 片选信号

    其中MISO方向为从设备到主设备,其余三个信号均为主设备到从设备。

    注意:

    • 对于主设备,如果设置SS作为从设备的片选信号(最常用的场合),则它就不能用于多设备应用的模式错误检测
    • SPI单个数据管脚支持双向模式。在双向模式下,主设备的MOSI,从设备的MISO作为双向IO。

    4.2 单个Master对多个Slave

    通过多个片选信号(SS)或菊花链方式(Daisy Chain Configuration),单个主设备可以同时控制多个不同从设备。

    4.2.1 片选方式

     

            每个从设备都需要单独的片选信号,主设备每次只能选择其中一个从设备进行通信。因为所有从设备的SCK、MOSI、MISO都是连在一起的,未被选中从设备的MISO要表现为高阻状态(Hi-Z)以避免数据传输错误。由于每个设备都需要单独的片选信号,如果需要的片选信号过多,可以使用译码器产生所有的片选信号。

     

    4.2.2 菊花链方式

     

            数据信号经过主从设备所有的移位寄存器构成闭环。数据通过主设备发送(绿色线)经过从设备返回(蓝色线)到主设备。在这种方式下,片选和时钟同时接到所有从设备,通常用于移位寄存器和LED驱动器。注意,菊花链方式的主设备需要发送足够长的数据以确保数据送达到所有从设备。切记主设备所发送的第一个数据需(移位)到达菊花链中最后一个从设备。

            菊花链式连接常用于仅需主设备发送数据而不需要接收返回数据的场合,如LED驱动器。在这种应用下,主设备MISO可以不连。如果需要接收从设备的返回数据,则需要连接主设备的MISO形成闭环。同样地,切记要发送足够多的接收指令以确保数据(移位)送达主设备。

    https://cdn.sparkfun.com/assets/e/3/b/d/1/50e5d529ce395fd27b000001.png

    5. SPI的数据收发及工作模式

    5.1 同步解决方案

           SPI的工作方式略有不同。它是一个“同步”数据总线,这意味着它使用单独的数据线和“时钟”,使双方保持完美同步。时钟是一个振荡信号,告诉接收器确切地何时采样数据线上的位。这可能是时钟信号的上升沿(低到高)或下降沿(从高到低); 数据表将指定使用哪一个。当接收器检测到该边沿时,它将立即查看数据线以读取下一位(参见下图中的箭头)。由于时钟与数据一起发送,因此指定速度并不重要,尽管设备将具有可以运行的最高速度(我们将讨论选择合适的时钟边沿和速度)。

     

    5.2 数据接收

            你可能会觉得,这对于单向通信来说很简单,但是如何以相反的方向发送数据呢?事情变得稍微复杂一些。

            在SPI中,只有一侧产生时钟信号(通常称为串行ClocK的CLK或SCK)。生成时钟的一侧称为“Master”,另一侧称为“Slave。总是只有一个主设备(基本上都是微控制器),但是可以有多个从设备。

            当数据从Master发送到Slave时,它将在MOSI线上发送,用于“Master输出/Slave输入”。如果Slave需要将响应发送回Master,则Master将继续生成预先安排好了的时钟周期,Slave将数据放入MISO线进行传输,用于“Master输入/Slave输出”。

     

    注意:

            我们在上面的描述中说“预先安排好了”。由于Master始终生成时钟信号,因此必须事先知道Slave何时需要返回数据以及将返回多少数据。这与异步串行不同,异步串行是随时可以向任一方向发送随机数据量。在实际应用中,这不是问题,因为SPI通常用于与具有非常特定命令结构的传感器通信。例如,如果我们将“读取数据”命令从Master发送到Slave,那么我们肯定知道Slave会回应我们(根据芯片文档寄存器的操作可知)。

            SPI是“全双工”(具有单独的发送和接收线),因此,在某些情况下,可以发送和接收数据在同一时间(例如,请求一个新的传感器读数的同时接收来自上一个传感器的数据)。

    5.3 工作模式

            SPI通信有4种不同的模式,不同的从设备可能在出厂是就是配置为某种模式,这是不能改变的;但我们的通信双方必须是工作在同一模式下,所以我们可以对我们的Master的SPI模式进行配置,通过CPOL(时钟极性)和CPHA(时钟相位)来控制我们主设备的通信模式,具体如下:

    Mode0:CPOL=0,CPHA=0
    Mode1:CPOL=0,CPHA=1
    Mode2:CPOL=1,CPHA=0
    Mode3:CPOL=1,CPHA=1

    时钟极性CPOL是用来配置SCLK的电平出于哪种状态时是空闲态或者有效态,时钟相位CPHA 
    是用来配置数据采样是在第几个边沿:
    CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
    CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时
    CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿
    CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿

    例如:
    CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是 
    SCLK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。

    CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是 
    SCLK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。

    CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是 
    SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。

    CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是 
    SCLK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。

    https://images2015.cnblogs.com/blog/944893/201610/944893-20161027161424453-974917858.gif

    https://images2015.cnblogs.com/blog/944893/201610/944893-20161027161436828-1727112897.gif

    注意:

            我们的主设备能够控制时钟,因为我们的SPI通信并不像UART或者IIC通信 那样有专门的通信周期,有专门的通信起始信号,有专门的通信结束信号;所以我们的 SPI协议能够通过控制时钟信号线,当没有数据交流的时候我们的时钟线要么是保持高电平要么是保持低电平。

            下面是将SPI协议作为SPI主控位进行位操作的例子,CPOL = 0CPHA = 0,每次传输8位。该示例使用C编程语言编写。因为这是CPOL = 0,所以必须在激活芯片选择之前将时钟拉低。必须激活芯片选择线,这通常意味着在传输开始之前为外设切换为低电平,然后在之后停用。选择线为低时,大多数外设允许或需要多次传输在取消选择芯片之前,可能会多次调用此例程。

    / * 
    *同时在SPI上发送和接收一个字节。
    * 
    *假设极性和相位均为0,即:
    *  - 在SCLK的上升沿捕获输入数据。
    *  - 输出数据在SCLK的下降沿传播。
    * 
    *返回接收的字节。
    * / 
    uint8_t SPI_transfer_byte(uint8_t byte_out)
    {
        uint8_t byte_in = 0;
        uint8_t bit;
    
        for (bit = 0x80; bit; bit >>= 1) {
            /* Shift-out a bit to the MOSI line */
            write_MOSI((byte_out & bit) ? HIGH : LOW);
    
            /* Delay for at least the peer's setup time */
            delay(SPI_SCLK_LOW_TIME);
    
            /* Pull the clock line high */
            write_SCLK(HIGH);
    
            /* Shift-in a bit from the MISO line */
            if (read_MISO() == HIGH)
                byte_in |= bit;
    
            /* Delay for at least the peer's hold time */
            delay(SPI_SCLK_HIGH_TIME);
    
            /* Pull the clock line low */
            write_SCLK(LOW);
        }
    
        return byte_in;
    }
    

     读例子:

    /*——————————————————————————
    * 函 数 名:SPI_Read_Reg
    * 输入参数:addr:    寄存器地址
    * 输出参数:None
    * 返 回 值:寄存器数据
    * 功能说明:读计量参数 下降沿发送和读取数据, 先发送8位地址,再读取24位数据
    *——————————————————————————*/
    uint32_t SPI_Read_Reg(uint8_t addr)
    {
    	uint8_t		i;
    	uint32_t	temp = 0;
    
    	addr &= 0x7F;
    	HIGH_CS();
    	SPI_Delay();
    	LOW_CS();
    	SPI_Delay();
    	SPI_Delay();
    	SPI_Delay();
    
    	LOW_CLK();
    	//SPI_Delay();
    	//LOW_CS();
    	for (i=0; i<8; i++)
    	{
    		SPI_Delay();
    		HIGH_CLK();
    		if (addr&0x80)
    		{
    			HIGH_DIN();
    		}
    		else
    		{
    			LOW_DIN();
    		}
    		addr <<= 1;
    		LOW_CLK();
    	}
    	SPI_Delay();
    	SPI_Delay();
    	SPI_Delay();
    	SPI_Delay();
    	SPI_Delay();
    	SPI_Delay();
    	for (i=0; i<24; i++)
    	{
    		SPI_Delay();
    		temp <<= 1;
    		HIGH_CLK();
    		SPI_Delay();
    		if (PIN_DOUT)
    		{
    			temp |= 0x01;
    		}
    		LOW_CLK();
    	}
    	SPI_Delay();
    	HIGH_CS();
    	SPI_Delay();
    	HIGH_CLK();
    	return (temp);
    }
    
    

     写例子:

    /*——————————————————————————
    * 函 数 名:SPI_Write_Reg
    * 输入参数:addr:		寄存器地址
    *			temp:		寄存器数据
    * 输出参数:None
    * 返 回 值:None
    * 功能说明:写寄存器参数 下降沿发送 先发送8位地址数据,再发送24位数据位数据
    *——————————————————————————*/
    void SPI_Write_Reg(uint8_t addr, uint32_t temp)
    {
    	uint8_t	i;
    
    	addr |= 0x80;
    	HIGH_CS();
    	SPI_Delay();
    	LOW_CS();
    	SPI_Delay();
    	SPI_Delay();
    	SPI_Delay();
    
    	LOW_CS();
    	for (i=0; i<8; i++)
    	{
    		SPI_Delay();
    		HIGH_CLK();
    		if (addr&0x80)
    		{
    			HIGH_DIN();
    		}
    		else
    		{
    			LOW_DIN();
    		}
    		addr <<= 1;
    		LOW_CLK();
    	}
    	for (i=0; i<24; i++)
    	{
    		SPI_Delay();
    		HIGH_CLK();
    		SPI_Delay();
    		if (temp&0x800000)
    		{
    			HIGH_DIN();
    		}
    		else
    		{
    			LOW_DIN();
    		}
    		temp <<= 1;
    		LOW_CLK();
    	}
    	SPI_Delay();
    	HIGH_CS();
    	SPI_Delay();
    	HIGH_CLK();
    }

    【硬件通信协议】1. IIC通信协议

     

    参考链接:

    http://www.wangdali.net/spi/

    https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi

    https://en.wikipedia.org/wiki/Serial_Peripheral_Interface

    展开全文
  • SPI通信协议

    2016-04-11 11:35:49
    SPI 是单片机系统中最常用的三种通信协议。前边我们已经学了 UART 和I2C通信协议,这节课我们来学习剩下的 SPI 通信协议SPI 是英语 Serial Peripheral Interface 的缩写,顾名思义就是串行外围设备接口。...
    UART、I2C和
     SPI 是单片机系统中最常用的三种通信协议。前边我们已经学了 UART 和I2C通信协议,这节课我们来学习剩下的
     SPI 通信协议。

    SPI 是英语 Serial Peripheral Interface 的缩写,顾名思义就是串行外围设备接口。SPI 是一种高速的、全双工、同步通信总线,标准的 SPI 也仅仅使用 4 个引脚,常用于单片机和 EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。SPI 通信原理比 I2C要简单,它主要是主从方式通信,这种模式通常只有一个主机和一个或者多个从机,标准的 SPI 是 4 根线,分别是 SSEL(片选,也写作 SCS)、SCLK(时钟,也写作 SCK)、MOSI(主机输出从机输入Master Output/Slave Input)和 MISO(主机输入从机输出 Master Input/Slave Output)。

    SSEL:从设备片选使能信号。如果从设备是低电平使能的话,当拉低这个引脚后,从设备就会被选中,主机和这个被选中的从机进行通信。

    SCLK:时钟信号,由主机产生,和 I2C通信的 SCL 有点类似。

    MOSI:主机给从机发送指令或者数据的通道。

    MISO:主机读取从机的状态或者数据的通道。

    在某些情况下,我们也可以用 3 根线的 SPI 或者 2 根线的 SPI 进行通信。比如主机只给从机发送命令,从机不需要回复数据的时候,那么 MISO 就可以不要;而在主机只读取从机的数据,不需要给从机发送指令的时候,那 MOSI 就可以不要;当一个主机一个从机的时候,从机的片选有时可以固定为有效电平而一直处于使能状态,那么 SSEL 就可以不要;此时如果再加上主机只给从机发送数据,那么 SSEL 和 MISO 都可以不要;如果主机只读取从机送来的数据,SSEL 和 MOSI 都可以不要。

    3 线和 2 线的 SPI 大家要知道怎么回事,实际使用也是有应用的,但是当我们提及 SPI的时候,一般都是指标准 SPI,都是指 4 根线的这种形式。

    SPI 通信的主机也是我们的单片机,在读写数据时序的过程中,有四种模式,要了解这四种模式,首先我们得学习以下两个名词。

    CPOL:Clock Polarity,就是时钟的极性。时钟的极性是什么概念呢?通信的整个过程分为空闲时刻和通信时刻,如果 SCLK 在数据发送之前和之后的空闲状态是高电平,那么就是CPOL=1,如果空闲状态 SCLK 是低电平,那么就是 CPOL=0。

    CPHA:Clock Phase,就是时钟的相位。

    主机和从机要交换数据,就牵涉到一个问题,即主机在什么时刻输出数据到 MOSI 上而从机在什么时刻采样这个数据,或者从机在什么时刻输出数据到 MISO 上而主机什么时刻采样这个数据。同步通信的一个特点就是所有数据的变化和采样都是伴随着时钟沿进行的,也就是说数据总是在时钟的边沿附近变化或被采样。而一个时钟周期必定包含了一个上升沿和一个下降沿,这是周期的定义所决定的,只是这两个沿的先后并无规定。又因为数据从产生的时刻到它的稳定是需要一定时间的,那么,如果主机在上升沿输出数据到 MOSI 上,从机就只能在下降沿去采样这个数据了。反之如果一方在下降沿输出数据,那么另一方就必须在上升沿采样这个数据。

    CPHA=1,就表示数据的输出是在一个时钟周期的第一个沿上,至于这个沿是上升沿还是下降沿,这要视 CPOL 的值而定,CPOL=1 那就是下降沿,反之就是上升沿。那么数据的采样自然就是在第二个沿上了。

    CPHA=0,就表示数据的采样是在一个时钟周期的第一个沿上,同样它是什么沿由 CPOL决定。那么数据的输出自然就在第二个沿上了。仔细想一下,这里会有一个问题:就是当一帧数据开始传输第一个 bit 时,在第一个时钟沿上就采样该数据了,那么它是在什么时候输出来的呢?有两种情况:一是 SSEL 使能的边沿,二是上一帧数据的最后一个时钟沿,有时两种情况还会同时生效。

    我们以 CPOL=1/CPHA=1 为例,把时序图画出来给大家看一下,如图 15-1 所示。
    图15-1  SPI 通信时序图(一)
    图15-1  SPI 通信时序图(一)

    大家看图 15-1 所示,当数据未发送时以及发送完毕后,SCK 都是高电平,因此 CPOL=1。可以看出,在 SCK 第一个沿的时候,MOSI 和 MISO 会发生变化,同时 SCK 第二个沿的时候,数据是稳定的,此刻采样数据是合适的,也就是上升沿即一个时钟周期的后沿锁存读取数据,即 CPHA=1。注意最后最隐蔽的 SSEL 片选,这个引脚通常用来决定是哪个从机和主机进行通信。剩余的三种模式,我们把图画出来,简化起见把 MOSI 和 MISO 合在一起了,大家仔细对照看看研究一下,把所有的理论过程都弄清楚,有利于你对 SPI 通信的深刻理解,如图 15-2 所示。
    图15-2  SPI 通信时序图(二)
    图15-2  SPI 通信时序图(二)

    在时序上,SPI 是不是比 I2C要简单的多?没有了起始、停止和应答,UART 和 SPI 在通信的时候,只负责通信,不管是否通信成功,而 I2C却要通过应答信息来获取通信成功失败的信息,所以相对来说,UART 和 SPI 的时序都要比 I2C简单一些。
    展开全文
  • 简述SPI通信协议-01

    2020-07-21 08:55:57
    简述SPI通信协议,基于STM32。

    What is SPI?

    SPI:Serial Peripheral interface 串行外围设备接口。

    SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线。

    SPI 接口一般使用 4 条线通信

    MISO :主设备数据输入,从设备数据输出。

    MOSI :主设备数据输出,从设备数据输入。

    SCLK :时钟信号,由主设备产生。

    CS     :从设备片选信号,由主设备控制。

    CPOL极性

    SPI的CPOL,表示当SCLK空闲idle的时候,其电平的值是低电平0还是高电平1:

    CPOL=0,时钟空闲idle时候的电平是低电平,所以当SCLK有效的时候,就是高电平,就是所谓的active-high;

    CPOL=1,时钟空闲idle时候的电平是高电平,所以当SCLK有效的时候,就是低电平,就是所谓的active-low;

    CPHA相位

    CPHA=0,表示第一个边沿:

    对于CPOL=0,idle时候的是低电平,第一个边沿就是从低变到高,所以是上升沿;

    对于CPOL=1,idle时候的是高电平,第一个边沿就是从高变到低,所以是下降沿;

    CPHA=1,表示第二个边沿:

    对于CPOL=0,idle时候的是低电平,第二个边沿就是从高变到低,所以是下降沿;

    对于CPOL=1,idle时候的是高电平,第一个边沿就是从低变到高,所以是上升沿;

    上升沿发送、下降沿接收、高位先发送;

    数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取;

     

    • 硬件上为4根线;

    • 主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输;

    • 串行移位寄存器通过MOSI信号线将字节传送给从机,同时从机也将自己的串行移位寄存器中的内容通过MISO信号线返回给主机。这样,两个移位寄存器中的内容就被交换;

    • 外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。

    STM32的SPI接口-SPI接口的框图

     

    STM32的SPI接口通过4个引脚与外部器件相连,与标准的SPI协议是一致的:

    MISO:主设备输入/从设备输出引脚。该引脚在从模式下发送数据,在主模式下接收数据;

    MOSI:主设备输出/从设备输入引脚。该引脚在主模式下发送数据,在从模式下接收数据;

    SCK:串口时钟,作为主设备的输入,从设备的输入;

    NSS:从设备选择。这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。

    展开全文
  • SPI通信协议参考

    2019-08-23 16:12:56
    串行外设接口(SPI)是微控制器和外围IC(如传感器、ADC、DAC、移位寄存器、SRAM等)之间使用最广泛的接口之一。本文先简要说明SPI接口,然后介绍ADI公司支持SPI的模拟开关与多路转换器,以及它们如何帮助减少系统电路...
  • SPI通信协议详解

    2019-05-07 09:49:18
    1、什么是SPISPI是串行外设接口(Serial Peripheral Interface)的缩写。...没有指定的流控制,没有应答机制确认是否接收到数据,所以跟IIC总线协议比较在数据可靠性上有一定的缺陷。 4、特点 1)...
  • 通信协议篇——SPI通信

    千次阅读 2020-02-12 19:21:05
    通信协议篇——SPI通信
  • MPU6050开发 -- 进阶之I2C/SPI通信协议

    万次阅读 多人点赞 2017-11-23 10:28:35
    上一篇基本概念讲了一通,大体上对MPU6050有了一个了解。对于MPU6050开发来讲主要的应该就是 I2C/SPI 通信和...接下来我们继续看芯片手册,简单了解一下I2C/SPI通信协议。(S5PV210开发里再综合详讲) I2C 和SPI...
  • STM32——SPI通信协议(W25Q128FLASH的通信)

    千次阅读 多人点赞 2018-11-23 18:28:19
    目录 SPI协议 ...串行外设接口(Serial Peripheral Interface Bus,SPI),是一种用于短程通信的同步串行通信接口规范,主要应用于单片机系统中。类似I2C。 这种接口首先被Motorola(摩托罗拉)公司开...
  • 文章目录(一)SPI协议简介(二)SPI物理层(三)SPI协议层3.1、SPI基本通信过程3.2、通信的起始和终止信号3.3、数据有效性3.4、CPOL/CPHA及通信模式(四)STM32的SPI特性及架构4.1、STM32的SPI外设简介4.2、STM32的...
  •  我们的主设备能够控制时钟,因为我们的SPI通信并不像UART或者IIC通信 那样有专门的通信周期,有专门的通信起始信号,有专门的通信结束信号;所以我们的 SPI协议能够通过控制时钟信号线,当没有数据交流的时候...
  • 详细剖析I2C和SPI通信协议的区别

    千次阅读 2018-01-04 10:32:13
    原文链接:http://m.elecfans.com/article/610220.html1. 概述I2C与SPI协议 IIC vs SPI现今,在低端数字通信应用领域,我们随处可见IIC (Inter-...原因是这两种通信协议非常适合近距离低速芯片间通信。Philips(for II
  • i2c和spi通信协议的特点及区别

    千次阅读 2018-08-30 15:30:23
    i2c是由Philips公司提出的双线多主机、同步、半双工、串行低速率、非差分信号的通信总线。广泛应用于传输速率要求不高、传输距离短的场合,最大优势是可以在总线上扩展多个外围设备的支持。如soc外部的各外围设备与...
  • SPI协议通信

    2018-11-16 22:44:39
    SPI通信协议 SPI是同步串行通信接口。 SPI是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口。SPI是一种高速的、全双工、同步通信总线,标准的SPI也仅仅使用4个引脚,常用于单片机和EEPROM、...
  • SPI总线通信协议

    2019-02-25 15:08:18
    SPI是一种高速的、全双工、同步通信总线,标准SPI也仅仅使用4个引脚,常用于单片机和EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信SPI主要是主从方式通信,这种模式通常只有一个主机和一个或者多个从机...
  • MOTOROLA的SPI标准协议

    2020-12-03 14:50:51
    该文档是MOTOROLA的SPI标准协议,V3.06版本,非常适合学习SPI的工程师学习使用。如有问题请联系我。
  • 1. 前言  鉴于之前的博客有详细的讲解到标准...而我们的spi号称是支持高速数据收发的一种协议,这样的时钟速率感觉是对不起他的学名咯。  其实不然,每个项目都是不一样的,一切项目都不能只为追求快,而应该是追求
  • SPI通信原理及通信协议

    千次阅读 2012-11-21 14:48:59
    SPI:高速同步串行口。3~4线接口,收发独立、可同步进行. SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。...SPI,是一种高速的,全双工,同步的通信总线,并且在芯
  • SPI通信

    2016-12-14 10:40:44
    UART、I2C和 SPI 是单片机系统中最常用的三种通信协议。前边我们已经学了 UART 和I2C通信协议,这节课我们来学习剩下的 SPI 通信协议。  SPI 是英语 Serial Peripheral Interface 的缩写,顾名思义就是串行外围...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,543
精华内容 3,817
关键字:

spi通信协议标准