本帖最后由 jf_37047872 于 2022-12-17 20:00 编辑
概述
本篇将围绕RA4M2
开发板提供的两类板载按键功能,介绍可以在这款开发板运行的程序编写方法,让大家能够独立写出一个真正属于自己的程序。
【第一部分】实体按键的使用方法
1、基本原理
对于MCU而言,想要驱动任何外部设备,必需先了解两者的物理
威廉希尔官方网站
连接方式,因此我们找到开发板上对应实体按键的部分。
通过原理图我们可以了解到,按键SW1和SW2分别与MCU的P005和P006两个引脚相连。按键未按下时,由于通过10K电阻连接到了3.3V,此时两个引脚的电压为高电平状态(可以理解成输入为1);当按键按下后,由于按键的1脚与4脚相连(4脚接地),因此两个引脚的电压为低电平状态(可以理解成输入为0)。这样,MCU通过检测两个引脚的状态,即可知道某一时刻,按键是否被按下,这就是按键的基本原理。
2、RASC配置
本次任务我们依旧采用RASC+KEIL的方式来实现。上一篇中,为了让大家尽快体验“点灯”的效果,只是简要提及了RASC的一些配置过程。为了让大家更深入地了解和掌握RASC的基本配置方法,这一篇中我会详细讲解RASC的基本配置方法和主要配置内容。
配置向导部分就不再赘述了,如果还有不会操作的可以翻看前一篇帖子,本次就从这个界面开始讲起。
在这个界面中,需要配置的主要包括BSP(已在向导中配置)、CLOCKS(时钟)、PINS(引脚)、INTERRUPTS(中断)、EVENT LINKS(事件关联)、STACKS(功能栈)、COMPONENTS(部件)等。
(1)首先要配置的是CLOCKS(时钟)选项卡。
时钟好比是MCU的心脏,从指令运行到外设动作都离不开时钟提供“节奏”信号。具体内容我们可以参考数据手册中关于时钟部分的描述,但最主要的还是要看懂时钟树!
上图左侧是关于各种时钟源的描述,所谓时钟源简单理解就是时钟信号的来源,包括芯片内部提供的高速(16/18/20MHz)、中速(8MHz)和低速(32.768KHz)时钟信号,以及外部高速时钟源(8-24MHz)和外部低速时钟源(32.768KHz),当然还包括经过PLL1(100-200MHz)和PLL2(120-240MHz)两种锁相环倍频后产生的时钟信号。
右侧主要是关于各种时钟信号的“使用者”,主要包括MCU内核、存储、片上外设以及接口时钟等。当我们在这里找到项目涉及的相关设备后,即可沿着箭头(逆向)回溯时钟信号源,中间涉及的各类寄存器就是我们要配置修改的地方了。(本例中我们保持默认配置即可)
外部时钟源一般由外接晶振提供,在这款开发板上,外接了两种频率的晶振,本篇中使用的是高速的24MHz频率的晶振。
开发板上在这里。
(2)接下来配置的是PINS(引脚)选项卡
通过原理图我们了解到,与按键SW1和SW2连接的是MCU的P005和P006两个引脚,于是我们将这两个引脚配置为输入模式;由于已经连接了外部上拉威廉希尔官方网站
,因此无需设置内部上拉;中断向量分别设置为IRQ10和IRQ11。(上一篇关于LED1、LED2和LED3引脚设置保持不变)
(3)下面我们配置STACKS(功能栈)选项卡
在这里,我们主要配置中断功能,切换至Stacks选显卡,点击“New Stack”,选择“Input”→“External IRQ(r_icu)”
选中刚才新建的STACK,在下方属性(Proper
ties)选项卡中,按照下图设置
如果Pins部分的设置中,默认为空,则可以在Pins选项卡中的Pin Number子选项卡内,按下图修改
最终的效果应该是这样的
(4)点击Generate Project Content,生成项目代码
3、代码编写
虽然绝大部分代码,RASC都已经为你自动生成好了,但对于应用逻辑部分,还是得根据你自己的设计编写一些代码的。
(1)代码框架
在正式编写代码前,我们需要先简单了解下RA代码的整体框架。
“Renesas RA Smart Configurator:Common Sources”目录中有一个文件:hal_entry.c,这是保存用户代码的文件,只有在这个文件中的内容,在重新生成代码框架后才不会被覆盖掉。
“Flex Software”目录:这里保存的是各类外部设备的底层驱动,我们可以通过修改这里的某个文件,改变对应外部设备的相关配置。
(2)设计目标
- 按下SW1按键,点亮LED1
- 按下SW2按键,熄灭LED1
(3)代码设计
首先,我们需要在主函数hal_entry()中增加一些关于LED状态和外部中断初始化的代码(重点关注附带中文注释的代码)
- void hal_entry (void)
- {
- #if BSP_TZ_SECURE_BUILD
- /* Enter non-secure code */
- R_BSP_NonSecureEnter();
- #endif
- /*设置LED01引脚P415为低电平(LED关闭)*/
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
- /* Protect PFS registers */
- R_BSP_PinAccessDisable();
- /* 配置按键01和按键02的GPIO引脚中断 */
- fsp_err_t err01 = R_ICU_ExternalIrqOpen(&g_external_irq10_ctrl, &g_external_irq10_cfg);
- fsp_err_t err02 = R_ICU_ExternalIrqOpen(&g_external_irq11_ctrl, &g_external_irq11_cfg);
- assert(FSP_SUCCESS == (err01 || err02));
- /* 使能按键01和按键02的GPIO引脚中断 */
- err01 = R_ICU_ExternalIrqEnable(&g_external_irq10_ctrl);
- err02 = R_ICU_ExternalIrqEnable(&g_external_irq11_ctrl);
- assert(FSP_SUCCESS == (err01 || err02));
- while (1);
- }
其次,我们需要增加两个中断回调函数(还记得我们在RASC的功能栈配置环节为两个按键引脚设置的中断回调函数名称吗?),并在回调函数中分别添加LED01开启和LED01关闭的代码- /* 按键01引脚中断函数 */
- void ICU_Key01_Callback (external_irq_callback_args_t * p_args)
- {
- (void) p_args;
- /* 设置LED01引脚P415状态为高电平(LED点亮)*/
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH);
- }
- /* 按键02引脚中断函数 */
- void ICU_Key02_Callback (external_irq_callback_args_t * p_args)
- {
- (void) p_args;
- /* 设置LED01引脚P415状态为低电平(LED关闭)*/
- R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
- }
好了,我们代码编写的任务就这样愉快的完成了~!有些熟悉
STM32开发的小伙伴可能会有点疑问:怎么在C文件中定义了函数体,没有在头文件中声明就能编译执行?这就是RA代码框架给我们提供的便利性。还记得之前我们通过图形化的配置工具RASC已经配置了LED和按键的相关引脚和中断参数了吗?RA代码框架已经为我们在其BSP和HAL层分别添加了相关的宏、变量、函数、及结构体等内容,这样可以极大简化应用开发的工作量,为实现基于RA产品体系的快速开发提供支撑;当然,前提是你必须对RA代码整体框架体系非常熟悉!
4、烧录运行
烧录代码的步骤,已经在上一篇中介绍过了,在此就不再赘述。同样,最后放出运行的实际效果视频,供大家参考体验。