前篇您可点击上方的文章合集或文末的“上一篇 · RA MCU CANFD应用实例(上)”查看相关文章。
3.14 设置Stack
点击New Stack,选择CAN FD Lite。
3.15 它会变为红色,表示FSP配置器发现模块有错误
将鼠标指针悬停在 CAN FD lite框上并检查错误:
3.16 CANFD时钟默认为禁用状态。
切换到Clocks选项卡,将CANFDCLK设置为40MHz:
● 将PLL(锁相环)分频器改为 Div / 2
● 将PLL乘法器改为 Mul x16.0
● 将CANFDCLK改为 Src: PLL
● 将CANFDCLK分频器改为 Div /4
3.17 切回Stacks选项卡,选择CANFD lite,转至Properties选项卡
(确保当前为FSP 配置透视图 – 点击右上方
)。打开属性检查比特率。
本实例将使用自动比特率生成器的默认比特率配置。您可在Bitrate->Automatic中检查比特率。确保已禁用了“使用手动设置”。
3.18 检查实际采样点和比特率(hal_data.c)是否与应用程序的要求相匹配。
注意
● 为了获得最佳时钟容差,检查Arbitration baud_rate_prescaler和Data baud_rate_prescaler是否相同至关重要。
● 如果启用了收发器Delay Compensation,请不要使Data baud_rate_prescaler位大于 1。
3.19 我们将传输CANFD消息(msg ID:0x60),通过TX Mailbox 0(TX MB0)。
为此,我们需要修改以下参数:
● Common->Reception->Acceptance Filtering->Channel 1 Rule Count: 0(修改后可以看到Stacks Tab上的error就没有了)
● Module CAN FD Lite->Transmit Interrupts: Enable TXMB 0
● Module CAN FD Lite->Reception->Message Buffer->Number of Buffer: 1
点击Generate Project Content按键
3.20 要使用CANFD Lite堆栈,您需要先初始化CANFD模块。
为此,在hal_entry()函数中添加以下内容:
左右滑动查看更多
/* Initialize CANFD Lite driver*/ err = R_CANFD_Open(&g_canfd0_ctrl, &g_canfd0_cfg); if(FSP_SUCCESS != err) { APP_ERR_TRAP(); }
3.21 须将AFL条目设置为在应用中接收消息。
本实例需求如下:
● CANFD Bus
● Standard ID (11 bits)
● Message FIFO Buffer 0 (接收0x60 ~ 0x6F的消息ID)
在hal_entry.c文件中hal_entry()函数前复制以下const来设置AFL:
左右滑动查看更多
const canfd_afl_entry_t p_canfd0_afl[CANFD_CFG_AFL_CH0_RULE_NUM] = { { .id = { .id = 0x60, .frame_type = CAN_FRAME_TYPE_DATA, .id_mode = CAN_ID_MODE_STANDARD, }, .mask = { .mask_id = 0x7F0, .mask_frame_type = 0, .mask_id_mode = 1, }, .destination = { .minimum_dlc = CANFD_MINIMUM_DLC_0, .fifo_select_flags = CANFD_RX_FIFO_0, }, }, };
注意
RA CANFD使用AFL条目来过滤接收到的消息。我们回顾一下AFL的主要参数:
点击查看大图
3.22 在hal_entry.c文件中hal_entry()函数前添加几个变量声明和一个宏定义:
左右滑动查看更多
/* Flags to be set in Callback function */ bool b_canfd_tx_complete = false; bool b_canfd_rx_complete = false; bool b_canfd_err_status = false; /* CANFD RX and TX variables */ can_frame_t g_can_tx_frame; can_frame_t g_can_rx_frame; can_frame_t g_can_rx_frame_fifo; uint8_t tx_data[64]; #define DATA_LENGTH (64)
3.23 添加Callback函数(也可以使用拖拽的方式进行添加):
左右滑动查看更多
/* Callback function */ void canfd0_callback(can_callback_args_t *p_args) { /* TODO: add your own code here */ switch (p_args->event) { case CAN_EVENT_TX_COMPLETE: { b_canfd_tx_complete = true; //set flag bit break; } case CAN_EVENT_RX_COMPLETE: // Currently driver don't support this. This is unreachable code for now. { b_canfd_rx_complete = true; break; } case CAN_EVENT_ERR_WARNING: //error warning event case CAN_EVENT_ERR_PASSIVE: //error passive event case CAN_EVENT_ERR_BUS_OFF: //error Bus Off event case CAN_EVENT_BUS_RECOVERY: //Bus recovery error event case CAN_EVENT_MAILBOX_MESSAGE_LOST: //overwrite/overrun error event case CAN_EVENT_ERR_BUS_LOCK: // Bus lock detected (32 consecutive dominant bits). case CAN_EVENT_ERR_CHANNEL: // Channel error has occurred. case CAN_EVENT_TX_ABORTED: // Transmit abort event. case CAN_EVENT_ERR_GLOBAL: // Global error has occurred. case CAN_EVENT_FIFO_MESSAGE_LOST: // Transmit FIFO is empty. case CAN_EVENT_TX_FIFO_EMPTY: // Transmit FIFO is empty. { b_canfd_err_status = true; //set flag bit break; } } }
3.24 若传送CANFD数据,需用到CAN传输函数的选项参数。
有三个仅限CANFD的位可以启用一些独有的 CANFD 功能:
● CANFD_FRAME_OPTION_ERROR
= Error state set (ESI).
● CANFD_FRAME_OPTION_BRS
= Bit Rate Switching (BRS) enabled.
● CANFD_FRAME_OPTION_FD
= Flexible Data frame (FDF).
另外,CANFD可以增加到64字节,所以我们将DLC(数据长度代码)设为64。
在按键user_irq_callback函数if(9 == p_args->channel)中添加以下代码以发送标准数据(11 位 ID)CANFD frame。
左右滑动查看更多
/* Callback function */ void user_irq_callback(external_irq_callback_args_t *p_args) { /* TODO: add your own code here */ /* Make sure it's the right interrupt*/ if(9 == p_args->channel) { fsp_err_t err = FSP_SUCCESS; for( uint16_t i = 0; i < DATA_LENGTH; i++) { tx_data[i] = (uint8_t) (i + 1); } memcpy((uint8_t*)&g_can_tx_frame.data[0], (uint8_t*)&tx_data[0], DATA_LENGTH); g_can_tx_frame.id = 0x60; g_can_tx_frame.id_mode = CAN_ID_MODE_STANDARD; g_can_tx_frame.type = CAN_FRAME_TYPE_DATA; g_can_tx_frame.data_length_code = 64; g_can_tx_frame.options = CANFD_FRAME_OPTION_FD | CANFD_FRAME_OPTION_BRS; /* Write some data to the transmit frame */ err = R_CANFD_Write(&g_canfd0_ctrl, 0, &g_can_tx_frame); /* Handle error */ if(FSP_SUCCESS != err) { APP_ERR_TRAP(); } } }
注意
在R_CANFD_Write函数中,如果传输消息缓冲区 (TXMB) 已在使用中,则传输消息将排队。CANFD_B外围设备自动传输排队的消息,并按消息缓冲区编号或消息ID确定其优先级(请参阅 CANFD Lite堆栈传输优先级属性)。
3.25 对工程进行编译和调试。
3.26 运行代码,并按下FPB板上的S1,可以正常发送CANFD数据。
如果有CAN总线数据采集工具PCAN可以在这里进行验证,如果没有,请在下节完成后使用两块FPB板进行验证。
3.27 按下断开按钮。
注意
这两张图片用于比较Classical CAN与CANFD frames。第一张图显示CAN帧以500Kb/s的速度传输8Bytes,第二张图显示CANFD以两个比特率(标称速率为500Kb/s,FD数据速率为2Mb/s)传输64Bytes。
Classical CAN Frame:
CANFD Frame:
4
CANFD:使用FIFO接收数据
本节要点:
本节学习如何通过FIFO接收CAN消息。当对方FPB板按下S1,发送CANFD数据,可以使用FIFO正常接收CANFD数据。
4.1 打开fpb_ra6e2_canfd_lab工程中FSP配置:
4.2 切到Stacks选项卡,选择CANFD Lite,然后转到Properties选项卡(确保当前为FSP配置透视图)。
Reception FIFO 0默认为启用状态,并配置为每帧触发一次中断。您可在FSP配置器中检查配置。(Module g_canfd0 CAN FD Lite (r_canfdlite)->Reception->FIFOs->FIFO 0)
并更改如下RX FIFO参数以确保其可以接收64字节的数据。
● Reception->FIFO->FIFO 0->Payload Size: 64 Bytes
● Reception->FIFO->FIFO 0->Depth: 8 Stages
点击Generate Project Content按钮。
注意
CANFD外设具有一个有限数量的缓冲池RAM,可用于分配RX MB和FIFO等级。就RA6E2和RA4E2而言:
● 最大64-byte 存储:16则消息
● 最大8-byte 存储:60则消息
4.3 在canfd0_callback中添加以下代码以便从FIFO获取数据:
左右滑动查看更多
case CAN_EVENT_RX_COMPLETE: // Currently driver don't support this. This is unreachable code for now. { b_canfd_rx_complete = true; memcpy(&g_can_rx_frame, &p_args->frame, sizeof(can_frame_t)); break; }
注意
FIFO缓冲区中有帧时,FSP ISR Handler将会多次调用CANFD回调函数。
4.4 对工程进行编译和调试。
4.5 运行代码,并按下对方FPB板上的S1,能够正确接收到CANFD数据。
4.6 按下断开按钮。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !