在Autosar标准中,SPI做为标准的通信模块,在与外设进行通讯时,经常会使用到。本文首先简单介绍SPI协议,然后详细介绍SPI在Autosar配置软件中的配置及使用。对应单片机为TC27x
网上关于SPI协议介绍有很多,具体可以自行查阅。
常用SPI通信一般由四根线组成,它们是SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)。
SDO – 主设备数据输出,从设备数据输入 对应MOSI master output slave input
SDI – 主设备数据输入,从设备数据输出 对应MISO master input slave output
SCLK – 时钟信号,由主设备产生
CS – Chip Select,从设备使能信号,由主设备控制
CS: 其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效,这就允许在同一总线上连接多个SPI设备成为可能。
SDI/SDO/SCLK: 通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。
要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。
当SPI主设备想读/写从设备时,它首先拉低从设备对应的CS线(如果CS是低电平有效)。接着开始发送工作脉冲到时钟线上,在相应的脉冲时间上,主设备把数据信号按位发到MOSI实现“写”,同时可对MISO采样而实现“读”。如下图所示:
注意:此图只是示例,不代表所有SPI的情况,因为输出和采样的边沿可能会变化。
缩写 | 含义 |
---|---|
EB | 外部缓冲通道。包含要传输的数据的缓冲区在SPI处理程序/驱动程序之外 |
IB | 内部缓冲通道。包含要传输的数据的缓冲区位于SPI处理程序/驱动程序内部。 |
Channel | SPI最小单元,其中可以配置传输长度,通道类型等。 |
Job | 一个Job是由一个或几个具有相同Chip Select(在Job处理期间不释放)的channel组成的。Job被认为是原子的,因此不能被另一个Job中断。Job具有指定的优先级。 |
Sequence | Sequence是要传输的连续Job的数量,但可以使用优先级机制在作业之间重新调度。Sequence传输是可中断的(被另一个Sequence传输),或者不依赖于静态配置。 |
LEVEL 0 | 简单同步SPI处理器/驱动程序:通信基于同步处理,采用FIFO策略处理多个访问。缓冲区的使用是可配置的,以优化和/或利用HW功能 |
LEVEL 1 | 基本异步SPI处理器/驱动程序:通信基于异步行为,并具有优先级策略来处理多个访问。缓冲区的使用是可配置的“简单同步”级别 |
LEVEL 2 | 增强的(同步/异步)SPI处理器/驱动程序:通信基于异步行为或同步处理,在执行期间使用可选择的中断或轮询机制,并具有优先级策略来处理多个访问。与其他级别一样,缓冲区的使用也是可配置的 |
下图很好的说明了Channel,Job,Sequence三者之间的关系:
一个Job可以包括多个CS相同的Channel,一个Sequence可以包含多个CS不同的Job.
SpiDriver中需要配置时钟,其他都是自动生成的
cfg中配置:
该参数表示传输数据单元的宽度。需要根据实际通信需求修改。
cfg中配置:
当(对于内部缓冲区或外部缓冲区)传递给Spi_WriteIB(对于内部缓冲区)或Spi_SetupEB(对于外部缓冲区)的指针为NULL时,传输的默认数据
cfg中配置:
在选择为EB通道的情况下,此参数仅包含数据缓冲区的最大大小(数据元素数量)。
依赖项:SPI_CHANNEL_TYPE参数必须为该通道配置为EB。
SPI_CHANNEL_BUFFERS_ALLOWED参数必须配置为1或2。
cfg中配置:
该参数用于设置IB模式下的最大数据缓冲区数量
依赖项: SPI_CHANNEL_TYPE参数必须为该通道配置为IB。SPI_CHANNEL_BUFFERS_ALLOWED参数必须配置为0或2
此处我们没有选择用IB,所以不用配置该项
此参数定义传输的第一个起始位。LSB-低位先传输,MSB-高位先传输。具体选择哪种需要看具体的应用场景。
cfg中配置:
通信外部设备的设置。与SpiJob密切相关,会被SpiJob引用。
此配置不是Autosar标准配置。用来启用或不启用qspi波特率参数的自动计算。如果参数设置为TRUE,则配置工具将根据参数SpiBaudrate自动生成波特率参数(TQ、Q、A、B、C)。该项配置后,TQ、Q、A、B、C可以不配置。
cfg中配置:
此参数是标识分配给该Job的Chip Select (CS)的符号名称。
此处CS信号我们没有选择在SPI中配置,而是直接通过配置PORT实现。
所以该配置不需要配。
当芯片选择处理被启用时(参见SpiEnableCs),那么这个参数指定芯片选择是由外设HW引擎自动处理还是通过Spi驱动程序的通用IO处理
一般都会选择CS_VIA_PERIPHERAL_ENGINE,除非对应的IO被异常占用。
cfg中配置:
此参数定义SPI数据移位边缘。数据可以在移位时钟的前沿或后沿上移位
对于一个时钟周期内,有两个edge,分别称为:
(1)Leading edge=前一个边沿=第一个边沿,对于开始电压是1,
那么就是1变成0的时候,对于开始电压是0,那么就是0变成1的时候;
(2)Trailing edge=后一个边沿=第二个边沿,对于开始电压是1,
那么就是0变成1的时候(即在第一次1变成0之后,才可能有后面的0变成1),
对于开始电压是0,那么就是1变成0的时候
在SPI协议中,有类似的定义为CPHA
CKPHA (Clock Phase) = CPHA = PHA = Phase = (时钟)相位
**不太一样的是,SpiDataShiftEdge是指的数据传输,CPHA指的是数据采样。**不过一个确定后,另外一个边沿也就跟着确定了。
启用或禁用Chip Select处理功能。如果该参数被启用,那么参数SpiCsSelection进一步详细说明了芯片选择的类型
cfg中配置:
此参数是QSPI硬件定义的IDLEA/IDLEB时间(以秒为单位)。此参数用于计算Qspi硬件延迟参数IPRE和IDLE。参数的单位为秒。
该配置需要参考具体的外设使用
cfg中配置:
当选择SpiParitySupport时,SPI数据传输/接收包含一个额外的位,使奇偶校验基于选择为偶数EVEN或奇数ODD。此处我们没有使用该功能
cfg中配置:
此参数定义SPI移位时钟空闲电平,在SPI中一般又称为极性CPOL
CKPOL (Clock Polarity) = CPOL = POL = Polarity = (时钟)极性
cfg中配置:
时钟和芯片选择CS之间的计时(以秒为单位),在英飞凌手册中也称为leading delay-此参数允许使用从0到0.0001秒的值范围。该配置需要参考具体的外设使用
cfg中配置:
此参数是QSPI硬件定义的Trailing时间(以秒为单位)在英飞凌手册中也称为trailing delay。该参数用于计算Qspi硬件延迟参数TPRE和TRAIL。该配置需要参考具体的外设使用
cfg中配置:
此参数是通知函数的引用。如果配置了Notification,则在job结束后会调用对应的函数
cfg中配置:
根据SPI093设置优先级:0,最低,3,最高优先级
cfg中配置:
配置job是同步还是异步
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I5MJRgTm-1671969044120)(https://files.mdnice.com/user/30966/bccc6c8e-2ddd-45a9-8884-2818813f73ec.png)]
配置job中的channel,一个job至少有一个channel
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQcm8SQo-1671969044120)(https://files.mdnice.com/user/30966/bd48e71f-bba9-4b00-82c0-27fff039e5be.png)]
此参数允许或不允许此序列被另一个序列挂起。依赖:这个SPI_INTERRUPTIBLE_SEQ_ALLOWED参数被配置为ON。
cfg中配置:
用于启用/禁用仅在Level 1和Level 2可编辑的并行异步传输
通过启用SpiAsyncParallelTransmit,限制适用于Autosar的使用。
Sequence不能包含属于不同QSPI模块的Job。
这个配置没用过
cfg中配置:
波特率配置选择是在Spi_Init()还是在运行时启动new job之前,一般不勾选
cfg中配置:
选择是否开启Spi_Cancel()函数,该函数用来取消指定的正在进行的序列传输。
选择允许和传递的SPI处理器/驱动程序通道缓冲区使用情况
如果通道使用IB,则选择0,如果通道使用EB,则选择为1,若两种都有使用,则选择2
cfg中配置:
选择是否开启Spi_GetHWUnitStatus函数,此函数返回指定SPI硬件微控制器外围设备的状态
cfg中配置:
打开或关闭可中断序列处理功能
SPI_LEVEL_DELIVERED需要配置为1或者2,sequence中也有对应的配置SpiInterruptibleSequence
cfg中配置:
SpiLevelDelivered为0(LEVEL0):驱动程序仅处理所有可用SPI总线(QSPIx)上的简单同步传输
SpiLevelDelivered为1(LEVEL1):驱动程序仅处理所有可用SPI总线(QSPIx)上的简单异步传输
SpiLevelDelivered是2级(LEVEL2):LEVEL2是驱动程序的增强行为,将处理同步和异步传输
一般都配置为2
cfg中配置:
队列中job的最大个数
cfg中配置:
其他配置项不是很重要,默认即可
配置SpiHwDmaConfiguration,即对应的发送和接收的DMA通道
TC27x有四路QSPI
记得在MCU中将DMA选择为SPI USE
此处我们SPI使用异步调用,中断方式。需要在OS中配置DMA,SPI的相关中断。
在EcuMDriverInitListOne中增加Spi_Init函数
在需要使用SPI的外设驱动CDD的初始化函数中,调用:
Spi_SetAsyncMode(SPI_ASYNC_MODE_INTERRUPT);
通过Spi_SetupEB函数设置发送和接收的数据,然后通过Spi_AsyncTransmit函数发送Sequence
对于Spi_SetupEB函数,使用方法如下:
Std_ReturnType Spi_SetupEB (
Spi_ChannelType Channel,
const Spi_DataBufferType* SrcDataBufferPtr,
Spi_DataBufferType* DesDataBufferPtr,
Spi_NumberOfDataType Length
)
Channel-配置的通道,一般会自动生成宏定义
SrcDataBufferPtr-输出的数据buffer指针
DesDataBufferPtr-输入的数据buffer指针
Length-发送或接收的数据长度
对于Spi_AsyncTransmit:
本文没有太多参考芯片手册,其实有时间应该再多看看芯片手册,理解的会更深刻一些。最近越来越觉得思路方法很重要,只要有想法,干就完了~