本帖最后由 zero949079783 于 2022-8-28 14:29 编辑
使用软件:RT-Thread Studio
原理图:
PIN 设备引脚简介芯片上的引脚一般分为 4 类:电源、时钟、控制与 I/O,I/O 口在使用模式上又分为 General Purpose Input Output(通用输入 / 输出),简称 GPIO,与功能复用 I/O(如 SPI/I2C/UART 等)。 大多数 MCU 的引脚都不止一个功能。不同引脚内部结构不一样,拥有的功能也不一样。可以通过不同的配置,切换引脚的实际功能。通用 I/O 口主要特性如下: - 可编程控制中断:中断触发模式可配置,一般有下图所示 5 种中断触发模式:
-
应用程序通过 RT-Thread 提供的 PIN 设备管理接口来访问 GPIO,相关接口如下所示: rt_pin_get() 获取引脚编号
rt_pin_mode() 设置引脚模式
rt_pin_write() 设置引脚电平
rt_pin_read() 读取引脚电平
rt_pin_attach_irq() 绑定引脚中断回调函数
rt_pin_irq_enable() 使能引脚中断
rt_pin_detach_irq() 脱离引脚中断回调函数
获取引脚编号RT-Thread 提供的引脚编号需要和芯片的引脚号区分开来,它们并不是同一个概念,引脚编号由 PIN 设备驱动程序定义,和具体的芯片相关。有3种方式可以获取引脚编号: API 接口获取、使用宏定义或者查看PIN 驱动文件。
使用 API使用 rt_pin_get() 获取引脚编号,如下获取 PF9 的引脚编号: pin_number = rt_pin_get("PF.9");
使用宏定义
如果使用 rt-thread/bsp/stm32 目录下的 BSP 则可以使用下面的宏获取引脚编号:
GET_PIN(port, pin)
获取引脚号为 PF9 的 LED0 对应的引脚编号的示例代码如下所示:
#define LED0_PIN GET_PIN(F, 9)
查看驱动文件
如果使用其他 BSP 则需要查看 PIN 驱动代码 drv_gpio.c 文件确认引脚编号。此文件里有一个数组存放了每个 PIN 脚对应的编号信息,如下所示:
static const rt_uint16_t pins[] =
{
__STM32_PIN_DEFAULT,
__STM32_PIN_DEFAULT,
__STM32_PIN(2, A, 15),
__STM32_PIN(3, B, 5),
__STM32_PIN(4, B, 8),
__STM32_PIN_DEFAULT,
__STM32_PIN_DEFAULT,
__STM32_PIN_DEFAULT,
__STM32_PIN(8, A, 14),
__STM32_PIN(9, B, 6),
... ...
}
以__STM32_PIN(2, A, 15)为例,2 为 RT-Thread 使用的引脚编号,A 为端口号,15 为引脚号,所以 PA15 对应的引脚编号为 2。
设置引脚模式
引脚在使用前需要先设置好输入或者输出模式,通过如下函数完成:
void rt_pin_mode(rt_base_t pin, rt_base_t mode);
参数 描述
pin 引脚编号
mode 引脚工作模式
目前 RT-Thread 支持的引脚工作模式可取如所示的 5 种宏定义值之一,每种模式对应的芯片实际支持的模式需参考 PIN 设备驱动程序的具体实现:
#define PIN_MODE_OUTPUT 0x00 /* 输出 */
#define PIN_MODE_INPUT 0x01 /* 输入 */
#define PIN_MODE_INPUT_PULLUP 0x02 /* 上拉输入 */
#define PIN_MODE_INPUT_PULLDOWN 0x03 /* 下拉输入 */
#define PIN_MODE_OUTPUT_OD 0x04 /* 开漏输出 */
使用示例如下所示:
#define BEEP_PIN_NUM 35 /* PB0 */
/* 蜂鸣器引脚为输出模式 */
rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);
设置引脚电平
设置引脚输出电平的函数如下所示:
void rt_pin_write(rt_base_t pin, rt_base_t value);
参数 描述
pin 引脚编号
value 电平逻辑值,可取 2 种宏定义值之一:PIN_LOW 低电平,PIN_HIGH 高电平
使用示例如下所示:
#define BEEP_PIN_NUM 35 /* PB0 */
/* 蜂鸣器引脚为输出模式 */
rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);
/* 设置低电平 */
rt_pin_write(BEEP_PIN_NUM, PIN_LOW);
读取引脚电平
读取引脚电平的函数如下所示:
int rt_pin_read(rt_base_t pin);
参数 描述
pin 引脚编号
返回 ——
PIN_LOW 低电平
PIN_HIGH 高电平
使用示例如下所示:
读取引脚电平
读取引脚电平的函数如下所示:
int rt_pin_read(rt_base_t pin);
参数 描述
pin 引脚编号
返回 ——
PIN_LOW 低电平
PIN_HIGH 高电平
使用示例如下所示:
#define BEEP_PIN_NUM 35 /* PB0 */
int status;
/* 蜂鸣器引脚为输出模式 */
rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);
/* 设置低电平 */
rt_pin_write(BEEP_PIN_NUM, PIN_LOW);
status = rt_pin_read(BEEP_PIN_NUM);
例程:#include <rtthread.h>
#include <board.h> // 添加头文件
#include <sys/reent.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#define LED0_PIN GET_PIN(F,9) //获取引脚号为 PF9 的 LED0
#define LED1_PIN GET_PIN(F,10) //获取引脚号为 PF10 的 LED1
#define KEY0_PIN GET_PIN(E,4) //获取引脚号为 PE4 的 KEY0
int main(void)
{
int count = 1;
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT); //设为输出模式
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT); //设为输出模式
rt_pin_mode(KEY0_PIN, PIN_MODE_INPUT_PULLUP);//设为上拉输入模式
while (count++)
{
if(rt_pin_read(KEY0_PIN) == PIN_LOW) //是否按下
{
rt_thread_mdelay(20);//消抖动
if(rt_pin_read(KEY0_PIN) == PIN_LOW)
{
rt_pin_write(LED1_PIN, PIN_LOW );//输出低电平
}
}else {
rt_pin_write(LED1_PIN, PIN_HIGH );//输出高电平
rt_pin_write(LED0_PIN, PIN_LOW );//输出低电平
rt_thread_mdelay(1000); //延时1秒
rt_pin_write(LED0_PIN, PIN_HIGH );//输出高电平
rt_thread_mdelay(1000);//延时1秒
}
// LOG_D("Hello RT-Thread!");
// rt_thread_mdelay(1000);
}
return RT_EOK;
}
|