前言:在裸机开发和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;

}

推荐链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。