Cypress-CYT4B-Mcal配置说明(三)Spi模块配置

有关AutoSar中对于Spi模块的相关描述可参考:Autosar MCAL-SPI配置及使用_spi总线的mcal配置-优快云博客

配置Spi模块前,往往要参考从机芯片的芯片手册和项目需求,确定通讯参数。

PhyUnit、 Channel、 ExternalDevice、 Job和Sequence的关系如下图所示:

Spi功能的配置顺序为:

  1. 配置Port模块中MISIO、MOSI、CLK和CS四个引脚。
  2. 配置ExternalDevice,并关联要使用的Spi硬件单元。
  3. 配置Channel。
  4. 配置Job,包含进去一个或多个Channel,并关联一个ExternalDevice。
  5. 配置Sequence,包含进去一个或多个job。

Port配置

MISO

MOSI

CLK

CS

SpiExternalDevice配置

SpiExternalDevice中主要配置通讯相关的大部分Spi硬件参数。

SpiHWUnit配置

选择关联的Spi硬件单元:SCB0-SCB10。

时钟参考点与波特率配置

首先要到MCU模块中配置SCB3的PCLK时钟。

接着配置SCB3的时钟参考点。

在SpiExternalDevice中引用参考点。

波特率能配置的最大值为参考的PCLK值除以4,最小值为PCLK除以16。

(建议参考的PCLK配置频率小一些,否则可能会出现输出时钟占空比不为50%的情况)。

片选配置

  • SpiEnableCs:是否需要控制CS。勾选该选项后,下面两项才可配置。

  • SpiCsSection:选择CS_VIA_PERIPHERAL_ENGINE(通过硬件外设控制)

    或者CS_VIA_GPIO(通过Spi驱动程序的通用IO控制)。

  • SpiCsIdentifier:若通过GPIO控制,则该项选择的是Dio模块中配置的通道。

    若通过硬件外设控制,则该项选择的是SPI_SELECT0-SPISELECT3。

片选极性、时钟相位、时钟极性配置

SpiEnableCs中选择CS_VIA_PERIPHERAL_ENGINE才需要配置这三项。

  • SpiCsPolarity:片选极性,即Cs引脚有效时输出高电平还是低电平。
  • SpiDataShiftEdge:选择LEADING,在第二个边沿输出数据,第一个边沿采样数据,对应CPHA=0。
    选择TRALING,在第一个边沿输出数据,第二个边沿采样数据,对应CPHA=1。

(CPHA= 0和CPHA= 1的区别可参考SPI中的CPHA,CPOL详解-优快云博客。)

  • SpiShiftClockIdleLevel:时钟极性,即CLK时钟空闲时的电平为高或低。

SetupDelay、HoldupDelay配置

  • SpiSetupDelay:开始传输数据时第一次选中CS到第一次拉高时钟线的时间,
  • SpiHoldDelay:传输数据完成释放时钟线到释放CS的时间。

EB中SpiSetupDelay可设置为1.25或0.25,SpiHoldDelay可设置为1.75或0.75,表示的是相对于CLK一个时钟周期的倍数。

SpiChannel配置

  • SpiChannelType:通道类型,EB(外部通道)/IB(内部通道)。

EB和IB区别如下:

类型区别
EB收发数据的buffer由用户(静态/动态的)提供,数据长度可输入
IB收发数据的buffer由SPI Driver提供,数据长度固定
  • SpiDataWidth:数据宽度,等价于传输数据的帧大小。
  • SpiDefaultData:当传递给Spi_WriteIB(对于内部缓冲区)或Spi_SetupEB(对于外部缓冲区)的指针为NULL 时,要传输的默认数据。
  • SpiEbMaxLength:当配置为EB类型时,允许通过Spi_SetupEB( )设置的最大数据长度。
  • SpiIbNBuffers:当配置为IB类型时,Spi驱动程序内部为通道分配的缓冲区长度。

** 举例:当选择DataWidth为8,IbNBuffers为10时,Spi驱动程序内部将生成类型为uint8,长度为10的接收数组和发送数组;当选择DataWidth为16,IbNBuffers为10时,程序内部将生成类型为uint8,长度为20的接收数组和发送数组。**

.

  • SpiTransferStart :每一帧数据的传输方向,MSB(先传输高位)/LSB(先传输低位)。

假如要发送的数据为0101,MSB会按0101的顺序发送,LSB则是按1010的顺序发送。

SpiJob配置

  • SpiHwUnitSynchronous:设置为SYNCHRONOUS,SpiJob以同步方式使用驱动程序(使用Spi_SyncTransmit( )传输数据)。
    设置为ASYNCHRONOUS,SpiJob以异步方式使用驱动程序(使用
    Spi_AsyncTransmit( )传输数据)。

  • SpiJobEndNotification:选择是否开启Job结束中断函数,开启则需要填入函数的名称。

  • SpiJobPriority:Job优先级,可设置1-3。

Job被认为是原子的,不能被打断。但是含有更高优先级Job的Sequence可以打断当前Sequence。

  • SpiDeviceAssignment :引用要关联的ExternalDevice。

在ChannelList中引用要包含的Channel。

SpiSequence配置

  • SpiInterruptibleSequence:是否允许该序列被其他序列打断。
  • SpiSeqEndNotification:选择是否开启序列结束中断函数,开启则需要填入函数的名称。

在jobAssignment中引用要包含的Job。

SpiGeneral配置

SpiChannelBuffersAllowed :选择允许分配的缓冲区类型。

  • 0:只允许内部缓冲区IB。
  • 1:只允许外部缓冲区EB。
  • 3:同时允许内部缓冲区IB和外部缓冲区EB。

SpiLevelDelivered :Spi驱动程序传输等级。

  • 0:简单同步SPI处理程序/驱动程序,只允许同步方式。
  • 1:基本异步SPI处理器/驱动程序,只允许异步方式。
  • 3:增强的(同步/异步)SPI处理器/驱动程序。

使用示例

同步传输、EB

初始化

Std_ReturnType Ret_Val1,Ret_Val2;
Spi_DataBufferType u8TXBuff[4U] = {0x66u,0x77u,0x66u,0x77u};/*发送缓冲区*/
Spi_DataBufferType u8RXBuff[4U] ; /*接收缓冲区*/
void bsp_Init_1(void)
{
    Mcu_Init(&McuConf_McuModuleConfiguration_McuModuleConfiguration_0);
    Mcu_SetMode(McuConf_McuModeSettingConf_McuModeSetting_CM7_0_Active);
    Mcu_InitClock(McuConf_McuClockSettingConfig_McuClockSettingConfig_Active);
    while(Mcu_GetPllStatus() != MCU_PLL_LOCKED)
    {
    }
    Mcu_DistributePllClock();
    Port_Init(&PortConf_PortConfigSet_PortConfigSet_0);      /* PORT 初始化 */
    Spi_Init(NULL);                                          /* Spi 初始化 */
    /* Cpt 初始化,开启10ms中断函数 */
    Gpt_Init(&GptConf_GptChannelConfigSet_GptChannelConfigSet_0);
    Gpt_EnableNotification(GptConf_GptChannelConfiguration_Timer_16bit_1kHz);
    Gpt_StartTimer(GptConf_GptChannelConfiguration_Timer_16bit_1kHz, 10-1);
}

在10ms中断函数中调用

void Gpt_Notification_Timer_16bit_1KHz(void)
{
    Ret_Val1 = Spi_SetupEB(SpiChannel_HSD_1,u8TXBuff,u8RXBuff,4U);/*设定EB通道的数据,长度为4*/
    Ret_Val2 = Spi_SyncTransmit(SpiSequence_HSD_1);/*同步方式传输序列*/
}

同步传输、IB

初始化

Std_ReturnType Ret_Val1,Ret_Val2,Ret_Val3;
Spi_DataBufferType u8TXBuff[4U] = {0x66u,0x77u,0x66u,0x77u};/*发送缓冲区*/
Spi_DataBufferType u8RXBuff[4U] ; /*接收缓冲区*/
void bsp_Init_1(void)
{
    Mcu_Init(&McuConf_McuModuleConfiguration_McuModuleConfiguration_0);
    Mcu_SetMode(McuConf_McuModeSettingConf_McuModeSetting_CM7_0_Active);
    Mcu_InitClock(McuConf_McuClockSettingConfig_McuClockSettingConfig_Active);
    while(Mcu_GetPllStatus() != MCU_PLL_LOCKED)
    {
    }
    Mcu_DistributePllClock();
    Port_Init(&PortConf_PortConfigSet_PortConfigSet_0);      /* PORT 初始化 */
    Spi_Init(NULL);                                          /* Spi 初始化 */
    /* Cpt 初始化,开启10ms中断函数 */
    Gpt_Init(&GptConf_GptChannelConfigSet_GptChannelConfigSet_0);
    Gpt_EnableNotification(GptConf_GptChannelConfiguration_Timer_16bit_1kHz);
    Gpt_StartTimer(GptConf_GptChannelConfiguration_Timer_16bit_1kHz, 10-1);
}

在10ms中断函数中调用

void Gpt_Notification_Timer_16bit_1KHz(void)
{
    Ret_Val1 = Spi_WriteIB(SpiChannel_HSD_1,u8TXBuff);/*设定IB通道发送缓冲区*/
    Ret_Val2 = Spi_SyncTransmit(SpiSequence_HSD_1);/*同步传输*/
    Ret_Val3 = Spi_ReadIB(SpiChannel_HSD_1,u8RXBuff);/*读取IB通道数据到接收缓冲区*/ 
}

异步中断传输、EB

初始化

Std_ReturnType Ret_Val1,Ret_Val2;
Spi_DataBufferType u8TXBuff[4U] = {0x66u,0x77u,0x66u,0x77u};/*发送缓冲区*/
Spi_DataBufferType u8RXBuff[4U] ; /*接收缓冲区*/
void bsp_Init_1(void)
{
    Mcu_Init(&McuConf_McuModuleConfiguration_McuModuleConfiguration_0);
    Mcu_SetMode(McuConf_McuModeSettingConf_McuModeSetting_CM7_0_Active);
    Mcu_InitClock(McuConf_McuClockSettingConfig_McuClockSettingConfig_Active);
    while(Mcu_GetPllStatus() != MCU_PLL_LOCKED)
    {
    }
    Mcu_DistributePllClock();
    Port_Init(&PortConf_PortConfigSet_PortConfigSet_0);      /* PORT 初始化 */
    Spi_Init(NULL);                                          /* Spi 初始化 */
    Spi_SetAsyncMode(SPI_INTERRUPT_MODE);                    /*设置Spi异步模式为中断模式*/
    /* Cpt 初始化,开启10ms中断函数 */
    Gpt_Init(&GptConf_GptChannelConfigSet_GptChannelConfigSet_0);
    Gpt_EnableNotification(GptConf_GptChannelConfiguration_Timer_16bit_1kHz);
    Gpt_StartTimer(GptConf_GptChannelConfiguration_Timer_16bit_1kHz, 10-1);
}

开启SCB3中断

Cy_SysInt_SetSystemIrqVector((cy_en_intr_t)scb_3_interrupt_IRQn,Spi_Interrupt_SCB3_Cat1);/*设置中断向量*/
/*初始化中断寄存器*/
Cy_SysInt_InitIRQ( &(cy_stc_sysint_irq_t){ .sysIntSrc=(cy_en_intr_t)scb_3_interrupt_IRQn, .intIdx = CPUIntIdx4_IRQn, .isEnabled = true});    
NVIC_EnableIRQ(CPUIntIdx4_IRQn);/*设置NVIC中断*/

在10ms中断函数中调用

void Gpt_Notification_Timer_16bit_1KHz(void)
{
    Ret_Val1 = Spi_SetupEB(SpiChannel_HSD_1,u8TXBuff,u8RXBuff,4U);/*设定EB通道的数据,长度为4*/
    Ret_Val2 = Spi_AsyncTransmit(SpiSequence_HSD_1);/*异步方式传输序列*/
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值