RT-Thread学习笔记——PIN 设备

本文详细介绍了如何在RT-Thread操作系统中访问和使用PIN设备,包括PIN设备的架构、I/O设备模型框架,以及如何基于STM32进行PIN设备操作。内容涵盖PIN设备的模式设置、电平读写、中断处理等,并提供了STM32开发板的使用示例。
摘要由CSDN通过智能技术生成

前言

本文主要学习RT-Thread的设备驱动框架之PIN 设备,这里以及后面更新的博客内容将不会详细介绍I/O 设备模型,当学习PIN 设备以及其他设备需要对I/O 设备模型有所了解,请和我一样刚学习RT-Thread的朋友们先自行到《RT-Thread编程指南》看一下I/O 设备模型。这里主要讲解如何访问PIN 设备,针对PIN设备各个函数讲解,以及教你如何基于PIN设备实现自己的GPIO驱动以及基于外部GPIO的外部中断实现,详细的gpio驱动文件的各个函数,学完PIN 设备就可以基于自己的开发板制作一个属于自己的bsp的GPIO驱动文件。本文讲的都是以STM32作为硬件设备的。

一、RT-Thread的架构

学习过FreeRTOS或UCOS的朋友都知道,这两个实时操作系统只有内核,RT-Thread不像FreeRTOS或UCOS, 它不仅仅有内核,还有设备驱动框架(如PIN 设备、I2C 设备、UART设备等)、丰富的上层组件和软件包,而软件包更是做了MQTT、LWM2M等协议,因此,RT-Thread是一个IoT OS,功能强大,这也是我为什么喜欢RT-Thread,学习RT-Thread的原因。 

RT-Thread 软件框架图(来源RT-Thread编程指南)
RT-Thread 软件框架图(来源RT-Thread编程指南)

 

 

二、I/O 设备模型框架

RT-Thread 提供了一套简单的 I/O 设备模型框架,它位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。

I/O 设备模型框架(来源RT-Thread编程指南)
 I/O 设备模型框架(来源RT-Thread编程指南)

 

三、访问 PIN 设备

应用程序通过 RT-Thread 提供的 PIN 设备管理接口来访问 GPIO,相关接口如下所示:

/* 设置引脚模式 */
void rt_pin_mode(rt_base_t pin, rt_base_t mode);
/* 设置引脚电平 */
void rt_pin_write(rt_base_t pin, rt_base_t value);
/* 读取引脚电平 */
int  rt_pin_read(rt_base_t pin);
/* 绑定引脚中断回调函数 */
rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void  *args);
/* 脱离引脚中断回调函数 */
rt_err_t rt_pin_detach_irq(rt_int32_t pin);
/* 使能引脚中断 */
rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled);

1、定义引脚信息

定义引脚信息非常重要,因为在上述的访问GPIO接口函数都是通过获取引脚信息来得到引脚编号或GPIO_PIN_X,然后根据这个信息去具体的操作对应的PIN,执行相关功能。

(1)宏定义引脚编号

对于引脚编号,用户可以自己随便定义,一般根据芯片封装的引脚顺序来定义,以潘多拉开发板的STM32L475VET6为例,下面定义LED & BEEP & KEY引脚编号,用户可以自己新建一个drv_gpio.h放这些引脚编号。

/* 
*宏定义STM32引脚编号,
*用户可以自己随便定义,
*一般根据芯片封装的引脚顺序来定义
*/

/* LED & BEEP & KEY */
#define PIN_BEEP		37	/* PB2 --> BEEP */
#define PIN_LED_R		38	/* PE7 --> LED_R */
#define PIN_LED_G		39	/* PE8 --> LED_G */
#define PIN_LED_B		40	/* PE9 --> LED_B */
#define PIN_KEY0		57	/* PD10 --> KEY0 */
#define PIN_KEY1		56	/* PD9 --> KEY1 */
#define PIN_KEY2		55	/* PD8 --> KEY2 */
#define PIN_WK_UP		7	/* PC13 --> WK_UP */
STM32L475VE引脚编号示意图
STM32L475VE引脚编号示意图

 

(2)定义引脚信息

通过用C语言连接符来实现引脚信息的定义,然后再将每个引脚的信息按引脚的顺序存放在一个数组里面,这个数组的类型是引脚信息,用户可以新建一个drv_gpio.c来存放。

/*
*用C语言字符串连接定义引脚信息
*index------->用户定义的PIN编号
*gpio-------->如A代表GPIOA
*gpio_index-->如1代表GPIO_PIN_7
*例如__STM32_PIN(1, E, 2)表示1, GPIOE_CLK_ENABLE, GPIO_PIN_2
*/
#define __STM32_PIN(index, gpio, gpio_index)	                        \
{                                                                       \
    index, GPIO##gpio##_CLK_ENABLE, GPIO##gpio, GPIO_PIN_##gpio_index	\
}
/*
*引脚不存在或引脚不能当做IO来用,
*如第0引脚不存在,VSS或VBAT引脚不能当做IO来用
*/
#define __STM32_PIN_DEFAULT	\
{				\
        -1, 0, 0, 0		\
}

/* 
*使能GPIO时钟
*/
static void GPIOA_CLK_ENABLE(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
}

static void GPIOB_CLK_ENABLE(void)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();
}

static void GPIOC_CLK_ENABLE(void)
{
    __HAL_RCC_GPIOC_CLK_ENABLE();
}

static void GPIOD_CLK_ENABLE(void)
{
    __HAL_RCC_GPIOD_CLK_ENABLE();
}

static void GPIOE_CLK_ENABLE(void)
{
    __HAL_RCC_GPIOE_CLK_ENABLE();
}

/*
*引脚信息
*index------->用户定义的PIN编号
*(*rcc)------>RCC时钟使能
*gpio-------->如A代表GPIOA
*gpio_index-->如1代表GPIO_PIN_7
*/
struct stm32_pin_index
{
    int index;
    void (*rcc)(void);
    GPIO_TypeDef *gpio;
    uint32_t pin;
};

/*
*stm32 pin引脚信息列表
*写的时候需要把所有的信息信息都写进去,且安装封装的引脚顺序来写
*/
static const struct stm32_pin_index stm32_pins_table[] =
{
        __STM32_PIN_DEFAULT,	/* 0 */
	......
        __STM32_PIN_DEFAULT,	/* 6, VBAT */
	__STM32_PIN(7, C, 13),	/* 7, PC13 --> WK_UP */
	......
	__STM32_PIN(36, B, 1),	/* 36, PB1 */
	__STM32_PIN(37, B, 2),	/* 37, PB2 --> BEEP */
	__STM32_PIN(38, E, 7),	/* 38, PE7 --> LED_R */
	__STM32_PIN(39, E, 8),	/* 39, PE8 --> LED_G */
	__STM32_PIN(40, E, 9),	/* 40, PE9 --> LED_B */
	......
	__STM32_PIN(55, D, 8),	/* 55, PD8 --> KEY2 */
	__STM32_PIN(56, D, 9),	/* 56, PD9 --> KEY1 */
	__STM32_PIN(57, D, 10),	/* 57, PD10 --> KEY0 */
	......
	__STM32_PIN_DEFAULT,	/* 94, BOOT0 */
	......
};

(3)定义引脚中断信息

定义引脚中断信息主要包括引脚中断映射列表和引脚中断回调函数列表。

/*
*引脚中断映射
*pinbitÿ
  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值