开发环境:IAR 8.30
FreeRTOS版本:10.1
- 一、移植FreeRTOS
- 二、配置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);
}
}