硬件和软件准备



  • 评测RA2E1,收到的开发板是RA-Eco-RA2L1-48PIN
  • 没有接外部高速晶振,有外部低速晶振
  • 23cb16b8e2bb4113ba5d54b79ca63909.png



  • 主芯片R7FA2L1AB2DFL LQFP的封装
    谈各种常见的芯片封装技术DIP/SOP/QFP/PGA/BGA  https://blog.csdn.net/LEON1741/article/details/104783084
    捕获.PNG


  • 使用需要短接mode的1,2引脚,使用normal工作模式


  • 下载器J-LINK


  • IDE安装与工程创建参考
    【瑞萨 RA2E1】+e2studio软件下载、安装和创建工程:点亮一个LED https://mbb.eet-china.com/forum/topic/126703_1_1.html


  • 示例程序和原理图 https://gitee.com/ramcu/ra-eco-ra2-l1-48-pin
    捕获.PNG



2.LED闪烁


  • 时钟
  • 2bfe9664992749a08dc70c2604731e33.png
    XTAL 外部时钟
    SUBCLK 外部低速时钟,在低功耗模式下可以作为主时钟

板子没有焊接高速外部时钟, 这里使用片内高速时钟作为主时钟

捕获.PNG

时钟初始化和外设初始化在SystemInit函数里
裸机程序在hal_entry函数里添加用户程序
RTOS在main函数里添加

LED 100ms交替闪烁的程序

* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
  • * is called by main() when no RTOS is used.
  • **********************************************************************************************************************/
  • void hal_entry(void)
  • {
  •     /* TODO: add your own code here */
  •     while(1)
  •     {
  •         R_IOPORT_PinWrite(&g_ioport_ctrl, LED1, BSP_IO_LEVEL_HIGH);
  •         R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_LOW);
  •         R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
  •         R_IOPORT_PinWrite(&g_ioport_ctrl, LED1, BSP_IO_LEVEL_LOW);
  •         R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, BSP_IO_LEVEL_HIGH);
  •         R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
  •     }
  • #if BSP_TZ_SECURE_BUILD
  •     /* Enter non-secure code */
  •     R_BSP_NonSecureEnter();
  • #endif
  • }
  • 复制代码


    2.按键中断控制LED按键中断分为ICU和KINT

    Interrupt Controller Unit (ICU) 中断控制器单元(ICU)控制哪些事件信号连接到嵌套矢量中断控制器(NVIC)和数据传输控制器(DTC)模块。ICU还控制不可屏蔽中断。

    Key Interrupt Function (KINT)按键中断函数(KINT)通过检测按键中断输入引脚上的上升沿或下降沿来产生按键中断。
    KINT只有P100,P101,P102,P103,P1045个引脚使用
    这个板子使用的是P015作为按键,所以使用ICU
    捕获.PNG
    ICU设置
    捕获.PNG
    在stacks里新建stack,在下方的属性里设置触发电平,使能数字滤波,编写中断函数名字
    捕获.PNG



    实现按键按下后,led灯翻转代码如下:

    #include "hal_data.h"
  • #define USER_SW_IRQ_NUMBER        (0x07)      //EK_RA2L1 and EK_RA2E1 board
  • /* Boolean flag to determine switch is pressed or not.*/
  • volatile bool g_sw_press = false;
  • FSP_CPP_HEADER
  • void R_BSP_WarmStart(bsp_warm_start_event_t event);
  • FSP_CPP_FOOTER
  • /*******************************************************************************************************************//**
  • * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
  • * is called by main() when no RTOS is used.
  • **********************************************************************************************************************/
  • void hal_entry(void)
  • {
  •     /* TODO: add your own code here */
  • //    fsp_err_t err = FSP_SUCCESS;
  •     bsp_io_level_t led_current_state  = (bsp_io_level_t) 0x01;
  •     /* Initialize External IRQ driver*/
  •     /* Enable External IRQ driver*/
  •     R_ICU_ExternalIrqOpen(&g_external_irq_ctrl, &g_external_irq_cfg);
  •     R_ICU_ExternalIrqEnable(&g_external_irq_ctrl);
  •     /* Main loop */
  •     while (true)
  •     {
  •         /* Toggle user LED  when user pushbutton is pressed*/
  •         if(true == g_sw_press)
  •         {
  •             /* Clear user pushbutton flag */
  •             g_sw_press = false;
  •             /* Read user LED  pin */
  •             R_IOPORT_PinRead(&g_ioport_ctrl, LED1, &led_current_state);
  •             /* Reverse LED pin state*/
  •             led_current_state ^= BSP_IO_LEVEL_HIGH;
  •             /* Toggle user LED */
  •             R_IOPORT_PinWrite(&g_ioport_ctrl, LED1, led_current_state);
  •             R_IOPORT_PinRead(&g_ioport_ctrl, LED2, &led_current_state);
  •             led_current_state ^= BSP_IO_LEVEL_HIGH;
  •             R_IOPORT_PinWrite(&g_ioport_ctrl, LED2, led_current_state);
  •         }
  •     }
  • #if BSP_TZ_SECURE_BUILD
  •     /* Enter non-secure code */
  •     R_BSP_NonSecureEnter();
  • #endif
  • }
  • /*******************************************************************************************************************//**
  • * This function is called at various points during the startup process.  This implementation uses the event that is
  • * called right before main() to set up the pins.
  • *
  • * @param[in]  event    Where at in the start up process the code is currently at
  • **********************************************************************************************************************/
  • void R_BSP_WarmStart(bsp_warm_start_event_t event)
  • {
  •     if (BSP_WARM_START_RESET == event)
  •     {
  • #if BSP_FEATURE_FLASH_LP_VERSION != 0
  •         /* Enable reading from data flash. */
  •         R_FACI_LP->DFLCTL = 1U;
  •         /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
  •          * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
  • #endif
  •     }
  •     if (BSP_WARM_START_POST_C == event)
  •     {
  •         /* C runtime environment and system clocks are setup. */
  •         /* Configure pins. */
  •         R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
  •     }
  • }
  • /*******************************************************************************************************************//**
  • * @brief      User defined external irq callback.
  • * @param[IN]  p_args
  • * @retval     None
  • **********************************************************************************************************************/
  • void irq_ep_callback(external_irq_callback_args_t *p_args)
  • {
  •     /* Make sure it's the right interrupt*/
  •     if(USER_SW_IRQ_NUMBER == p_args->channel)
  •     {
  •         g_sw_press = true;
  •     }
  • }
  • #if BSP_TZ_SECURE_BUILD
  • BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
  • /* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
  • BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
  • {
  • }
  • #endif
  • 复制代码

    3.定时器控制LED
    [color=rgba(0, 0, 0, 0.75)]

    R7FA2L1AB2DFP定时器有PWM和通用定时器,看门狗定时器
    这里使用通用定时器,定时器是低功耗的

    捕获.PNG


    [color=rgba(0, 0, 0, 0.75)]

    通用定时器的设置如下:
    捕获.PNG

    定时器计数时间到了之后,翻转LED,可以使用R_AGT_PeriodSet重新设置翻转led的时间

    void hal_entry(void)
  • {
  •     /* TODO: add your own code here */
  •     fsp_err_t err = FSP_SUCCESS;
  • //    unsigned char rByte[BUFFER_SIZE_DOWN] = {RESET_VALUE};
  •     uint32_t time_period_ms_oneshot = RESET_VALUE;
  •     uint32_t time_period_ms_periodic = RESET_VALUE;
  •     uint32_t raw_counts_oneshot = RESET_VALUE;
  •     uint32_t raw_counts_periodic = RESET_VALUE;
  •     timer_info_t  one_shot_info =
  •     {
  •      .clock_frequency = RESET_VALUE,
  •      .count_direction = (timer_direction_t) RESET_VALUE,
  •      .period_counts = RESET_VALUE,
  •     };
  •     timer_info_t periodic_info =
  •     {
  •      .clock_frequency = RESET_VALUE,
  •      .count_direction = (timer_direction_t) RESET_VALUE,
  •      .period_counts = RESET_VALUE,
  •     };
  •     uint32_t clock_freq = RESET_VALUE;
  •     /* Initialize AGT driver */
  •     R_AGT_Open(&g_timer_one_shot_ctrl, &g_timer_one_shot_cfg);
  •     /* Open Timer1 in Periodic mode */
  •     R_AGT_Open(&g_timer_periodic_ctrl, &g_timer_periodic_cfg);
  •       time_period_ms_oneshot = 2000;
  •       /*设置LED灯闪烁时间,单位是毫秒*/
  •       time_period_ms_periodic = 100;
  •       /* Calculation of raw counts value for given milliseconds value */
  •       err = R_AGT_InfoGet(&g_timer_periodic_ctrl, &periodic_info);
  •       /* Handle error */
  •       if(FSP_SUCCESS != err)
  •       {
  •           R_AGT_Close(&g_timer_one_shot_ctrl);
  •           R_AGT_Close(&g_timer_periodic_ctrl);
  •       }
  •       /* Depending on the user selected clock source, raw counts value can be calculated
  •        * for the user given time-period values */
  •       clock_freq = periodic_info.clock_frequency;
  •       raw_counts_periodic = (uint32_t)((time_period_ms_periodic * clock_freq ) / 1000);
  •       /* Set period value */
  •       err = R_AGT_PeriodSet(&g_timer_periodic_ctrl, raw_counts_periodic);
  •       /* Handle error */
  •       if (FSP_SUCCESS != err)
  •       {
  •           R_AGT_Close(&g_timer_one_shot_ctrl);
  •           R_AGT_Close(&g_timer_periodic_ctrl);
  •       }
  •       R_AGT_Start(&g_timer_periodic_ctrl);
  •       for(;;)
  •       {
  •       }
  • }
  • 复制代码