CAN的应用非常广泛,如今,许多单片机都内置了CAN控制器,为各种应用场景提供了便利。今天,我们将结合瑞萨RA2单片机的CAN控制器模块,为大家介绍一些应用案例。
瑞萨RA2L1系列MCU简介
RA2L1产品组基于Arm® Cortex®-M23 核心,是目前 Arm® Cortex-M 系列中功耗最低的CPU。这一系列产品采用了优化的制程和瑞萨电子的低功耗工艺技术,成为了业界一流水平的超低功耗微控制器。RA2L1产品组支持广泛的电压范围,从1.6V至5.5V,其CPU时钟频率最高可达48MHz,同时在运行模式和待机模式下的电流消耗更低。此外,RA2L1产品组还配备了增强型电容式触摸感应单元(CTSU2)、CAN控制器局域网总线、串行通信接口、高精度模拟电路和定时器。产品封装范围从48引脚到100引脚,满足了不同应用场景的需求。
应用案例:
-
汽车电子控制单元(ECU): 在汽车电子系统中,CAN总线是一种常见的通信协议,用于连接各种电子控制单元(ECU),如发动机控制单元、防抱死制动系统(ABS)等。利用瑞萨RA2单片机的CAN控制器模块,可以实现ECU之间的高效通信,提高汽车系统的性能和稳定性。
-
工业自动化: 在工业自动化领域,CAN总线被广泛应用于控制系统和传感器网络之间的数据通信。利用RA2单片机的CAN控制器,可以实现各种工业设备之间的实时数据传输和控制,提高生产效率和自动化水平。
-
智能家居系统: 在智能家居领域,CAN总线可以用于连接各种智能设备,如智能灯具、智能插座、智能门锁等,实现它们之间的联动和远程控制。利用瑞萨RA2单片机的CAN控制器,可以构建稳定可靠的智能家居系统,提升家居生活的舒适度和便利性。
以上仅是几个简单的应用案例,瑞萨RA2单片机的CAN控制器模块还可以在更多领域发挥作用,为各种嵌入式系统提供可靠的通信解决方案。
![image-20240403223905431](https://lxlinux.superbed.verylink.top/item/660d6a959f345e8d03fbcd44.png)
一
控制器局域网CAN模块简介
控制器局域网(CAN)模块使用基于消息的协议在电磁噪声应用中的多个从机和主机之间接收和传输数据。
该模块符合ISO11898-1(CAN2.0A / CAN2.0B)标准,最多支持32个邮箱,可配置为普通邮箱和FIFO模式下的发送或接收。支持标准(11位)和扩展(29位)消息格式。CAN模块需要额外的外部CAN收发器。
CAN模块框图
![image-20240403223910330](https://lxlinux.superbed.verylink.top/item/660d6a949f345e8d03fbc46d.png)
注意事项:
CAN需要外部高速晶体作为时钟源,使用CAN模块前需要先配置好外部高速时钟。
CAN模块参数规格
![image-20240403223920117](https://lxlinux.superbed.verylink.top/item/660d6a969f345e8d03fbd56f.png)
![image-20240403223923175](https://lxlinux.superbed.verylink.top/item/660d6a949f345e8d03fbc3b3.png)
二
RA2L1 CAN通信应用例程
使用官方e2 studio开发工具创建RA2L1工程,并添加CAN外设模块底层应用。
![image-20240403223926233](https://lxlinux.superbed.verylink.top/item/660d6a949f345e8d03fbc472.png)
配置CAN模块参数(包括通信速率、引脚配置等)。
![image-20240403223934174](https://lxlinux.superbed.verylink.top/item/660d6a969f345e8d03fbda75.png)
CAN应用参考代码
左右滑动查看完整内容
#define WAIT_TIME (500U) //wait time value
#define CAN_MAILBOX_NUMBER_TX (0U) //mail box number
#define CAN_MAILBOX_NUMBER_RX (1U)
#define CAN_FRAME_TRANSMIT_DATA_BYTES (8U) //data length
#define ZERO (0U)
/* Private global variables*/
/* Flags, set from Callback function */
static volatile bool b_can_tx = false; //CAN transmission status
static volatile bool b_can_rx = false; //CAN receive status
static volatile bool b_can_err = false; //CAN error status
/* CAN frames for tx and rx */
static can_frame_t g_can_tx_frame; //CAN transmit frame
static can_frame_t g_can_rx_frame; //CAN receive frame
void hal_entry(void)
{
/* TODO: add your own code here */
fsp_err_t err = FSP_SUCCESS;
uint32_t time_out = WAIT_TIME; // time out
uint8_t can_tx_msg[CAN_FRAME_TRANSMIT_DATA_BYTES] = {0,1,2,3,4,5,6,7};
uint8_t can_rx_msg[CAN_FRAME_TRANSMIT_DATA_BYTES] = {0};
/* Initializes the CGC module. */
err = R_CGC_Open(&g_cgc0_ctrl, &g_cgc0_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
/* Start the CGC_CLOCK_MAIN_OSC. */
err = R_CGC_ClockStart(&g_cgc0_ctrl, CGC_CLOCK_MAIN_OSC, NULL);
assert(FSP_SUCCESS == err);
/* Initialize CAN module */
err = R_CAN_Open(&g_can_ctrl, &g_can_cfg);
/* Error trap */
if(FSP_SUCCESS != err)
{
__asm("BKPT #0\n");
}
g_can_tx_frame.id = CAN_MAILBOX_NUMBER_TX;
g_can_tx_frame.type = CAN_FRAME_TYPE_DATA;
g_can_tx_frame.data_length_code = CAN_FRAME_TRANSMIT_DATA_BYTES;
/* copy the tx data frame with TX_MSG */
memcpy((uint8_t*)&g_can_tx_frame.data[ZERO], (uint8_t*)&can_tx_msg[ZERO], CAN_FRAME_TRANSMIT_DATA_BYTES);
err = R_CAN_Write(&g_can_ctrl, CAN_MAILBOX_NUMBER_TX, &g_can_tx_frame);
/* Error trap */
if (FSP_SUCCESS != err)
{
err = R_CAN_Close(&g_can_ctrl);
if (FSP_SUCCESS != err)
{
__asm("BKPT #0\n");
}
}
while(1)
{
/* check if receive flag is set */
if (true == b_can_rx)
{
/* Reset flag bit */
b_can_rx = false;
g_can_rx_frame.data[CAN_FRAME_TRANSMIT_DATA_BYTES-1] = g_can_rx_frame.id;
/* Transmit the rx data frame as acknowledging the data transfer is successful */
err = R_CAN_Write (&g_can_ctrl, CAN_MAILBOX_NUMBER_TX, &g_can_rx_frame);
/* Error trap */
if (FSP_SUCCESS != err)
{
err = R_CAN_Close(&g_can_ctrl);
if (FSP_SUCCESS != err)
{
__asm("BKPT #0\n");
}
}
/* wait for transmit flag bit to set */
while ((true != b_can_tx) && (time_out--));
if (0 == time_out)
{
__asm("BKPT #0\n");
}
/* Reset flag bit */
b_can_tx = false;
}
}
}
void can_callback(can_callback_args_t *p_args)
{
switch (p_args->event)
{
case CAN_EVENT_TX_COMPLETE:
{
b_can_tx = true; //set flag bit
break;
}
case CAN_EVENT_RX_COMPLETE:
{
b_can_rx = true;
//copy the received data to rx_frame
memcpy(&g_can_rx_frame, p_args->p_frame, sizeof(can_frame_t)); break;
}
case CAN_EVENT_MAILBOX_MESSAGE_LOST: //overwrite/overrun error event
case CAN_EVENT_BUS_RECOVERY: //Bus recovery error event
case CAN_EVENT_ERR_BUS_OFF: //error Bus Off event
case CAN_EVENT_ERR_PASSIVE: //error passive event
case CAN_EVENT_ERR_WARNING: //error warning event
{
b_can_err = true; //set flag bit
break;
}
}
}
四
CAN通信实测验证
RA2L1芯片内部只有CAN控制器,需要与外部CAN设备通信时,还需要外接CAN收发器。
CAN收发器应用参考原理图
![image-20240403224006489](https://lxlinux.superbed.verylink.top/item/660d6a949f345e8d03fbcadd.png)
使用USB-CAN工具测试CAN通信
![image-20240403224010848](https://lxlinux.superbed.verylink.top/item/660d6a969f345e8d03fbda26.png)
a. 接收不到ID为0的数据
![image-20240403224017804](https://lxlinux.superbed.verylink.top/item/660d6a949f345e8d03fbc46a.png)
b. 禁止Mask功能后,可接收所有ID的数据.
![image-20240403224014223](https://lxlinux.superbed.verylink.top/item/660d6a959f345e8d03fbccbc.png)
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !