1、CAN引脚配置
点击引脚配置
选择对应的引脚
2、添加CAN组件
点击Components
点击一下右侧的can_pal,左侧会有一个CAN组件。需要几个CAN就加入几个CAN组件。这里我使用三个CAN,加入了三个CAN组件
注意:有时候建立好工程,在右侧的库中会找不到can_pal。此时关闭一下软件,重新打开即可!
3、配置CAN组件信息
需要500K的波特率,默认配置即可!
注意一下can_pal0和can_pal0_Config0的名称。代码中依据这两个名称进行配置的。
4、代码
测试三路CAN的收发功能。通过向CAN发送数据,再通过CAN将数据发出来。
/* ###################################################################
** Filename : main.c
** Processor : S32K1xx
** Abstract :
** Main module.
** This module contains user's application code.
** Settings :
** Contents :
** No public methods
**
** ###################################################################*/
/*!
** @file main.c
** @version 01.00
** @brief
** Main module.
** This module contains user's application code.
*/
/*!
** @addtogroup main_module main module documentation
** @{
*/
/* MODULE main */
/* Including necessary module. Cpu.h contains other modules needed for compiling.*/
#include "Cpu.h"
volatile int exit_code = 0;
/* User includes (#include below this line is not maintained by Processor Expert) */
/*!
\brief The main function for the project.
\details The startup initialization sequence is the following:
* - startup asm routine
* - main()
*/
#define Rx_Filter 0x0
char IRQ_CAN0_RX;
char IRQ_CAN1_RX;
char IRQ_CAN2_RX;
can_message_t recvMsg_CAN0;
can_message_t recvMsg_CAN1;
can_message_t recvMsg_CAN2;
#define RX_MAILBOX_CAN0 (0UL)
#define TX_MAILBOX_CAN0 (1UL)
#define RX_MAILBOX_CAN1 (2UL)
#define TX_MAILBOX_CAN1 (3UL)
#define RX_MAILBOX_CAN2 (4UL)
#define TX_MAILBOX_CAN2 (5UL)
/*CAN0回调函数*/
void CAN0_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState; //此处防止警报
(void)instance;
(void)buffIdx;
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //接收报文并重新注册回调函数
switch(event) //回调事件
{
case CAN_EVENT_RX_COMPLETE: //接收完成 事件
IRQ_CAN0_RX =1;
break;
case CAN_EVENT_TX_COMPLETE: //发送完成事件
break;
default:
break;
}
}
void CAN1_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)instance;
(void)buffIdx;
CAN_Receive(&can_pal1_instance, RX_MAILBOX_CAN1, &recvMsg_CAN1);
switch(event)
{
case CAN_EVENT_RX_COMPLETE:
IRQ_CAN1_RX =1;
break;
case CAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
void CAN2_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)instance;
(void)buffIdx;
CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2);
switch(event)
{
case CAN_EVENT_RX_COMPLETE:
IRQ_CAN2_RX =1;
break;
case CAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
void CAN0_Init(void)
{
CAN_Init(&can_pal0_instance, &can_pal0_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
CAN_ConfigRxBuff(&can_pal0_instance, RX_MAILBOX_CAN0, &Rx_buffCfg, Rx_Filter); //注册接收配置和MSGID过滤器(如过滤器配置为0x1,则只接受msgid 0x1发来的报文)
CAN_ConfigTxBuff(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_buffCfg); //配置发送
/*设置MSGID的掩码,掩码粗略可以理解为对11bit MSGID地址的过滤
如果某bit位需要过滤设置为1,不过滤设置为0,例如掩码设置为0x7ff则过滤全部标准id,如果设置为0x7fe,这只能接受0x01的报文(不存在0x0的地址)*/
CAN_SetRxFilter(&can_pal0_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN0,0); //设置MSGID掩码,
CAN_InstallEventCallback(&can_pal0_instance,&CAN0_Callback_Func,(void*)0); //注册回调函数
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //*****重点****此函数不只有接收作用 还有续订回调函数的作用.
}
void CAN1_Init(void)
{
CAN_Init(&can_pal1_instance, &can_pal1_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
CAN_ConfigRxBuff(&can_pal1_instance, RX_MAILBOX_CAN1, &Rx_buffCfg, Rx_Filter);
CAN_ConfigTxBuff(&can_pal1_instance, TX_MAILBOX_CAN1, &Tx_buffCfg);
CAN_SetRxFilter(&can_pal1_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN1,0);
CAN_InstallEventCallback(&can_pal1_instance,&CAN1_Callback_Func,(void*)0);
CAN_Receive(&can_pal1_instance, RX_MAILBOX_CAN1, &recvMsg_CAN1);
}
void CAN2_Init(void)
{
CAN_Init(&can_pal2_instance, &can_pal2_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
CAN_ConfigRxBuff(&can_pal2_instance, RX_MAILBOX_CAN2, &Rx_buffCfg, Rx_Filter);
CAN_ConfigTxBuff(&can_pal2_instance, TX_MAILBOX_CAN2, &Tx_buffCfg);
CAN_SetRxFilter(&can_pal2_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN2,0);
CAN_InstallEventCallback(&can_pal2_instance,&CAN2_Callback_Func,(void*)0);
CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2);
}
int main(void)
{
/* Write your local variable definition here */
/*** 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_CALLBACK_CNT);
CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); //初始化IO
CAN0_Init();
CAN1_Init();
CAN2_Init();
for(;;)
{
if(IRQ_CAN0_RX ==1 )
{
can_message_t Tx_msg = {
.cs = 0U,
.id = recvMsg_CAN0.id,
.data[0] = recvMsg_CAN0.data[0],
.data[1] = recvMsg_CAN0.data[1],
.data[2] = recvMsg_CAN0.data[2],
.data[3] = recvMsg_CAN0.data[3],
.data[4] = recvMsg_CAN0.data[4],
.data[5] = recvMsg_CAN0.data[5],
.data[6] = recvMsg_CAN0.data[6],
.data[7] = recvMsg_CAN0.data[7],
.length = recvMsg_CAN0.length
};
CAN_Send(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_msg);
IRQ_CAN0_RX =0;
}
if(IRQ_CAN1_RX ==1 )
{
can_message_t Tx_msg = {
.cs = 0U,
.id = recvMsg_CAN1.id,
.data[0] = recvMsg_CAN1.data[0],
.data[1] = recvMsg_CAN1.data[1],
.data[2] = recvMsg_CAN1.data[2],
.data[3] = recvMsg_CAN1.data[3],
.data[4] = recvMsg_CAN1.data[4],
.data[5] = recvMsg_CAN1.data[5],
.data[6] = recvMsg_CAN1.data[6],
.data[7] = recvMsg_CAN1.data[7],
.length = recvMsg_CAN1.length
};
CAN_Send(&can_pal1_instance, TX_MAILBOX_CAN1, &Tx_msg);
IRQ_CAN1_RX =0;
}
if(IRQ_CAN2_RX ==1 )
{
can_message_t Tx_msg = {
.cs = 0U,
.id = recvMsg_CAN2.id,
.data[0] = recvMsg_CAN2.data[0],
.data[1] = recvMsg_CAN2.data[1],
.data[2] = recvMsg_CAN2.data[2],
.data[3] = recvMsg_CAN2.data[3],
.data[4] = recvMsg_CAN2.data[4],
.data[5] = recvMsg_CAN2.data[5],
.data[6] = recvMsg_CAN2.data[6],
.data[7] = recvMsg_CAN2.data[7],
.length = recvMsg_CAN2.length
};
CAN_Send(&can_pal2_instance, TX_MAILBOX_CAN2, &Tx_msg);
IRQ_CAN2_RX =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!!! ***/
/* END main */
/*!
** @}
*/
/*
** ###################################################################
**
** This file was created by Processor Expert 10.1 [05.21]
** for the NXP S32K series of microcontrollers.
**
** ###################################################################
*/