开发环境:
IDE:MKD 5.30
开发板:RA-Eco-RA4M2
MCU:R7FA4M2AD3CFP
1 GPIO工作原理
熟悉单片机的朋友都知道,学习的第一个例程就是流水灯,要想实现流水灯,首先必须了解GPIO的工作原理。GPIO的基本结构如下图所示。
和其他Cortex-M系列的MCU一样,RA4M2的I/O也有多种模式:输入模式,输出模式,模拟输入模式,复用模式。
1.1 通用输入输出模式
通用输入输出模式也就是普通GPIO模式。
1.1.1 通用输入模式
通用输入模式分为浮空输入和上拉/下拉输入。
浮空输入:
浮空(floating)就是逻辑器件的输入引脚即不接高电平,也不接低电平。由于逻辑器件的内部结构,当它输入引脚悬空时,相当于该引脚接了高电平。一般实际运用时,引脚不建议悬空,易受干扰。通俗讲就是让管脚什么都不接,浮空着。信号进入芯片内部后,既没有接上拉电阻也没有接下拉电阻,经由触发器输入。配置成这个模式后,用电压变量引脚电压为1点几伏,这是个不确定值。由于其输入阻抗比较大,一般把这种模式用于标准的通讯协议,比如IIC、USART的等。
上拉输入:
上拉就是把电位拉高,比如拉到Vcc。上拉就是将不确定的信号通过一个电阻嵌位在高电平,电阻同时起限流作用,弱强只是上拉电阻的阻值不同,没有什么严格区分。上拉输入就是信号进入芯片后加了一个上拉电阻,再经过施密特触发器转换成0、1信号,读取此时的引脚电平为高电平。
下拉输入:
就是把电压拉低,拉到GND。与上拉原理相似。下拉输入就是信号进入芯片后加了一个下拉电阻,再经过施密特触发器转换成0、1信号,读取此时的引脚电平为低电平;
1.1.2 通用输出模式
通用输出模式推挽模式和开漏模式。
开漏输出:
一般用在电平不匹配的场合,如需要输出5V的高电平。输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对强(一般20mA以内)。
推挽输出:
可以输出高、低电平,连接数字器件;推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源决定。推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。
1.2 模拟输入模式
信号进入后不经过上拉电阻或者下拉电阻,关闭施密特触发器,经由另一线路把电压信号传送到片上外设模块。模拟输入是指传统方式的输入,数字输入是输入PCM数字信号,即0、1的二进制数字信号,通过数模转换,转换成模拟信号,经前级放大进入功率放大器,功率放大器还是模拟的。比如传送给ADC模块,由ADC采集电压信号。所以可以理解为模拟输入的信号是未经处理的信号,是原汁原味的信号。
1.3 复用模式
复用开漏输出:
可以理解为GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)。端口必须配置成复用开漏功能输出模式。
复用推挽输出:
可以理解为GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)。端口必须配置成复用推挽功能输出模式。
2 GPIO流水灯硬件电路分析
发光二极管是属于二极管的一种,具有二级管单向导电特性,即只有在正向电压(二极管的正极接正,负极接负)下才能导通发光。P405引脚接发光二极管(LED1)的正极,所以P405引脚输出高电平LED1亮,P405引脚输出低电平LED1熄灭,其他LED同理。
值得注意的,不同的开发板,LED连接的GPIO一般是不同的,请注意修改。
3 GPIO 流水灯实现
3.1 配置LED GPIO
在前面一章,已经搭建了RA4M2的开发环境,接下来在第一章的基础上配置GPIO。
首先打开RA Smart Configurator,按照下图所示操作,即可打开RA Smart Configurator。
然后即可配置参数。这里将3个LED配置后才能输出模式。
然后最后点右上角的 “Generate Project Content” 图标生成工程即可。
3.2 编译代码
打开工程,在hal_entry.c添加如下代码。
/* Exported macro ------------------------------------------------------------*/
#define GPIO_LED1 BSP_IO_PORT_04_PIN_05
#define GPIO_LED2 BSP_IO_PORT_04_PIN_04
#define GPIO_LED3 BSP_IO_PORT_00_PIN_02
/*******************************************************************************************************************//**
* 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_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED3, BSP_IO_LEVEL_LOW);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED1, BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED1, BSP_IO_LEVEL_LOW);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED2, BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED2, BSP_IO_LEVEL_LOW);
R_IOPORT_PinWrite(&g_ioport_ctrl, GPIO_LED3, BSP_IO_LEVEL_HIGH);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
应用代码很简单,就是不断改变LED引脚的高低电平,再加上延时,从而实现流水灯的效果。
4 实验现象
将编译好的程序下载到板子中,可以看到三个LED灯依次闪烁。