CAN通信
前言
基于MPC5748G开发板的CAN通信
一、CAN_PAL配置
二、编写代码
1.采用轮询方式
代码如下(示例):
/* 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) */
#define TX_MAILBOX1 0UL
#define RX_MAILBOX1 1UL
#define RX_MAILBOX2 2UL
#define RX_MSG_ID1 0x7E6
#define RX_MSG_ID2 0x7DF
#define TX_MSG_ID 0x7EE
can_buff_config_t RxBuffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t TxBuffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_message_t TxMsg = {
.cs = 0U,
.id = TX_MSG_ID,
.data[0] = 0xAA,
.length = 1U
};
can_message_t RxMsg;
void pitCh0Handler(void)
{
PIT_DRV_ClearStatusFlags(INST_PIT1, 0U);
PINS_DRV_TogglePins(PTA, 1UL<<0);
PINS_DRV_TogglePins(PTA, 1UL<<10);
}
/*!
\brief The main function for the project.
\details The startup initialization sequence is the following:
* - startup asm routine
* - main()
*/
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_DRV_Init(&clockMan1_InitConfig0);
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);
INT_SYS_InstallHandler(PIT_Ch0_IRQn, &pitCh0Handler, NULL);
PIT_DRV_Init(INST_PIT1, &pit1_InitConfig);
PIT_DRV_InitChannel(INST_PIT1, &pit1_ChnConfig0);
PIT_DRV_StartChannel(INST_PIT1, 0U);
CAN_Init(&can_pal1_instance, &can_pal1_Config0);
CAN_ConfigRxBuff(&can_pal1_instance, RX_MAILBOX1, &RxBuffCfg, RX_MSG_ID1);
CAN_SetRxFilter(&can_pal1_instance, CAN_MSG_ID_STD, RX_MAILBOX1, 0);
CAN_ConfigTxBuff(&can_pal1_instance, TX_MAILBOX1, &TxBuffCfg);
for(;;)
{
RxMsg.id = 0;
CAN_Receive(&can_pal1_instance, RX_MAILBOX1, &RxMsg);
if(RxMsg.id == RX_MSG_ID1)
{
CAN_Send(&can_pal1_instance, TX_MAILBOX1, &TxMsg);
}
}
/*** 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!!! ***/
2.采用中断形式
建议采用中断方式,避免帧丢失
/* 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) */
#define TX_MAILBOX1 0UL
#define RX_MAILBOX1 1UL
#define RX_MAILBOX2 2UL
#define RX_MSG_ID1 0x7E6
#define RX_MSG_ID2 0x7DF
#define TX_MSG_ID 0x7EE
can_buff_config_t RxBuffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t TxBuffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_message_t TxMsg = {
.cs = 0U,
.id = TX_MSG_ID,
.data[0] = 0xAA,
.length = 1U
};
can_message_t RxMsg;
void pitCh0Handler(void)
{
PIT_DRV_ClearStatusFlags(INST_PIT1, 0U);
PINS_DRV_TogglePins(PTA, 1UL<<0);
PINS_DRV_TogglePins(PTA, 1UL<<10);
}
void CAN0_CallBackHandle(uint32_t instance, can_event_t eventType, uint32_t objIdx, void *driverState)
{
(void)driverState;
(void)instance;
switch(eventType)
{
case CAN_EVENT_RX_COMPLETE:
if(objIdx == RX_MAILBOX1)
{
CAN_Receive(&can_pal1_instance, RX_MAILBOX1, &RxMsg);
CAN_Send(&can_pal1_instance, TX_MAILBOX1, &TxMsg);
}
break;
case CAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
/*!
\brief The main function for the project.
\details The startup initialization sequence is the following:
* - startup asm routine
* - main()
*/
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_DRV_Init(&clockMan1_InitConfig0);
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);
INT_SYS_InstallHandler(PIT_Ch0_IRQn, &pitCh0Handler, NULL);
PIT_DRV_Init(INST_PIT1, &pit1_InitConfig);
PIT_DRV_InitChannel(INST_PIT1, &pit1_ChnConfig0);
PIT_DRV_StartChannel(INST_PIT1, 0U);
CAN_Init(&can_pal1_instance, &can_pal1_Config0);
CAN_ConfigRxBuff(&can_pal1_instance, RX_MAILBOX1, &RxBuffCfg, RX_MSG_ID1);
CAN_SetRxFilter(&can_pal1_instance, CAN_MSG_ID_STD, RX_MAILBOX1, 0);
CAN_ConfigTxBuff(&can_pal1_instance, TX_MAILBOX1, &TxBuffCfg);
CAN_InstallEventCallback(&can_pal1_instance, CAN0_CallBackHandle, NULL);
CAN_Receive(&can_pal1_instance, RX_MAILBOX1, &RxMsg);
for(;;)
{
//RxMsg.id = 0;
//CAN_Receive(&can_pal1_instance, RX_MAILBOX1, &RxMsg);
if(RxMsg.id == RX_MSG_ID2)
{
//CAN_Send(&can_pal1_instance, TX_MAILBOX1, &TxMsg);
}
if(exit_code != 0)
{
break;
}
}
/*** 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!!! ***/
3.CANoe测试
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210228140819473.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z6ODM1MzA0MjA1,size_16,color_FFFFFF,t_70)总结
通过can_pal完成简单的CAN通信。
参考代码:
/* ###################################################################
** Filename : main.c
** Processor : S32K144
** 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 needed modules to compile this module/procedure */
#include "Cpu.h"
#include "pin_mux.h"
#include "clockMan1.h"
#include "canCom1.h"
#include "dmaController1.h"
#include "osif1.h"
volatile int exit_code = 0;
/* User includes (#include below this line is not maintained by Processor Expert) */
#include <string.h>
#include <stdlib.h>
const uint8_t message1[] = "Hello World!";
const uint8_t message2[] = "Hello Board!";
const uint8_t * pMessage;
volatile bool toSend;
volatile bool dataReceived;
uint8_t rxDataBuffer[16];
void PORTC_IRQHandler(void)
{
uint32_t buttonsPressed;
buttonsPressed = PORT_HAL_GetPortIntFlag(PORTC);
switch(buttonsPressed)
{
case (1 << 12):
pMessage = message1;
toSend = true;
break;
case (1 << 13):
pMessage = message2;
toSend = true;
break;
default:
break;
}
PORT_HAL_ClearPortIntFlagCmd(PORTC);
}
void flexcan0_Callback(uint8_t instance,
flexcan_event_type_t eventType,
flexcan_state_t *flexcanState)
{
(void)flexcanState;
(void)instance;
switch(eventType)
{
case FLEXCAN_EVENT_RX_COMPLETE:
dataReceived = true;
break;
case FLEXCAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
/*!
\brief The main function for the project.
\details The startup initialization sequence is the following:
* - startup asm routine
* - main()
*/
int main(void)
{
/* Write your local variable definition here */
flexcan_data_info_t canDataInfo;
flexcan_msgbuff_t rxDataBuff;
/*** 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. ***/
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);
FLEXCAN_DRV_Init(INST_CANCOM1, &canCom1_State, &canCom1_InitConfig0);
INT_SYS_EnableIRQ(PORTC_IRQn);
GPIO_HAL_WritePin(PTD, 15, 1);
GPIO_HAL_WritePin(PTD, 16, 1);
canDataInfo.msg_id_type = FLEXCAN_MSG_ID_STD;
canDataInfo.is_remote = false;
canDataInfo.enable_brs = true;
canDataInfo.fd_enable = true;
canDataInfo.fd_padding = 0U;
canDataInfo.data_length = sizeof(message1);
FLEXCAN_DRV_ConfigTxMb(INST_CANCOM1, 0U, &canDataInfo, 1U);
FLEXCAN_DRV_ConfigRxMb(INST_CANCOM1, 1U, &canDataInfo, 0U);
FLEXCAN_DRV_InstallEventCallback(INST_CANCOM1, flexcan0_Callback, NULL);
FLEXCAN_DRV_Receive(INST_CANCOM1, 1U, &rxDataBuff);
while(1)
{
if(toSend)
{
FLEXCAN_DRV_Send(INST_CANCOM1, 0U, &canDataInfo, 1U, pMessage);
toSend = false;
}
if(dataReceived)
{
memcpy(rxDataBuffer, rxDataBuff.data, rxDataBuff.dataLen);
if(strcmp((char *)rxDataBuffer, (char *)message1) == 0)
{
GPIO_HAL_TogglePins(PTD, (1 << 16));
}
else if(strcmp((char *)rxDataBuffer, (char *)message2) == 0)
{
GPIO_HAL_TogglePins(PTD, (1 << 15));
}
else
{
GPIO_HAL_WritePin(PTD, 15, 1);
GPIO_HAL_WritePin(PTD, 16, 1);
}
FLEXCAN_DRV_Receive(INST_CANCOM1, 1U, &rxDataBuff);
dataReceived = false;
}
}
/*** 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 Freescale S32K series of microcontrollers.
**
** ###################################################################
*/