昨天晚上拿到RA工作室寄过来的开发板就迫不及待的发表了开箱检测图文报告(含视频)。今天我们将对其板载的其他外设功能进行测试。
RA-Eco-RA6E2-64PIN-V1.0开发板板载两路用户LED和一路用户按键SW1,今天我们就对其进行相关测试。
RA6E2这个芯片支持多种IDE(e2_studio、IAR、Keil5等)开发,今天比对了e2_studio和Keil5的,虽然e2_studio是其官方提供的IDE,对自家芯片的兼容性比较好,但我有点用不惯,最终选择了rasc+keil进行测试开发工具。
至于开发工具的下载、安装、配置网上的教程一搜一大片,我这边就不进行介绍了,大家自行百度即可。
今天测试板子的led和按键,所以通过*使用 RA Smart Configurator 来创建 MDK 工程,步骤如下:
双击打开rasc软件,如下图:

按照图片的步骤操作后,画面如下:

按照图片的步骤操作后,画面如下:

保持默认,点击"Next"进入下一步,如下图:

保持默认,点击"Next"进入下一步,如下图:

这里选择是否使用RTOS,这里不使用,保持默认,点击"Next"进入下一步,如下图:

保持默认,点击"Finish"等待软件生成配置文件完成,如下图:

在该页面中进行外设的配置,由于只测试led和按键,查看原理图,如下:


根据原理图可知只需要配置P005引脚为输入,上拉,P207 P113为输出默认低电平即可,设置如下:



配置好引脚功能后,点击右上角的"Generate Project Content"按钮生成MDK工程及代码,如下图:

进入刚刚新建工程时保存的路径,双击"Demo.uvprojx"打开工程,如下图:

使用RASC创建的MDK工程可以编译通过,但是无法直接烧写,需要进一步配置。
使用RASC创建的MDK工程,它的默认配置里没有为芯片添加配置(比如Flash的烧写算法)。我们可以先选择任意其他芯片,再选择回我们所使用的芯片,MDK就会为这个芯片添加配置。
方法为:先点击“魔术棒”,再点击“Device”,本教程使用的是下图编号④的R7FA6M5BF,故意先点击编号③的其他芯片,再点击编号④的芯片,就可以让MDK为R7FA6E2BB添加芯片配置信息了。如下图所示:

这个时候可以编译并且下载程序进MCU中,但是在下载前我们得编写关于led和按键的程序才有意义。我们先写一段LED等交叉闪烁得代码来验证一下开发板是否能够正常工作,代码如下:
void hal_entry(void)
{
/* TODO: add your own code here */
bsp_io_level_t level = BSP_IO_LEVEL_HIGH;
while(1)
{
// R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, level);
// R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_13, !level);
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_02_PIN_07,level);
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_01_PIN_13,!level);
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
level = !level;
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
以上就是两个LED交叉500ms周期闪烁的程序。最终效果会有视频呈现。
下面我们将按键的功能加上,可以通过按键来控制led的交替闪烁,每按一次led的状态指示灯就变化一次,代码如下:
`
void hal_entry(void)
{
bsp_io_level_t level = BSP_IO_LEVEL_HIGH;
bsp_io_level_t level2 = BSP_IO_LEVEL_HIGH;
bsp_io_level_t keyStateCur = BSP_IO_LEVEL_HIGH;
bsp_io_level_t keyStatePrev = BSP_IO_LEVEL_HIGH;
while(1)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &keyStateCur);
if(keyStatePrev == BSP_IO_LEVEL_LOW && keyStateCur == BSP_IO_LEVEL_HIGH)
{
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_02_PIN_07,level);
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_01_PIN_13,!level);
level = !level;
}
keyStatePrev = keyStateCur;
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
代码通过检测按键的上升沿来控制led的状态,但是效果不是很好,发现会有误动作的情况,这是因为按键没有进入消抖程序,我们将消抖功能加上看一下效果,代码如下:
`
void hal_entry(void)
{
bsp_io_level_t level = BSP_IO_LEVEL_HIGH;
bsp_io_level_t keyStateCur = BSP_IO_LEVEL_HIGH;
bsp_io_level_t keyStatePrev = BSP_IO_LEVEL_HIGH;
while(1)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &keyStateCur);
if (keyStatePrev != keyStateCur)
{
R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &keyStateCur);
if (!keyStateCur)
{
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_02_PIN_07,level);
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_01_PIN_13,!level);
level = !level;
}
keyStatePrev = keyStateCur;
}
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
加了消抖的按键控制led效果明显就比之前的要好很多,但是我不满足现状,有两个LED,我想让其一个led可以周期闪烁,另一个受按键控制,说干就干,写代码测试,如下:
`
void hal_entry(void)
{
bsp_io_level_t level = BSP_IO_LEVEL_HIGH;
bsp_io_level_t level2 = BSP_IO_LEVEL_HIGH;
bsp_io_level_t keyStateCur = BSP_IO_LEVEL_HIGH;
bsp_io_level_t keyStatePrev = BSP_IO_LEVEL_HIGH;
while(1)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &keyStateCur);
if (keyStatePrev != keyStateCur)
{
R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS);
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &keyStateCur);
if (!keyStateCur)
{
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_02_PIN_07,level);
level = !level;
}
keyStatePrev = keyStateCur;
}
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_01_PIN_13,level2);
level2 = !level2;
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
这段代码的本意是想着能够实现其中一个led按照500ms周期闪烁,另一个led由按键控制,每按一次就变一次状态,但是并没有实现我的需求,按键必须要要按下超过500ms才有可能触发led状态变化,这里也就说明R_BSP_SoftwareDelay函数是阻塞型的延时函数。要想实现我的需求那就要一个不阻塞的延时才能完成,这要怎么办呢?
我们可以通过systick中断函数来实现这个,那我们就增加systick中断功能,并且优化一下代码实现需求,如下:
`
volatile uint64_t SysTickms = 0;
fsp_err_t SystickInit(void)
{
uint32_t uwSysclk= R_BSP_SourceClockHzGet(FSP_PRIV_CLOCK_PLL);
if(SysTick_Config(uwSysclk/1000) != 0)
{
return FSP_ERR_ASSERTION;
}
return FSP_SUCCESS;
}
void SysTick_Handler(void)
{
SysTickms += 1;
}
`
void hal_entry(void)
{
SystickInit();
bsp_io_level_t level_led1 = BSP_IO_LEVEL_HIGH;
bsp_io_level_t level_led2 = BSP_IO_LEVEL_HIGH;
bsp_io_level_t keyStateCur = BSP_IO_LEVEL_HIGH;
uint64_t key_scan_tick = SysTickms;
uint64_t led_toggle_tick = SysTickms;
uint16_t keypresstick = 0;
while(1)
{
if (key_scan_tick != SysTickms)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &keyStateCur);
if (!keyStateCur)
{
if (keypresstick++ == 10)
{
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_02_PIN_07,level_led1);
level_led1 = !level_led1;
}
}
else
{
keypresstick = 0;
}
key_scan_tick = SysTickms;
}
if (led_toggle_tick < SysTickms)
{
g_ioport.p_api->pinWrite(g_ioport.p_ctrl,BSP_IO_PORT_01_PIN_13,level_led2);
level_led2 = !level_led2;
led_toggle_tick = SysTickms + 100;
}
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
以上代码就完全满足我的需求了,在增加了systick中断功能,将其设置成1ms中断,每次进中断都对SysTickms自加1,这个也就是MCU运行的总时间,单位为ms。在主循环里每1ms扫描一下按键的状态,如果检测到按下了就开始计数,如果维持10ms以上表示按键真的按下了,而不是抖动导致,进而驱动led改变状态。另一个led任务放在100ms周期里进行改变状态。
至此,关于RA-Eco-RA6E2-64PIN-V1.0开发板的板载LED与按键的功能也就测试完毕了。其实按键还有很多功能可以测试,比如单击、双击、长按等。led也有其他功能可以测试,比如,呼吸灯、调节亮度等。这些都放在后面进行吧。