S32K148----SDK笔记----CAN收发
前面写过这个S32K flexcan组件的用法, 其实有对flexcan进一步封装的can_pal组件, 本篇就介绍下它的用法. 以CAN0(PTE4, PTE5)为例, 不用CANFD.
打开S32 Design Studio for ARM, 接下来步骤:
双击工程名, 点击Components窗口Components目录下的 pin_mux:PinSetting
, CAN配置:
Component Library中双击添加一组can_pal
组件(用几路CAN就添加几组):
can_pal1:can_pal组件默认配置如下:
上图中默认的位速率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 format
有 Format 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
can_pal 可用(拖拽)的函数有下面这些:
由于用法和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被滤掉了: