MPC5748G开发笔记-----CAN通信

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.
**
** ###################################################################
*/

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值