TC264学习笔记 带DMA的SPI通信

TC264学习笔记 带DMA的SPI通信

前言

最近学习英飞凌的TC264相关知识,在使用时需要用到带DMA的SPI通信,但是逐飞和龙邱等主流的库当中的SPI都没有使用DMA功能,于是去学习iLLD库,由于是全英文的,并且网上相关资料太少,在学习时踩了不少坑。这里SPI协议、DMA之类的基础知识就不讲了。笔者对单片机了解不是很透彻,下面内容中可能有许多错误,望读者指正。

一.学习建议

1.1使用TC264的iLLD库的时候,首先使用有道翻译之类的软件进行翻译,看的时候同时对比英文版和中文版,只看机翻可能会导致部分代码被翻译了或者理解出错。

1.2iLLD例程中提到的头文件包含只讲了这个头文件本身,在调用某些函数要注意一下添加相应的头文件。

1.3iLLD例程中IfxCpu_Irq_installInterruptHandler这个函数是否调用和中断管理模式(?)有关,在龙邱和逐飞的库中无需调用。

二.初始化

2.1相关参数配置与初始化

宏定义

#define SPI_BUFFER_SIZE   //发送长度
#define BAUD              //设置波特率

//中断优先级 设置时主要不要冲突
#define IFX_INTPRIO_QSPI0_TX 99 // DMA channel 1
#define IFX_INTPRIO_QSPI0_RX 100 // DMA channel 2
#define IFX_INTPRIO_QSPI0_ER  0x30

#define IFX_INTPRIO_DMA_CH1  101
#define IFX_INTPRIO_DMA_CH2  102

首先为收发定义两个数组,在发送时请直接调用发送数组,以减少CPU的占用。

//为数据传输声明全局传输和接收缓冲区
uint8   spiTxBuffer [SPI_BUFFER_SIZE];
uint8   spiRxBuffer [SPI_BUFFER_SIZE];

设置相关变量

IfxQspi_SpiMaster spi;
IfxQspi_SpiMaster_Channel spiChannel;
IfxQspi_SpiMaster_ChannelConfig spiMasterChannelConfig;
IfxQspi_SpiMaster_Config spiMasterConfig;

2.2添加中断服务函数

IFX_INTERRUPT(qspi0TxISR, 0, IFX_INTPRIO_QSPI0_TX)
{
    
    
     IfxQspi_SpiMaster_isrTransmit(&spi);
}

IFX_INTERRUPT(qspi0RxISR, 0, IFX_INTPRIO_QSPI0_RX)
{
    
    
     IfxQspi_SpiMaster_isrReceive(&spi);
}
IFX_INTERRUPT(qspi0DmaTxISR, 0, IFX_INTPRIO_DMA_CH1 )
{
    
    
     IfxQspi_SpiMaster_isrDmaTransmit(&spi);
}

IFX_INTERRUPT(qspi0DmaRxISR, 0, IFX_INTPRIO_DMA_CH2)
{
    
    
     IfxQspi_SpiMaster_isrDmaReceive(&spi);
}
 IFX_INTERRUPT(qspi0ErISR, 0, IFX_INTPRIO_QSPI0_ER)
{
    
    
     IfxQspi_SpiMaster_isrError(&spi);

}

2.3模块初始化

//创建模块配置
    IfxQspi_SpiMaster_initModuleConfig(&spiMasterConfig, &MODULE_QSPI3); //注意 改模块时这里也要改 例程中为MODULE_QSPI0
    //设置所需的模式和最大波特率
    spiMasterConfig.base.mode             = SpiIf_Mode_master;  //主机
    spiMasterConfig.base.maximumBaudrate  = 10000000;
    // ISR优先级和中断目标(带有Dma使用)
    spiMasterConfig.base.txPriority       = IFX_INTPRIO_DMA_CH1;
    spiMasterConfig.base.rxPriority       = IFX_INTPRIO_DMA_CH2;
    spiMasterConfig.base.erPriority       = IFX_INTPRIO_QSPI0_ER;
    //dma配置
    spiMasterConfig.dma.txDmaChannelId = IfxDma_ChannelId_1;
    spiMasterConfig.dma.rxDmaChannelId = IfxDma_ChannelId_2;
    spiMasterConfig.dma.useDma = 1;
    //引脚配置
    const IfxQspi_SpiMaster_Pins pins = {
    
    
    &IfxQspi3_SCLK_P33_11_OUT , IfxPort_OutputMode_pushPull,	// SCLK 例程为IfxQspi0_SCLK_P20_11_OUT
    &IfxQspi3_MTSR_P33_12_OUT, IfxPort_OutputMode_pushPull, 	// MTSR 例程为IfxQspi0_MTSR_P20_14_OUT
    &IfxQspi3_MRSTD_P33_13_IN , IfxPort_InputMode_pullDown,     // MRST 例程为IfxQspi0_MRSTA_P20_12_IN
    IfxPort_PadDriver_cmosAutomotiveSpeed3 // pad driver mode
    };
    spiMasterConfig.pins = &pins;
    //初始化模块
    IfxQspi_SpiMaster_initModule(&spi, &spiMasterConfig);
	/*安装中断处理器 不使用
	* IfxCpu_Irq_installInterruptHandler (&qspi0TxISR IFX_INTPRIO_QSPI0_TX);
	* IfxCpu_Irq_installInterruptHandler (&qspi0RxISR IFX_INTPRIO_QSPI0_RX);
	* IfxCpu_Irq_installInterruptHandler (&qspi0ErISR IFX_INTPRIO_QSPI0_ER);
	* IfxCpu_enableInterrupts ();
	*/

2.4SPI通道初始化

	//创建通道配置
    IfxQspi_SpiMaster_initChannelConfig(&spiMasterChannelConfig, &spi);
    //设置该通道的波特率
    spiMasterChannelConfig.base.baudrate = BAUD;
    //选择引脚配置
    const IfxQspi_SpiMaster_Output slsOutput = {
    
    
            &IfxQspi3_SLSO7_P33_7_OUT,                         //cs 例程为IIfxQspi0_SLSO7_P33_5_OUT
            IfxPort_OutputMode_pushPull,
            IfxPort_PadDriver_cmosAutomotiveSpeed1
          };
    spiMasterChannelConfig.sls.output = slsOutput;

    spiMasterChannelConfig.mode =  IfxQspi_SpiMaster_Mode_short;
     //初始化通道

     IfxQspi_SpiMaster_initChannel(&spiChannel, &spiMasterChannelConfig);

至此,初始化完成。

三.数据收发

不需要发送的数据或者收到的数据使用NULL_PTR

//发送和接收数据流:
 //等待前一个数据流的传输完成
 	while(IfxQspi_SpiMaster_getStatus(&spiChannel) == SpiIf_Status_busy); 
 //接收新流
 	IfxQspi_SpiMaster_exchange(&spiChannel, spiTxBuffer, spiTxBuffer, SPI_BUFFER_SIZE);
//只发送,丢弃接收到的数据:
 //等待前一个数据流的传输完成
 	while(IfxQspi_SpiMaster_getStatus(&spiChannel) == SpiIf_Status_busy); 
 //发送新流
 	IfxQspi_SpiMaster_exchange(&spiChannel, &spiTxBuffer[i], NULL_PTR, SPI_BUFFER_SIZE); 
//只接收
 //等待前一个数据流的传输完成
	 while(IfxQspi_SpiMaster_getStatus(&spiChannel) == SpiIf_Status_busy); 
 //接收新流
 	IfxQspi_SpiMaster_exchange(&spiChannel, NULL_PTR, &spiRxBuffer[i], SPI_BUFFER_SIZE); 

猜你喜欢

转载自blog.csdn.net/qq_15535629/article/details/113447151