前言
MPC574x是恩智浦公司出的一个系列的芯片,本人所接触的主要是MPC5742,最近在调试MPC5742的CAN通信,使用S32自带的SDK生成CAN驱动。通过网络的教程去完成,但是跟着教程走,不能跑通CAN的收发,下面就结合自己的学习过程,尽可能详细的将步骤复现出来,如有不对之处,还请指出。
创建项目
这里不做过多的解释,直接上图。
1.选择新建S32DS Application Project
2.选择芯片(我选择的是MPC5742)
3.选择SDK
这样我们就创建好我们的新项目了。
配置CAN
1.在状态栏中选择Processor Expert=》show views,打开配置界面
2.选择flexcan,双击或者右键选择Add to project
3.添加完成
4.配置CAN引脚,这里取决于实际的情况(根据芯片原理图选择)
5.打开StandBy(这个也取决于芯片原理图),将SIUL2/gpio/42勾选out。
6.配置时钟
7.CAN配置
8.生成代码
9.生成代码后都是驱动代码,需要自己去把驱动封装
封装源码
1.CAN初始化
void FlexCAN_Inital(void)
{
uint32_t mailbox = 8;
flexcan_id_table_t filterTable[8];
status_t status = 0;
status = FLEXCAN_DRV_Init(INST_CANCOM1,&canCom1_State,&canCom1_InitConfig0);
flexcan_data_info_t dataInfo =
{
.data_length = 8U,
.msg_id_type = FLEXCAN_MSG_ID_STD
};
FLEXCAN_DRV_ConfigRxFifo(INST_CANCOM1,FLEXCAN_RX_FIFO_ID_FORMAT_A,filterTable);
FLEXCAN_DRV_SetRxFifoGlobalMask(INST_CANCOM1,FLEXCAN_RX_FIFO_ID_FORMAT_A,0);
}
2.发送
void FlexCAN_SendData(uint8_t *data,uint32_t len)
{
uint32_t mailbox = 9;
flexcan_data_info_t dataInfo =
{
.data_length = len,
.msg_id_type = FLEXCAN_MSG_ID_STD
};
FLEXCAN_DRV_ConfigTxMb(INST_CANCOM1,mailbox,&dataInfo,SendID);
FLEXCAN_DRV_Send(INST_CANCOM1,mailbox,&dataInfo,SendID,data);
}
3.接收
uint8_t FlexCAN_ReceiveData(uint8_t *data)
{
flexcan_msgbuff_t recvBuff;
volatile status_t Receive_status;
Receive_status = FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recvBuff);
if(FLEXCAN_DRV_GetTransferStatus(INST_CANCOM1,0) == STATUS_BUSY)
{
if(recvBuff.msgId == ReceiveID)
{
uint8_t i;
for(i = 0; i<recvBuff.dataLen;i++)
{
data[i] = recvBuff.data[i];
}
return recvBuff.dataLen;
}
}
return 0;
}
4.main函数
#include "Cpu.h"
#include "FlexCAN.h"
volatile int exit_code = 0;
void ReceiveData(void)
{
uint8_t data[8] = {0};
uint8_t dataLen = 8;
dataLen = FlexCAN_ReceiveData(data);
if(dataLen != 0)
{
PINS_DRV_TogglePins(PTD,1<<1);
data[0] += 1;
FlexCAN_SendData(data,dataLen);
}
}
uint32_t count = 0;
int main(void)
{
/* Write your local variable definition here */
uint8_t data[8] = {0};
uint8_t dataLen = 8;
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
#ifdef PEX_RTOS_INIT
PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
#endif
/*** End of Processor Expert internal initialization. ***/
/* Write your code here */
/* For example: for(;;) { } */
CLOCK_SYS_Init(g_clockManConfigsArr,CLOCK_MANAGER_CONFIG_CNT,
g_clockManCallbacksArr,CLOCK_MANAGER_POLICY_AGREEMENT);
CLOCK_SYS_UpdateConfiguration(0U,CLOCK_MANAGER_POLICY_AGREEMENT);
CLOCK_DRV_Init(g_clockManConfigsArr[0]);
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS,g_pin_mux_InitConfigArr);
FlexCAN_Inital();
while(1)
{
count++;
if(count > 800000){
ReceiveData();
// dataLen = FlexCAN_ReceiveData(data);
// if(dataLen != 0)
// {
// PINS_DRV_TogglePins(PTD,1<<1);
// data[0] += 1;
// FlexCAN_SendData(data,dataLen);
// }
count = 0;
}
}
/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
/*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
#ifdef PEX_RTOS_START
PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
#endif
/*** End of RTOS startup code. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;) {
if(exit_code != 0) {
break;
}
}
return exit_code;
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/