【瑞萨RA MCU创意氛围赛速通】瑞萨单片机点灯
一般而言,点灯例程就像是刚学习 C 语言那时的“Hello World”程序那样,是入门一块单片机开
发板的经典例程。C 语言的“Hello World”程序使用 printf 函数来打印“Hello World!”字符串,而
我们学习这块开发板的第一个例程的内容却不是打印“Hello World!”字符串,而是首先要学会控
制芯片的引脚。
当电灯完成之后,意味着这块单片机的基础功能基本上就搞定了,剩下就是堆外设、搞协议的问题了
![在这里插入图片描述](https://img-blog.csdnimg.cn/3dc7a85cbf1f4ca1938252c8acf7b866.png)
1.IOPORT简介
芯片的引脚可以被粗略地分为 IO 引脚和非 IO 引脚。非 IO 引脚就是电源引脚、晶振引脚等的那
些引脚,他们不具备 GPIO(通用输入输出)功能。而 IO 引脚是那些具备 GPIO 功能的引脚,他
们可以配置为各种模式、实现各种通用功能。
IO 引脚最基本的输出功能是输出高、低电平,实现开关控制(比如开关 LED 灯、继电器或三极
管等等);最基本的输入功能是检测外部输入电平(比如通过引脚电平的高低区分按键是否被按
下)。IO 引脚还可以用来连接外部设备,与外部设备进行通讯,发送控制指令,采集传感器数据
等。
IOPORT 即 I/O Port,在代码里面为了方便而写成“IOPORT”,表示输入输出端口。IOPORT 是
RA MCU 的一个外设模块,它用来控制芯片的引脚,对每一个引脚进行详细的配置。具体地说,
IOPORT 可以对引脚进行以下几个方面的配置:
• 配置引脚为一般的 IO 功能,即输入或输出高电平或者低电平。
• 控制引脚的输入上拉电阻。
• 控制引脚的驱动能力。
• 控制引脚是否检测上升沿/下降沿/双边沿。
• 控制引脚是否作为中断输入引脚。
• 配置引脚为模拟输入功能或者将引脚在内部连接到其他外设模块。
瑞萨 RA 系列芯片的 IO 端口从理论上被分成 16 个组(0~9, A, B, C, D, E, F),每组有 16 个引脚
(0~15)。然而,实际情况并非是完整的“16 个组 + 每组 16 个引脚”的配置,而是因实际的芯片型
号而异。以野火启明 6M5 板子上的 R7FA6M5BH3CFC 芯片为例,它是 LQFP 176-pin 封装,一
共有 176 个引脚,其中的大部分引脚都是可以被 IOPORT 模块控制的 IO 引脚。而这些 IO 引脚被
分成了 0~9, A, B 共 11 组引脚(注:A, B 是 10, 11 的十六进制表示),每组一般有 16 个引脚(引
脚号为 0~15),实际上有些组不到 16 个引脚。对于引脚数比较少的封装(LQFP 144-pin 和 LQFP
100-pin 封装)来说,芯片的可用 IO 引脚数也会相对减
2.IOPORT 的寄存器描述
IOPORT 模块由于功能相对简单,寄存器相对来说比较少。
2.1端口引脚功能选择寄存器
我们在前面说过,瑞萨 RA 系列芯片的 IO 端口从理论上被分成 16 个组、每组有 16 个引脚(实
际上可能会更少),而下图中所描述的端口引脚功能选择寄存器(PmnPFS)便是用来配置 IO 引
脚的,一个这样的寄存器对应配置一个 IO 引脚。
注:上图中的“Pmn”,“m = 0 to 9, A, B”表示的是 IO 端口 m 的范围,而“n = 00 to 15”表示的
是 IO 引脚 n 的范围。
2.2端口输出数据寄存器
2.3端口输入数据寄存器
2.4端口输出置位/复位寄存器
2.4写保护寄存器
当要配置 RA 单片机的 I/O 引脚时,主要需要配置的是 PmnPFS 寄存器,但是所有的
PmnPFS 寄存器默认是被保护的,因此要想写入引脚 Pmn 对应的 PmnPFS 寄存器,需要先通过写
保护寄存器解除写保护。
3.使用寄存器点亮 LED 灯
3.1硬件链接
野火启明 6M5 开发板的 LED 电路图如图所示。图中 RA6M5 芯片的 P400、P403、P404 引脚分别
通过一个 2.2 KΩ 的限流电阻连接到 LED1、LED2、LED3 这三个 LED 灯的阴极,LED 灯的阳极
连接到 3.3V 电源。而 LED4 是电源指示灯,只要开发板通电就会亮。
效果如图所示:
3.2代码
#include "hal_data.h"
/*
* 作者:PrairieOne
* csdn:PrairieOne
* 邮箱:prairieone1024@163.com
* 嵌入式技术交流群:826251093
*/
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
/* 用户头文件包含 */
#include "led/bsp_led.h"
/*******************************************************************************************************************//**
* 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 */
LED_Init(); // LED 初始化
while(1)
{
LED1_ON; // LED1亮
LED2_ON; // LED2亮
LED3_ON; // LED3亮
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒
LED1_OFF; // LED1灭
LED2_OFF; // LED2灭
LED3_OFF; // LED3灭
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒
}
#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);
}
}
#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
遇事不决,可问春风