前篇您可点击上方的文章合集或文末的“上一篇 · 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];
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:
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 按下断开按钮。
完整工程您可以通过以下链接下载:
https://gitee.com/recn-mcu-ae/fpb_ra6e2-canfd-sample-project
更多内容,您可复制下方网址到浏览器中打开进入瑞萨中文论坛查看:
https://community-ja.renesas.com/zh/frums-groups/mcu-mpu/
1
END
1
推荐阅读
RA MCU CANFD在FSP中的配置详解
RA MCU CAN和CANFD IP介绍
CAN和CANFD协议简介(上)