S32K148 CAN_PAL SDK_RTM300 PE配置

文章目录

    • 前言
    • 建立工程
    • ProcessorExpert配置
    • 发送接收代码参考
    • 调试验证
    • 微信公众号

前言

S32K148----SDK笔记----CAN收发
前面写过这个S32K flexcan组件的用法, 其实有对flexcan进一步封装的can_pal组件, 本篇就介绍下它的用法. 以CAN0(PTE4, PTE5)为例, 不用CANFD.

建立工程

打开S32 Design Studio for ARM, 接下来步骤:

  • File -> New -> S32DS Application Project
  • Processors 选择 S32K148, Project Name 填你自己的工程名
  • Select SDK: SDKs 选择 S32K148_SDK 3.0.0, Debugger选择J-Link, Finish.

ProcessorExpert配置

双击工程名, 点击Components窗口Components目录下的 pin_mux:PinSetting, CAN配置:
S32K148 CAN_PAL SDK_RTM300 PE配置_第1张图片
Component Library中双击添加一组can_pal组件(用几路CAN就添加几组):
S32K148 CAN_PAL SDK_RTM300 PE配置_第2张图片
can_pal1:can_pal组件默认配置如下:
S32K148 CAN_PAL SDK_RTM300 PE配置_第3张图片
上图中默认的位速率500kbit/s, Number of buffers可选[1, 32], 默认16, 可以设置接收16个CAN ID, 改成32可以接收32个CAN ID, 一般情况下是够用的.

如果不够用, 可以勾选Enable Rx FIFO extension进行滤波器的片段(mask)过滤, 还不太会使, 如果想接收所有CAN ID, 这个, 暂时不太清楚怎么设置, 有了解的麻烦评论下.

RXFIFO ID filters number 范围(8, 16, 24, …, 104, 112, 120, 128) Rx FIFO Filters, 但其实最多104, 且这个数值越大, Number of buffers的最大值越小(会变红, 鼠标悬停提示有最大值).

RxFIFO ID filter formatFormat A, B, C, D四种选择, 解释可参考:

/*! @brief FlexCAN Rx FIFO filters number
 * Implements : flexcan_rx_fifo_id_filter_num_t_Class
 */
typedef enum {
    FLEXCAN_RX_FIFO_ID_FILTERS_8   = 0x0,         /*!<   8 Rx FIFO Filters. @internal gui name="8 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_16  = 0x1,         /*!<  16 Rx FIFO Filters. @internal gui name="16 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_24  = 0x2,         /*!<  24 Rx FIFO Filters. @internal gui name="24 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_32  = 0x3,         /*!<  32 Rx FIFO Filters. @internal gui name="32 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_40  = 0x4,         /*!<  40 Rx FIFO Filters. @internal gui name="40 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_48  = 0x5,         /*!<  48 Rx FIFO Filters. @internal gui name="48 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_56  = 0x6,         /*!<  56 Rx FIFO Filters. @internal gui name="56 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_64  = 0x7,         /*!<  64 Rx FIFO Filters. @internal gui name="64 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_72  = 0x8,         /*!<  72 Rx FIFO Filters. @internal gui name="72 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_80  = 0x9,         /*!<  80 Rx FIFO Filters. @internal gui name="80 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_88  = 0xA,         /*!<  88 Rx FIFO Filters. @internal gui name="88 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_96  = 0xB,         /*!<  96 Rx FIFO Filters. @internal gui name="96 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_104 = 0xC,         /*!< 104 Rx FIFO Filters. @internal gui name="104 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_112 = 0xD,         /*!< 112 Rx FIFO Filters. @internal gui name="112 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_120 = 0xE,         /*!< 120 Rx FIFO Filters. @internal gui name="120 Rx FIFO Filters" */
    FLEXCAN_RX_FIFO_ID_FILTERS_128 = 0xF          /*!< 128 Rx FIFO Filters. @internal gui name="128 Rx FIFO Filters" */
} flexcan_rx_fifo_id_filter_num_t;

/*! @brief FlexCAN Rx mask type.
 * Implements : flexcan_rx_mask_type_t_Class
 */
typedef enum {
    FLEXCAN_RX_MASK_GLOBAL,      /*!< Rx global mask*/
    FLEXCAN_RX_MASK_INDIVIDUAL   /*!< Rx individual mask*/
} flexcan_rx_mask_type_t;

/*! @brief ID formats for Rx FIFO
 * Implements : flexcan_rx_fifo_id_element_format_t_Class
 */
typedef enum {
    FLEXCAN_RX_FIFO_ID_FORMAT_A, /*!< One full ID (standard and extended) per ID Filter Table element.*/
    FLEXCAN_RX_FIFO_ID_FORMAT_B, /*!< Two full standard IDs or two partial 14-bit (standard and
                                      extended) IDs per ID Filter Table element.*/
    FLEXCAN_RX_FIFO_ID_FORMAT_C, /*!< Four partial 8-bit Standard IDs per ID Filter Table element.*/
    FLEXCAN_RX_FIFO_ID_FORMAT_D  /*!< All frames rejected.*/
} flexcan_rx_fifo_id_element_format_t;

由于这个还没搞懂, 先飞一会, 这里默认不勾选Enable Rx FIFO extension. S32K的CAN1, CAN2和CAN0应该是平行关系, 不太像STM32的两路CAN有主从关系, 待确认. CAN滤波器设置有兴趣的可以参考NXP论坛这篇文章, 待验证:

S32K Can Filtering: https://community.nxp.com/thread/500761

点击生成代码:
S32K148 CAN_PAL SDK_RTM300 PE配置_第4张图片

发送接收代码参考

can_pal 可用(拖拽)的函数有下面这些:
S32K148 CAN_PAL SDK_RTM300 PE配置_第5张图片
由于用法和flexcan差别不算太大, 就不分开介绍了, 代码参考如下:

/* 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) */
#define TX_STD_MAILBOX (0UL)
#define TX_EXT_MAILBOX (1UL)

can_buff_config_t stdBuffCfg = {
    .enableFD = false,
    .enableBRS = false,
    .fdPadding = 0U,
    .idType = CAN_MSG_ID_STD,
    .isRemote = false};

can_buff_config_t extBuffCfg = {
    .enableFD = false,
    .enableBRS = false,
    .fdPadding = 0U,
    .idType = CAN_MSG_ID_EXT,
    .isRemote = false};

can_message_t recvMsg;

// void can_send_msg(void)
// {
//   can_message_t message = {
//       .cs = 0U,
//       .id = TX_STD_MSG_ID,
//       .data[0] = 0x01,
//       .data[1] = 0x02,
//       .length = 2U};
//   CAN_Send(&can_pal1_instance, TX_STD_MAILBOX, &message);

//   message.id = 0x1234567;
//   message.length = 8;
//   static uint8_t kk = 0;
//   message.data[7] = kk;
//   ++kk;
//   CAN_Send(&can_pal1_instance, TX_EXT_MAILBOX, &message);
// }

//refer to can_callback_t
void canRxCallback(uint32_t instance,
                   can_event_t eventType,
                   uint32_t objIdx,
                   void *driverState)
{
  if(eventType == CAN_EVENT_RX_COMPLETE) {
    if(instance == can_pal1_instance.instIdx) {
    	if(recvMsg.id < 0x800) {	//not sure
    		CAN_Send(&can_pal1_instance, TX_STD_MAILBOX, &recvMsg);
    	} else {
    		CAN_Send(&can_pal1_instance, TX_EXT_MAILBOX, &recvMsg);
    	}
        CAN_Receive(&can_pal1_instance, objIdx, &recvMsg);
    }
  }
}
/*! 
  \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_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);

  CAN_Init(&can_pal1_instance, &can_pal1_Config0);

  CAN_ConfigTxBuff(&can_pal1_instance, TX_STD_MAILBOX, &stdBuffCfg);
  CAN_ConfigTxBuff(&can_pal1_instance, TX_EXT_MAILBOX, &extBuffCfg);

  CAN_ConfigRxBuff(&can_pal1_instance, 2, &stdBuffCfg, 0x119);
  CAN_ConfigRxBuff(&can_pal1_instance, 3, &stdBuffCfg, 0x120);
  CAN_ConfigRxBuff(&can_pal1_instance, 4, &extBuffCfg, 0x1234567);
  CAN_ConfigRxBuff(&can_pal1_instance, 5, &extBuffCfg, 0x1234568);

  CAN_InstallEventCallback(&can_pal1_instance, canRxCallback, NULL);
  CAN_Receive(&can_pal1_instance, 2, &recvMsg);
  CAN_Receive(&can_pal1_instance, 3, &recvMsg);
  CAN_Receive(&can_pal1_instance, 4, &recvMsg);
  CAN_Receive(&can_pal1_instance, 5, &recvMsg);

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

代码中, 0邮箱用于标准帧发送, 1邮箱用于扩展帧发送, 2邮箱用于接收ID为0x119的CAN报文… 邮箱数不大于上面设置的Number of buffers, 默认16, 最大可手动设置32.

接收中断中把接收到的CAN报文原封不动返还, 然后重新开始接收.

调试验证

连接CAN0到CAN分析仪, 记得总线上至少有120Ω终端电阻, 打开CAN上位机工具, 波特率设置为500k, 打开, 可以看到0x119, 0x120, 0x1234567, 0x1234568都可以正常回传, 0x121和0x1234569被滤掉了:
S32K148 CAN_PAL SDK_RTM300 PE配置_第6张图片

微信公众号

欢迎扫描关注我的微信公众号, 及时获取最新文章:
S32K148 CAN_PAL SDK_RTM300 PE配置_第7张图片

你可能感兴趣的:(S32K148)