S32K144 + FreeRTOS + SPI + IAR

開發環境: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);
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章