40 Linux SPI通信问题记录

38.1 SPI简要介绍

SPI是串行外设接口(Serial Peripheral Interface)的缩写。是 Motorola 公司推出的一 种同步串行接口技术,是一种高速的,全双工同步的通信总线。

SPI是通过移位寄存器进行数据收发的,也就是由主机发起动作,如果主机进行单字节传输,主机发一个数据就会从从机中拿到一个数据,不管你愿不愿意,每发送一个数据,从机都会发一个数据过来。如果是没用的数据,那么不用管就好。所以SPI刚开始第一个字节通信时,一般拿到的是无效数据内容。所以,在通信时,一般发一个指令,然后跟地址,然后读取数据,可以避免这问题。

主机和从机模式区别在哪?答:就是谁发起时钟信号,就这样!

spi四种模式SPI的相位(CPHA)和极性(CPOL)分别可以为0或1,对应的4种组合构成了SPI的4种模式:

Mode 0 CPOL=0, CPHA=0 //0-低电平 0-第一个边缘

Mode 1 CPOL=0, CPHA=1 //0-低电平 1-第二个边缘

Mode 2 CPOL=1, CPHA=0 //1-高电平 0-第一个边缘

Mode 3 CPOL=1, CPHA=1 //1-低电平 1-第二个边缘

SPI通信的基本协议格式:操作指令-地址-(读/写)数据;

38.2 SPI主从机通信问题

最近在搞Linux和单片机(MCU)的SPI通信,其中遇到一些问题。首先Linux默认的SPI驱动是master模式,所以单片机必须选为从机模式(slave)。而SPI是全双工高速、同步(就是这个同步)通信方式,也就是说数据读写只能主机发起,从机只有干等的份。如果主机不发起时钟,从机就无法发送数据,所以难点在这里。主机需要不定时的寻问从机的操作是否完成,是否已经准备好数据,准备好之后,则需要发送时钟给从机,才能把从机中的数据收上来。

本次项目中,Linux跟MCU的SPI通信原本是觉得一下子搞定,但是因为还是不够熟悉导致项目进度没有预想那么快,所以在此记录下本次项目中遇到的问题:

1.主机发送 0x7f 0x12 0x13 时,主机收到什么就回什么数据,然后主机收到0xff 0x7f 0x12;

2.主机跟从机通信出现数据丢失,或移位问题;

以下是对于以上问题的解决及想法:

对于问题1

主机发送完0x7f 0x12 0x13之后,收到的数据却是多了一个0xff 少了一个0x13,那是因为移位寄存器的原因,你发第一个字节0x7f时,那边会把从机中SPI-DR中的0xff返回给主机,所以接收到的第一个字节是没用的。解决办法是,先发一个操作码,然后再读数据。然后还少了0x13,那是因为主机这边只发了三个时钟,0x13理论上到达了第四个时钟,所以收不到这个,如果想收到,那么就发第四个时钟就可以收到了。

对于问题2

对于现在的SPI数据收发速率可以达到50Mbps这么快,但是一般情况,我们并不会设置这么快的传输速度,原因一般有这几个:

1、PCB布板,电磁干扰信号不稳定时,需要低频率通信;

2、模拟SPI时输出端IO的驱动能力跟不上,需要降速;

3、CPU主频低,处理SPI速度慢时需要降低频率通信;

我遇到的是第三个问题,因为是Linux跟stm32单片机SPI同信,解决的方案是,先测量出MCU中但判决对于SPI中断函数处理时间,然后再调通信频率。比如:我用的是stm32f103c8t6单片机,主频72M,使用SPI1。经过测量,从进入SPI中断函数,再出来,需要21个系统时钟节拍,那也就是用时:

所以通过上述计算,我的SPI通信速度应该小于3.4Mbps才能正常通信,不掉数据。

猜你喜欢

转载自blog.csdn.net/Chasing_Chasing/article/details/105837201
40