瑞萨RA2L1系列MCU简介和CAN通信应用例程

描述

 

瑞萨RA2L1系列MCU简介

RA2L1产品组基于Arm Cortex-M23 核心(现今 Arm Cortex-M系列中功耗最低的 CPU)。这款产品采用优化的制程和瑞萨电子的低功耗工艺技术,是业界一流水平的超低功耗微控制器。RA2L1产品组能够支持1.6V至5.5V宽电压工作,CPU时钟频率最高48MHz,且运行模式电流和待机模式电流更低。RA2L1产品群配备了增强型电容式触摸感应单元(CTSU2)、CAN控制器局域网总线,串行通信接口、高精度模拟电路和定时器。产品封装从48引脚到100引脚。

mcu

控制器局域网CAN模块简介

控制器局域网(CAN)模块使用基于消息的协议在电磁噪声应用中的多个从机和主机之间接收和传输数据。

该模块符合ISO11898-1(CAN2.0A / CAN2.0B)标准,最多支持32个邮箱,可配置为普通邮箱和FIFO模式下的发送或接收。支持标准(11位)和扩展(29位)消息格式。CAN模块需要额外的外部CAN收发器。

CAN模块框图

mcu

注意事项:

CAN需要外部高速晶体作为时钟源,使用CAN模块前需要先配置好外部高速时钟。

CAN模块参数规格

mcumcu

RA2L1 CAN通信应用例程

使用官方e2 studio开发工具创建RA2L1工程,并添加CAN外设模块底层应用。

mcu

配置CAN模块参数(包括通信速率、引脚配置等)。

mcu

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
");
    }
    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
");
        }
    }


    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
");
                }
            }
            /* wait for transmit flag bit to set */
            while ((true != b_can_tx) && (time_out--));
            if (0 == time_out)
            {
                __asm("BKPT #0
");
            }
            /* 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收发器应用参考原理图

mcu

使用USB-CAN工具测试CAN通信

mcu

a. 接收不到ID为0的数据

mcu

b. 禁止Mask功能后,可接收所有ID的数据.

mcu

 

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分