c语言sscanf函数的用法是什么
254
2022-11-01
简要分析Thread的通用GPIO设备驱动
1 本文的目的和结构
1.1 本文的目的 和背景
1.2 本文的结构
2 问题阐述
图A. 1 RT-Thread设备管理框架
3 问题的解决
图A. 2 实验用正点原子开发板
3.1 准备和配置工程
1) 在menuconfig配置界面依次选择RT-Thread Components ---》 Device Drivers ---》 Using generic GPIO device drivers,如图所示:
图A. 3 menuconfig中开启GPIO驱动
2) 输入scons --target=mdk5 -s
命令生成mdk5工程。将本应用笔记附带的main.c替换掉bsp中的main.c,如图所示:
图A. 5 查看pin设备
下面是3个通用GPIO设备驱动API应用示例,分别是:GPIO输出、GPIO输入、GPIO外部中断,这些代码在正点原子STM32F4探索者开发板上验证通过。
3.2 GPIO输出配置
图A. 6 LED原理图
#define LED0 21 //PF9--21,在 drv_gpio.c 文件 pin_index pins[]中查到 PF9 编号为 21
#define LED1 22 //PF10--21,在 drv_gpio.c 文件 pin_index pins[]中查到 PF10 编号为 22
{
//设置管脚为输出模式
rt_pin_mode(LED0, PIN_MODE_OUTPUT);
//设置管脚为输出模式
rt_pin_mode(LED1, PIN_MODE_OUTPUT);
while (1)
{
//输出低电平,LED0 亮
//输出低电平,LED1 亮
rt_pin_write(LED1, PIN_LOW);
//挂起 500ms
//输出高电平,LED0 灭
rt_pin_write(LED0, PIN_HIGH);
//输出高电平,LED1 灭
rt_pin_write(LED1, PIN_HIGH);
//挂起 500ms
}
}
在线程入口函数led_thread_entry里首先调用rt_pin_mode设置管脚模式为输出模式,然后就进入while(1)循环,间隔500ms调用rt_pin_write来改变GPIO输出电平。
下面是创建线程的代码:
/* 创建led线程 */
led_thread_entry,
RT_NULL,
1024,
3,
10);
/* 创建成功则启动线程 */
rt_thread_startup(tid);
编译、下载程序,我们将看到LED间隔500ms闪烁的现象。
3.3 GPIO输入配置
示例2:配置GPIOE3、GPIOE2为上拉输入,GPIOA0为下拉输入,检测按键信号。根据原理图,GPIOE3连接到按键KEY1,按键被按下时GPIOE3应读取到低电平,按键没有被按下时GPIOE3应读取到高电平;GPIOE2连接到按键KEY2,按键被按下时GPIOE2应读取到低电平,按键没有被按下时GPIOE2应读取到高电平;GPIOA0连接到按键WK_UP,按键被按下时GPIOA0应读取到高电平,按键没有被按下时GPIOA0应读取到低电平。
#define KEY1 2 //PE3--2,在 drv_gpio.c 文件 pin_index pins[]中查到 PE3 编号为 2
#define KEY2 1 //PE2--1,在 drv_gpio.c 文件 pin_index pins[]中查到 PE2 编号为 1
#define WK_UP 34 //PA0--34,在 drv_gpio.c 文件 pin_index pins[]中查到 PA0 编号为 34
void key_thread_entry(void* parameter)
{
//PE2、PE3设置上拉输入
rt_pin_mode(KEY1, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(KEY2, PIN_MODE_INPUT_PULLUP);
//PA0设置为下拉输入
while (1)
{
//检测到低电平,即按键1按下了
if (rt_pin_read(KEY1) == PIN_LOW)
{
rt_kprintf(“key1 pressed!”);
}
//检测到低电平,即按键2按下了
if (rt_pin_read(KEY2) == PIN_LOW)
{
rt_kprintf(“key2 pressed!”);
}
//检测到高电平,即按键wp按下了
if (rt_pin_read(WK_UP) == PIN_HIGH)
{
rt_kprintf(“WK_UP pressed!”);
}
//挂起10ms
rt_thread_delay(rt_tick_from_millisecond(10));
}
}
在线程入口函数key_thread_entry里首先调用rt_pin_mode设置管脚GPIOE3为上拉输入模式。这样当用户按下按键KEY1时,GPIOE3读取到的电平是低电平;按键未被按下时,GPIOE3读取到的电平是高电平。然后进入while(1)循环,调用rt_pin_read读取管脚GPIOE3电平,如果读取到低电平则表示按键KEY1被按下,就在终端打印字符串“key1 pressed!”。每隔10ms检测一次按键输入情况。
下面是创建线程的代码:
rt_thread_t tid;
/* 创建key线程 */
tid = rt_thread_create(“key”,
key_thread_entry,
RT_NULL,
1024,
2,
10);
/* 创建成功则启动线程 */
if (tid != RT_NULL)
rt_thread_startup(tid);
3.4 GPIO中断配置
示例3:配置GPIO为外部中断模式、下降沿触发,检测按键信号。根据原理图,GPIOE4连接到按键KEY0,按键被按下时MCU应探测到电平下降沿。
#define KEY0 3 //PE4--3,在gpio.c文件pin_index pins[]中查到PE4编号为3
void hdr_callback(void *args)//回调函数
{
char *a = args;//获取参数
rt_kprintf(“key0 down! %s”,a);
}
void irq_thread_entry(void* parameter)
{
//上拉输入
rt_pin_mode(KEY0, PIN_MODE_INPUT_PULLUP);
//绑定中断,下降沿模式,回调函数名为hdr_callback
rt_pin_attach_irq(KEY0, PIN_IRQ_MODE_FALLING, hdr_callback, (void*)“callback
args”);
//使能中断
rt_pin_irq_enable(KEY0, PIN_IRQ_ENABLE);
}
在线程入口函数irq_thread_entry里首先调用rt_pin_attach_irq设置管脚GPIOE4为下降沿中断模式,并绑定了中断回调函数,还传入了字符串“callback args”。然后调用rt_pin_irq_enable使能中断,这样按键KEY0被按下时MCU会检测到电平下降沿,触发外部中断,在中断服务程序中会调用回调函数hdr_callback,在回调函数中打印传入的参数和提示信息。
下面是创建线程的代码:
rt_thread_t tid;//线程句柄
/* 创建irq线程 */
tid = rt_thread_create(“exirq”,
irq_thread_entry,
RT_NULL,
1024,
4,
10);
/* 创建成功则启动线程 */
if (tid != RT_NULL)
rt_thread_startup(tid);
编译、下载程序,我们按下按键KEY0,终端将打印提示字符。
3.5 I/O设备管理框架和通用GPIO设备联系
RT-Thread自动初始化功能依次调用rt_hw_pin_init ===》 rt_device_pin_register ===》 rt_device_register完成了GPIO硬件初始化。rt_device_register注册设备类型为RT_Device_Class_Miscellaneous,即杂类设备,从而我们就可以使用统一的API操作GPIO。
图A. 8 通用GPIO驱动和设备管理框架联系
4 参考
4.1 本文所有相关的API
要使用这些API需引用头文件
#include
4.1.1 API 列表(Summary)
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~