S32K144 + FreeRTOS + SPI + IAR

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q921374795/article/details/82921601

开发环境:IAR 8.30

FreeRTOS版本:10.1

  • 一、移植FreeRTOS
  • 二、配置IAR
  • 三、配置IO、使能DMA、SPI
  • 四、创建任务、开启任务调度

一、移植FreeRTOS

  1. 从官网下载FreeRTOS源码
  2. 将..\FreeRTOS_v10_1_0\Source目录下的FreeRTOS源码复制到工程目录下
  3. 将..\FreeRTOS_v10_1_0\Source\portable\IAR\ARM_CM4F下的文件添加到工程目录下
  4. 将..\FreeRTOS_v10_1_0\Source\portable\MemMang下的一种内存管理文件添加到工程目录下
  5. 打开S32DS下FreeRTOS例程的文件夹,复制其中的FreeRTOSConfig.h到工程目录下
  6. 复制S32DS中的连接文件以及脚本文件

  

二、配置IAR

 三、配置IO、使能DMA、SPI

配置IO

       PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);

使能DMA

#define EDMA_CHN0_NUMBER   0U
#define EDMA_CHN1_NUMBER   1U
#define EDMA_CHN2_NUMBER   2U
#define EDMA_CHN3_NUMBER   3U
#define EDMA_CONFIGURED_CHANNELS_COUNT   4U

edma_state_t dmaController1_State;
edma_chn_state_t dmaController1Chn0_State;
edma_chn_state_t dmaController1Chn1_State;
edma_chn_state_t dmaController1Chn2_State;
edma_chn_state_t dmaController1Chn3_State;
edma_chn_state_t * const edmaChnStateArray[] = {
    &dmaController1Chn0_State,
    &dmaController1Chn1_State,
    &dmaController1Chn2_State,
    &dmaController1Chn3_State
};
void SPI_EDMA_init(void)
{
    edma_channel_config_t dmaController1Chn0_Config = {
        .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
        .virtChnConfig = EDMA_CHN0_NUMBER,
        .source = EDMA_REQ_LPSPI0_RX,
        .callback = NULL,
        .callbackParam = NULL
    };
    
    edma_channel_config_t dmaController1Chn1_Config = {
        .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
        .virtChnConfig = EDMA_CHN1_NUMBER,
        .source = EDMA_REQ_LPSPI0_TX,
        .callback = NULL,
        .callbackParam = NULL
    };
    
    edma_channel_config_t dmaController1Chn2_Config = {
        .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
        .virtChnConfig = EDMA_CHN2_NUMBER,
        .source = EDMA_REQ_LPSPI1_RX,
        .callback = NULL,
        .callbackParam = NULL
    };
    
    edma_channel_config_t dmaController1Chn3_Config = {
        .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
        .virtChnConfig = EDMA_CHN3_NUMBER,
        .source = EDMA_REQ_LPSPI1_TX,
        .callback = NULL,
        .callbackParam = NULL
    };
    
    const edma_channel_config_t * const edmaChnConfigArray[] = {
        &dmaController1Chn0_Config,
        &dmaController1Chn1_Config,
        &dmaController1Chn2_Config,
        &dmaController1Chn3_Config
    };
    
    const edma_user_config_t dmaController1_InitConfig0 = {
      .chnArbitration = EDMA_ARBITRATION_FIXED_PRIORITY,
      .notHaltOnError = false,
    };
    
    EDMA_DRV_Init(&dmaController1_State, &dmaController1_InitConfig0, edmaChnStateArray, 
                 edmaChnConfigArray, EDMA_CONFIGURED_CHANNELS_COUNT);
}

初始化Master--SPI

lpspi_state_t SendState;
void SPIMasterInit(void)
{
	uint32_t ret = 0;
	
	const lpspi_master_config_t Send_MasterConfig0 = {
	  .bitsPerSec = 10000000U,
	  .whichPcs = LPSPI_PCS0,
	  .pcsPolarity = LPSPI_ACTIVE_HIGH,
	  .isPcsContinuous = false,
	  .bitcount = 8U,
	  .lpspiSrcClk = 48000000U,
	  .clkPhase = LPSPI_CLOCK_PHASE_1ST_EDGE,
	  .clkPolarity = LPSPI_SCK_ACTIVE_HIGH,
	  .lsbFirst = false,
	  .transferType = LPSPI_USING_DMA,
	  .rxDMAChannel = 0U,
	  .txDMAChannel = 1U,
	  .callback = NULL,
	  .callbackParam = NULL,
	};
	
	/* SPI master configuration: clock speed: 500 kHz, 8 bits/frame, MSB first */
	ret = LPSPI_DRV_MasterInit(0, &SendState, &Send_MasterConfig0);
	
	printf("\r\n SPI Master Init : 0x%x ", ret);
	
	/* Configure delay between transfer, delay between SCK and PCS and delay between PCS 
       and SCK */
	LPSPI_DRV_MasterSetDelay(0, 1, 1, 1);
}

初始化Slave--SPI

lpspi_state_t ReceiveState;
void SPISlaveInit(void)
{
	uint32_t ret = 0;
	
	const lpspi_slave_config_t Receive_SlaveConfig0 = {
      .pcsPolarity = LPSPI_ACTIVE_HIGH,
      .bitcount = 8U,
      .clkPhase = LPSPI_CLOCK_PHASE_1ST_EDGE,
      .whichPcs = LPSPI_PCS0,
      .clkPolarity = LPSPI_SCK_ACTIVE_HIGH,
      .lsbFirst = false,
      .transferType = LPSPI_USING_DMA,
      .rxDMAChannel = 2U,
      .txDMAChannel = 3U,
      .callback = NULL,
      .callbackParam = NULL,
    };
	
	
	ret = LPSPI_DRV_SlaveInit(0, &ReceiveState, &Receive_SlaveConfig0);
	
	printf("\r\n SPI SlaveInit : 0x%x ", ret);
}

四、创建任务、开启任务调度

特别注意:

    1、关于systick:由于FreeRTOS中的时间片调度已经使能设置了systick,故不必在设置

    2、设置中断的组别:NVIC_SetPriorityGrouping(0x3);

    3、由于FreeRTOS的中断优先级较低,会影响到正常的信号量的获取等,故需在程序刚开始时调用INT_SYS_SetPriority();修改系统中所有中断的优先级

创建任务

    xTaskCreate((TaskFunction_t )IPC_task,               //任务函数 
                (const char*    )"IPC_task",             //任务名称
                (uint16_t       )IPC_TASK_STK_SIZE,      //任务堆栈大小
                (void*          )NULL,                   //传递给任务函数的参数
                (UBaseType_t    )IPC_TASK_STK_PRIO,      //任务优先级       
                (TaskHandle_t*  )&IPC_Task_Handler);     //任务句柄    

    vTaskStartScheduler();                               //开启任务调度

Master--SPI任务函数

void IPC_task(void *pvParameters)
{
    uint8_t TXBuffer[10] = {0,1,2,3,4,5,6,7,8,9};
    uint8_t RXBuffer[10] = {0};
    
    while(1)
    {
        LPSPI_DRV_MasterTransferBlocking(0, TXBuffer, RXBuffer, sizeof(TXBuffer), 10U);
        printf("\r\n Master recever 0x%x 0x%x 0x%x 0x%x ", RXBuffer[0], RXBuffer[1], 
                                                           RXBuffer[2], RXBuffer[3]);
        vTaskDelay(1000);
    }
}

Slave--SPI任务函数

void IPC_task(void *pvParameters)
{
    uint8_t TXBuffer[10] = {9,8,7,6,5,4,3,2,1,0};
    uint8_t RXBuffer[10] = {0};
    
    while(1)
    {
        LPSPI_DRV_SlaveTransfer(0, TXBuffer, RXBuffer, sizeof(RXBuffer), 10U);
        printf("\r\n Master recever 0x%x 0x%x 0x%x 0x%x ", RXBuffer[0], RXBuffer[1], 
                                                           RXBuffer[2], RXBuffer[3]);
        vTaskDelay(1000);
    }
}

猜你喜欢

转载自blog.csdn.net/q921374795/article/details/82921601