RT-Thread GPIO驱动

一、GPIO驱动的框架

pin.c 中,会有一个GPIO 的注册函数:rt_device_pin_register

通过里面的这三个函数来操作引脚,这里使用了全局变量,说明永远只能有一个驱动程序。

1.1 读函数

函数的代码如下,其中传入的参数 buffer 是 rt_device_pin_status 这个结构体类型的参数。

rt_device_pin_status  这个结构体里面有两个值,我们之前的buffer 是可以往里面存入数据,现在是通过这个引脚pin把硬件数据传递给驱动程序,通过status 把驱动程序返回的数据传给应用程序。

1.2 写函数

写函数和读函数基本一样,都是用rt_device_pin_status 这个结构体来控制使用哪个引脚,把这个引脚写成什么状态。

1.3 硬件相关的函数

上面的读写函数可以算是框架层,在里面的函数中可以发现里面会调用到底层的函数,涉及到一个“ops” 结构体,里面有各种函数,和上面的应用程序相对应。

二、分析GPIO的驱动代码

2.1 初始化驱动

在 drv_gpio.c 中,rt_hw_pin_init 函数使能各个串口的时钟,最后注册了一个驱动的程序,驱动程序的名字叫“pin”,提供了一些引脚操作的相关函数

return rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);


const static struct rt_pin_ops _stm32_pin_ops =
{
    stm32_pin_mode,
    stm32_pin_write,
    stm32_pin_read,
    stm32_pin_attach_irq,
    stm32_pin_dettach_irq,
    stm32_pin_irq_enable,
};

 注册函数中的 “name” 其实就是“pin”,以后使用“pin”的时候,首先要找到这个名字为“pin”的驱动程序,然后打开,读写它。

引出一个问题,读写引脚的时候都是传入整数,这里的整数是如何和具体的引脚挂钩呢?里面其实是有一个数组的索引,数组的每一项表示一个引脚。

2.2 APP编写大概思路

里面最主要是要分辨清楚 0/1号引脚对应的是哪个真正的引脚,以及引脚编号是什么。

dev = rt_device_find("pin");  //找到刚刚定义的驱动
rt_device_open(dev);          //打开这个驱动程序

/* 设置0 号引脚读 */
struct rt_device_pin_mode mode;  
mode.pin = 0;                    
// PIN_MODE_OUTPUT,PIN_MODE_INPUT_PULLUP,PIN_MODE_INPUT_PULLDOWN,PIN_MODE_OUTPUT_OD
mode.mode = PIN_MODE_INPUT; //上面的各种模式
rt_device_control(dev, 0, &mode);

/* 现在要去读 这个设备中的某个引脚 eg.0 */   
rt_device_pin_status status;        //需要先构造一个status 结构体
status.pin = 0;                     //在这个结构体中指定读哪个引脚
rt_device_read(dev, &status, sizeof(status));
rt_kprintf("gpio 0 = %d\n", status.status);

/* 设置1 号引脚输出 */
struct rt_device_pin_mode mode;
mode.pin = 1;
// PIN_MODE_INPUT,PIN_MODE_INPUT_PULLUP,PIN_MODE_INPUT_PULLDOWN,PIN_MODE_OUTPUT_OD
mode.mode = PIN_MODE_OUTPUT; 
rt_device_control(dev, 0, &mode);

rt_device_pin_status status;
status.pin = 1;
status.status = 0;
rt_device_write(dev, &status, sizeof(status));

 三、编写一个驱动LED的程序

思路是:查看原理图,确定使用哪个引脚;查看RT-Thread的pin驱动程序,确定引脚编号;编写APP

这里我选择PA11, 对应 __STM32_PIN(11,  A, 10)

(下面的代码是基于韦东山老师的课程代码修改)

#include <rtthread.h>
#include <rtdevice.h>

#include <string.h>
#include <stdlib.h>
#include <drivers\pin.h>

#define DBG_TAG "led"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>


#ifdef FINSH_USING_MSH

/* led on
 * led off
 */
static int led(int argc, char **argv)
{
	rt_device_t pin_dev;
	struct rt_device_pin_mode mode;
	struct rt_device_pin_status status;
	int len;

    if (argc != 2)
    {
        rt_kprintf("Usage: \n");
        rt_kprintf("led <on | off> - set led an on/off\n");
        return -RT_ERROR;
    }
	else 
    {
		/* 找到设备 */
		pin_dev = rt_device_find("pin");
		if (!pin_dev)
		{
			rt_kprintf("can not get pin drv\n");
			return -RT_ERROR;
		}

		/* 设置引脚输出模式,结构体在上面定义 */
		rt_device_open(pin_dev, RT_DEVICE_OFLAG_RDWR);
		mode.pin  = 11;
		mode.mode = PIN_MODE_OUTPUT;
		rt_device_control(pin_dev, 0, &mode);

		/* 设置引脚输出的状态,结构体在上面定义 */
		status.pin  = 11;

		if (!strcmp(argv[1], "on"))
			status.status = 0;
		else
			status.status = 1;

		len = rt_device_write(pin_dev, 0, &status, sizeof(status));
		rt_kprintf("rt_device_write ret = %d, err = %d\n", len, rt_get_errno());

		/* 关闭驱动程序 */
		rt_device_close(pin_dev);

		/* 调用驱动的read函数 */
    }
	
    return RT_EOK;
}
MSH_CMD_EXPORT(led, led function);

#endif /* FINSH_USING_MSH */

总结来说步骤如下:
1. 找到注册的设备 :rt_device_find;并打开这个设备rt_device_open

2. 设置模式:mode (输出还是输入)

3. 设置引脚的输出状态(高低电平)

4. 关闭驱动程序

四、遇到的问题

4.1 创建模版问题

解决方法:RT-Thread Studio与CubeMX联合编程(超级详细)_rtthread studio cubemx-CSDN博客https://blog.csdn.net/qq_40824852/article/details/123067421

4.2 stlink下载版本过低问题

这里我使用的是V2,要更新一下:
STSW-LINK007 - ST-LINK、ST-LINK/V2、ST-LINK/V2-1、STLINK-V3开发板固件升级 - 意法半导体STMicroelectronicshttps://www.st.com.cn/zh/development-tools/stsw-link007.html?dl=RIx9iLUtfNDl1cH%2FCKNh4w%3D%3D%2CWmjsWwu0XAI6NsDPtwzzdpOAOX%2BaGwlIel0lRuJ%2BdHrAT599KA3P%2FoTQ9L6XQgJo%2Fny5qVRnw4ZcKc0MvfxxWpufH2c3sHye7m6Wk5PybsvzGUBVJ00PyGSRQqm2vT0dUqKAQ9T3ShXOL9rcHBtNXSxoscZxSToPKvy4t9ChRO8f2KN9d7CdesyGFrxrhkoTPxzAlPB5aTJeMX2OMJ97AuJigXoQPaa8X4tWJf9yCpuBEbFJ7zKyF%2Flp7l8mtNvH1SBbX2v7S4JdDwb2Yz%2BlyxB%2BWRQ5SpfAjHfPCk4zqt%2BTU7VdLM8Qr6eyXrPO4SbPDAGIGnROeZXS3e2UriCfpA%3D%3D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值