文章目录
- 一、函数介绍
- 二、项目背景
- 三、函数在AUTOSAR官网中的介绍
- 四、代码实现
- 五、验证
- 六、联调过程中遇到的问题
一、函数介绍
此函数是Autosar标准中的接口,为EB SPI处理器/驱动程序设置缓冲区和数据长度的服务
指定频道。用容易理解的话说就是 设置一下某个通道的接收数据地址和发送数据地址以及数据长度的函数。
函数原型:
Std_ReturnType Spi_SetupEB ( Spi_ChannelType Channel, const Spi_DataBufferType* SrcDataBufferPtr, Spi_DataBufferType* DesDataBufferPtr, Spi_NumberOfDataType Length )
入参Channel为Channel索引号,索引号在Spi_Cfg.h里有。入参SrcDataBufferPtr为某路Channel的发送数据缓冲区地址,DesDataBufferPtr为某路Channel的接收数据缓冲区地址,Length为数据长度。
二、项目背景
写此函数的背景是目前有一个项目,需要我这边的MCU做SPI从机,SOC做主机与MCU进行SPI通信,并使用AUTOSAR标准接口实现。
三、函数在AUTOSAR官网中的介绍
首先进入到AUTOSAR官网
在Communication Drivers中即可找到关于SPI相关的介绍,可通过此访问文档。
函数的详细介绍可查看此文档进行了解。了解功能和接口定义实现一个函数基本就足够了。
四、代码实现
根据上面介绍,我们就来实现一下这个接口。并将其应用到SPI从机的代码逻辑功能中。
下面代码是当SPI来数据,SPI从机就会进入到接收中断中进行处理数据,然后将数据放入到Spi_SetupEB中的接收数据DesDataBufferPtr中。
函数实现:
Spi_ChannelObjType Spi_ChannelObj[SPI_MAX_CHANNELS];typedf struct
{Spi_DataBufferType* TxBufPtr;Spi_DataBufferType* RxBufPtr;Spi_NumberOfDataType numWordsTxRx;
}
Spi_ChannelObjType;Spi_SetupEB(spi_ChannelType Channel,Spi_DataBufferType *Src,Spi_DataBufferType *Des,Spi_NumberOfDataType Length)
{/*关全部中断*/Spi_ChannelObjType *chObj;chObj = &Spi_ChannelObj[Channel];chObj->TxBufPtr = Src;ChObj->RxBufPtr = Des;ChObj->numWordsTxRx = Length;/*开全部中断*/
}
接收中断处理代码
uint8 RxOneData;
void Spi_IrqHandler(spi_ChannelType Channel)
{RxOneData = xxxx();//xxxx()代表获取接收SPI数据的函数Spi_ChannelObj[Channel].RxBufPtr = &RxOneData;//将数据给到全局指针中
}
验证测试代码
Spi_DataBufferType TXEB[10];
Spi_DataBufferType RXEB[10];
Spi_NumberOfDataType Length = 10;Spi_SetupEB(0,TXEB,RXEB,Length);//上电后调用一次即可
//待接收中断中收到数据,即存到了EXEB中
五、验证
当调用验证代码,当SPI主机来了数据,RXEB数组中也就存放了接收到的数据。
六、联调过程中遇到的问题
1、字节间纯同步
众所周知,SPI是同步传输的,从机应跟随时钟线进行数据通信,问题是,当主机来了一个字节的数据,从机触发了中断,数据从机收到了,但是,从机的第二个字节的数据是主机第一个字节的数据,导致数据错了一位。
答:其实这不是一个问题,是没问题的,因为从机是不可能提前知道主机要给从机发什么数据的,相当于我告诉你我要打你一拳,你是不知道我打你哪里的,这也是相同的道理,不可能提前预知。但是甲方毕竟是甲方,此问题要解决。
**解决办法是:**在应用设置SpiSetupEB接口时,将第一个字节的数据放入到接收数据寄存器中,也就是提前将第一个接收数据寄存器的一个字节放入了主机要发送给我第一个数据,这样就实现数据对齐了。
2、数据错误
在本地调试没有问题,到了项目中调试出现了主机给从机发数据,不过几秒中从机就收不到数据了,经过测试,主机确实给主机发过去了,从机没有进接收中断。
**答:**这是从机MCU产生错误标志,需要将错误状态标志位给清掉之后才能再次进中断接收数据。
解决办法是:
每间隔1ms的时间查询是否产生了错误状态,如果产生了错误状态,连续读四次接收数据寄存器才能彻底清除。然后再清除错误状态寄存器。