[经验分享]

软件SPI

[复制链接]
2659|31
手机看帖
扫描二维码
随时随地手机跟帖
vivilyly|  楼主 | 2023-11-12 23:10 | 显示全部楼层 |阅读模式
SPI协议简介
SPI接口介绍
       CS:片选信号,由主设备控制从设备,,所以主设备CS信号为输出模式,从设备的CS信号为输入模式。
       MISO:主设备数据输入,从设备数据输出,所以主设备MISO信号为输入模式,从设备的MISO信号为输出模式。

SPI数据传输方向
       SPI总线传输一共有4种模式,这4种模式分别由时钟极性(CPOL)和时钟相位(CPHA)来定义。
       CPOL:规定了SCK时钟信号空闲状态的电平
       模式1:CPOL=0,CPHA =1 SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据)
       模式3:CPOL=1,CPHA =1 SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)

       MOSI上数据为1,则在此边沿从机采样(提取)数据为1,采样点在MOSI数据线的中间。

◐在时钟的第1个下降沿(游标2处)(切换点)

       MISO上数据由0切换为1,,数据在时钟下降沿时切换数据。

◐在时钟的第2~8个下降沿(切换点),主机在MISO上切换数据,从机在MOSI上切换数据

       首先来看主器件,主器件的输出口(MOSI)输出的数据bit1,在时钟的前沿被从器件采样,那主器件是在何时刻输出bit1的呢?bit1的输出时刻实际上在SCK信号有效以前,比 SCK的上升沿还要早半个时钟周期。bit1的输出时刻与SSEL信号没有关系。
       关于上面的主器件和从器件输出bit1位的时刻,可以从以下两图中得到验证。
       注意上图中,CS信号有效后(低电平有效,注意CS下降沿后发生的情况),故意用延时程序延时了一段时间,之后再向数据寄存器写入了要发送的数据,来观察主器件输出bit1的情况(MOSI)。
       通常我们进行的spi操作都是16位的。下图记录了第一个字节和第二个字节间的相互衔接的过程。
Soft_SPI.c
void SPI_Delay()        //每步的间隔 用于等待电平稳定和控制通讯速率
}

void MOSI_H()
        SOFT_SPI_MOSI = 1;
//MOSI拉低 移植时需修改
{
}

void MISO_H()
        SOFT_SPI_MISO = 1;
//MISO拉低 移植时需修改
{
}

void SPI_SCK_H()
        SOFT_SPI_SCK = 1;
//SCK拉低 移植时需修改
{
}

uint8_t MISO_Read()
        SOFT_SPI_MISO = 1;
        return SOFT_SPI_MISO;
//空闲时时钟极性(CPOL)                0为低电平 1为高电平
/* CPOL = 0, CPHA = 0, MSB first */
{
        SPI_SCK_L();
    {
                read_dat |= MISO_Read();
            MOSI_H();  
            MOSI_L();  
        SPI_Delay();
                SPI_Delay();
    }
}

uint8_t SOFT_SPI_RW_MODE1(uint8_t write_dat)
    uint8_t i, read_dat = 0;

        for(i = 0; i < 8; i++)        //循环8次
                if(write_dat & 0x80)
                else      
                write_dat <<= 1;        //低一位移位到最高位
                SPI_SCK_H();                //拉高时钟
                read_dat <<= 1;                //数据左移
                SPI_SCK_L();                //拉低时钟
        return read_dat;                //返回数据
/* CPOL=1,CPHA=0, MSB first */
{
        SPI_SCK_H();
        {
                read_dat |= MISO_Read();  
                        MOSI_H();                //若最到位为高,则输出高
                        MOSI_L();                //若最到位为低,则输出低
                SPI_Delay();
                SPI_Delay();
        }
}

uint8_t SOFT_SPI_RW_MODE3(uint8_t write_dat)
    uint8_t i, read_dat = 0;

    for( i = 0; i < 8; i++ )
        if(write_dat & 0x80)
        else                    
        write_dat <<= 1;
                SPI_SCK_L();
        read_dat <<= 1;  
        SPI_SCK_H();
    return read_dat;
Soft_SPI.h
#define SOFT_SPI_H_

#include "stdint.h"

sbit SOFT_SPI_MOSI        = P1^0;
//MOSI拉高 移植时需修改
//MOSI拉低 移植时需修改
//MISO拉高 移植时需修改
//MISO拉低 移植时需修改
//SCK拉高 移植时需修改
//SCK拉低 移植时需修改
//读取MISO电平 移植时需修改
void SPI_Delay();        //每步的间隔 用于等待电平稳定和控制通讯速率

uint8_t SOFT_SPI_RW_MODE1(uint8_t write_dat);
uint8_t SOFT_SPI_RW_MODE3(uint8_t write_dat);

#endif

使用特权

评论回复
weifeng90| | 2023-11-13 07:43 | 显示全部楼层
IO模拟SPI效率还是太低了

使用特权

评论回复
tpgf| | 2023-12-2 15:26 | 显示全部楼层
spi通讯速度的快慢收到哪些因素的制约呢

使用特权

评论回复
gwsan| | 2023-12-2 16:25 | 显示全部楼层
四线制的spi也只能是一主一从吗?

使用特权

评论回复
zljiu| | 2023-12-3 08:41 | 显示全部楼层
四线制的spi是不是不太容易模拟啊

使用特权

评论回复
tfqi| | 2023-12-3 09:27 | 显示全部楼层
使用软件模拟spi有什么优势吗

使用特权

评论回复
nawu| | 2023-12-3 10:00 | 显示全部楼层
好像是使用的普通的io口模拟的spi是吗

使用特权

评论回复
aoyi| | 2023-12-3 10:41 | 显示全部楼层
这两种方式的spi的通讯速度能相同 吗

使用特权

评论回复
uptown| | 2024-4-6 20:46 | 显示全部楼层
SPI通信协议严格定义了时钟信号(SCLK)、数据信号(MOSI)、数据使能信号(MISO)和片选信号(CS)之间的时序关系。

使用特权

评论回复
ingramward| | 2024-4-7 19:48 | 显示全部楼层
软件SPI的时序与硬件SPI有所不同。在软件SPI中,需要通过软件来控制SCK、MOSI和MISO引脚的电平变化,以实现数据的传输。

使用特权

评论回复
backlugin| | 2024-4-7 19:55 | 显示全部楼层
当使用GPIO模拟SPI时,需要通过计算来等待时钟信号CLK的变化,以正确设置比特率。如果SPI使用适配器,则波特率的设置较为简单,通常通过写入寄存器来完成。

使用特权

评论回复
robincotton| | 2024-4-8 13:18 | 显示全部楼层
优化SPI通信的代码,减少不必要的操作,提高数据传输的效率。

使用特权

评论回复
fengm| | 2024-4-8 15:12 | 显示全部楼层
软件实现SPI通信时,应当具备错误检测和处理机制,比如检测传输错误、时钟同步问题等  

使用特权

评论回复
10299823| | 2024-4-8 20:31 | 显示全部楼层
SPI通信的数据格式通常为主从模式,主设备控制时钟信号,从设备根据时钟信号的变化来发送或接收数据。数据通常在时钟的上升沿或下降沿采样,并在下一个时钟沿发送或接收。

使用特权

评论回复
mollylawrence| | 2024-4-9 09:55 | 显示全部楼层
在软件SPI中,需要明确数据的传输方向,即MOSI和MISO引脚的作用。通常情况下,MOSI引脚用于主机(主设备)向从设备发送数据,MISO引脚用于从设备向主机发送数据。

使用特权

评论回复
updownq| | 2024-4-9 15:22 | 显示全部楼层
驱动应能提供高电平或低电平选择。常见的SPI设备通常是低电平选择有效,在发送消息时选择是否变化片选信号。

使用特权

评论回复
earlmax| | 2024-4-9 16:45 | 显示全部楼层
如果有多个设备,需要确保在通信期间只选择一个设备。

使用特权

评论回复
mnynt121| | 2024-4-12 03:40 | 显示全部楼层
与硬件SPI相比,软件SPI会增加实现的复杂性,需要更多的代码来模拟硬件SPI的功能

使用特权

评论回复
febgxu| | 2024-4-12 13:09 | 显示全部楼层
软件SPI通常需要占用CPU资源来模拟硬件SPI功能,因此需要考虑CPU资源的使用情况,避免因为SPI通信占用过多资源而影响系统的其他任务。

使用特权

评论回复
cashrwood| | 2024-4-12 14:32 | 显示全部楼层
SPI通信需要使用特定的线进行连接,如SCK(时钟线)、MISO(主设备接收从设备数据线)、MOSI(主设备发送数据线)和SS(片选线)。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

1407

帖子

0

粉丝