RT-Thread初识学习-04-GPIO操作

前言:在裸机开发和FreeRTOS开发过程中,我们使用的GPIO操作函数都是由stm32库函数提供,如GPIO_SetBits()、GPIO_Init()、GPIO结构体对端口进行初始化--模式、速度、管脚号等操作,但是是在RTT中它也为我们封装了很多函数使用,我们既可以使用它提供给我们的函数也可以使用HAL库提供的函数

PIN设备操作方法 

RTT提供6个函数供我们使用

rt_base_t rt_pin_get(const char *name);
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:rt_pin_mode()

设置引脚模式,引脚在使用前需要设置好输入还是输出模式

注意:引脚编号和芯片的引脚号区分开来,他们不是同一个概念,引脚编号由PIN设备驱动程序定义,和芯片相关

模式共5种:输入、输出、上拉输入、下拉输入、开漏输出


#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

/* RT-Thread Hardware PIN APIs */
void rt_pin_mode(rt_base_t pin, rt_base_t mode)
{
    RT_ASSERT(_hw_pin.ops != RT_NULL);
    _hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_mode, pinMode, set hardware pin mode);

注意这里的pin是引脚编号,并不是芯片端口号,一个芯片的端口号对应得编号在drv_gpio.c中
static const struct pin_index pins[] = 
{
#if defined(GPIOA)
    __STM32_PIN(0 ,  A, 0 ),
    __STM32_PIN(1 ,  A, 1 ),
    __STM32_PIN(2 ,  A, 2 ),
    __STM32_PIN(3 ,  A, 3 ),
    __STM32_PIN(4 ,  A, 4 ),
    __STM32_PIN(5 ,  A, 5 ),
    __STM32_PIN(6 ,  A, 6 ),
    __STM32_PIN(7 ,  A, 7 ),
    __STM32_PIN(8 ,  A, 8 ),      如果你想使用GPIOA.11的话,那么编号就是11了,但是我觉得这样写的方式不好,阅读性太差。使用#define LED0_PIN    GET_PIN(A, 8)更好
    __STM32_PIN(9 ,  A, 9 ),
    __STM32_PIN(10,  A, 10),
    __STM32_PIN(11,  A, 11),
    __STM32_PIN(12,  A, 12),
    __STM32_PIN(13,  A, 13),
    __STM32_PIN(14,  A, 14),
    __STM32_PIN(15,  A, 15),
}

2:rt_pin_write() 

设置引脚输出电平,高低电平

#define PIN_LOW                 0x00
#define PIN_HIGH                0x01
void rt_pin_write(rt_base_t pin, rt_base_t value)
{
    RT_ASSERT(_hw_pin.ops != RT_NULL);
    _hw_pin.ops->pin_write(&_hw_pin.parent, pin, value);
}

3:rt_pin_read()

读取某一个引脚的值

int  rt_pin_read(rt_base_t pin)
{
    RT_ASSERT(_hw_pin.ops != RT_NULL);
    return _hw_pin.ops->pin_read(&_hw_pin.parent, pin);
} 

pin的获取
#define LED0_PIN    GET_PIN(A, 8)--使用GET_PIN()获取,LED0_pin是我们使用的宏定义表示后面的GPIOA.8

 4:rt_pin_attach_irq()

绑定引脚的中断回调函数,其实就是相当于EXTI

rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
                             void (*hdr)(void *args), void  *args)
{
    RT_ASSERT(_hw_pin.ops != RT_NULL);
    if(_hw_pin.ops->pin_attach_irq)
    {
        return _hw_pin.ops->pin_attach_irq(&_hw_pin.parent, pin, mode, hdr, args);
    }
    return RT_ENOSYS;
}

#define PIN_IRQ_MODE_RISING             0x00
#define PIN_IRQ_MODE_FALLING            0x01
#define PIN_IRQ_MODE_RISING_FALLING     0x02
#define PIN_IRQ_MODE_HIGH_LEVEL         0x03
#define PIN_IRQ_MODE_LOW_LEVEL          0x04

pin--引脚编号、、、mode--触发模式(上升沿、下降沿与stm32的exti是一样的)、、中断回调函数(中断函数自己写,不像stm32自己给我们提供)、中断函数的参数(一般不传递使用RT_NULL)、、、返回值绑定成功---RT_EOK

5: rt_pin_detach_irq()

脱离引脚的中断回调函数、、参数是pin--引脚编号

注意:引脚脱离了中断回调函数后,中断并没有关闭,还可以调用绑定中断回调函数。意思就是引脚走了,中断没有走,引脚可以以后继续绑定这个中断---添狗

rt_err_t rt_pin_detach_irq(rt_int32_t pin)
{
    RT_ASSERT(_hw_pin.ops != RT_NULL);
    if(_hw_pin.ops->pin_detach_irq)
    {
        return _hw_pin.ops->pin_detach_irq(&_hw_pin.parent, pin);
    }
    return RT_ENOSYS;
}

6:rt_pin_irq_enable()

第四点只是绑定了中断函数,但是还没有使能引脚中断,该函数作用就是开启引脚中断

rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled)
{
    RT_ASSERT(_hw_pin.ops != RT_NULL);
    if(_hw_pin.ops->pin_irq_enable)
    {
        return _hw_pin.ops->pin_irq_enable(&_hw_pin.parent, pin, enabled);
    }
    return RT_ENOSYS;
}

#define PIN_IRQ_DISABLE                 0x00
#define PIN_IRQ_ENABLE                  0x01

按键中断控制LED灯

void KEY0_ISR(void * args)
{
    rt_kprintf("enter key0_isr\r\n");
}
int main(void)
{

    //引脚模式初始化
    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);

    //引脚电平初始化
    rt_pin_write(LED0_PIN, PIN_LOW);
    rt_pin_write(LED1_PIN, PIN_LOW);

    //绑定引脚中断函数
    rt_pin_attach_irq(KEY0_PIN, PIN_IRQ_MODE_FALLING, KEY0_ISR, RT_NULL);

    //使能引脚中断
    rt_pin_irq_enable(KEY0_PIN, ENABLE);

    while(1);

    return RT_EOK;
}

你可能感兴趣的:(#,RT_Thread,单片机,学习,stm32)