24.4.17 驱动开发定时器作业,消抖

  • 定时器消抖工作原理
    • 在按键按下之后,进入中断处理函数,在中断处理函数中,定时时间10ms
    • 当定时时间到,执行定时器处理函数,在定时器处理函数中,读取管脚的电平状态
    • 如果读到的是低电平,表示按键按下
    • 编写设备树
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/timer.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
/*
myled{
    extend-led{
        led1 = <&gpioe 10 0>; //LED1 PE10
        led2 = <&gpiof 10 0>; //LED2 PF10
        led3 = <&gpioe 8 0>; //LED3 PE8
    };
    core-led{
        "led" = <&gpioz 5 0>,<&gpioz 6 0>,<&gpioz 7 0>; //LED1 PE10
    };
};

mykey{
    interrupt-parent = <&gpiof>;
    interrupts = <9 0>,<7 0>,<8 0>;
};
*/
struct device_node *node;
int gpiono;
char *name[3] = {"led1", "led2", "led3"};

struct timer_list mytimer; // 分配定时器对象
// 定时器处理函数
void timer_func(struct timer_list *timer)
{
    int i = gpio_get_value(gpiono);   
    if(i==0)
    {
        printk("引脚为低电平");
    }
    else
    {
        printk("引脚为高电平");
    }
}

int irqno;
// 中断处理函数
irqreturn_t key_irq_handler(int irq, void *dev)
{
    printk("key1 down!!!!!\n");
    mytimer.expires = jiffies + 100;      // 定时时间为1s
    timer_setup(&mytimer, timer_func, 0); // 定时器初始化
    add_timer(&mytimer);                  // 启动定时器
    return IRQ_HANDLED;                   // 表示中断处理完成
}

// 入口
static int __init demo_init(void)
{
    int ret;
    // 解析设备树节点信息
    node = of_find_node_by_name(NULL, "myled"); // 通过节点的名字获取节点相关信息
    if (node == NULL)
    {
        printk("of find node by name is error\n");
        return -EIO;
    }

    // 映射软中断号
    irqno = irq_of_parse_and_map(node, 0);
    if (irqno < 0)
    {
        printk("irq of parse and map is error\n");
        return -EIO;
    }

    gpiono = of_get_named_gpio(node, name[0], 0);
    if (gpiono < 0)
    {
        printk("of get named gpio is error");
        return -EIO;
    }

    // 注册中断子系统
    ret = request_irq(irqno, key_irq_handler, IRQF_TRIGGER_FALLING, "KEY1", NULL);
    if (ret)
    {
        printk("request irq is error\n");
        return -EIO;
    }
    return 0;
}

// 出口 卸载驱动 LED1熄灭
static void __exit demo_exit(void)
{
    //设置gpio编号输出低电平
    gpio_direction_output(gpiono, 0);
    // 释放gpio编号
    gpio_free(gpiono);
    del_timer(&mytimer);
    // 注销中断
    free_irq(irqno, NULL);
}

module_init(demo_init); // 指定入口地址
module_exit(demo_exit); // 指定出口地址
MODULE_LICENSE("GPL");  // 遵循GPL协议

相关推荐

  1. 4.19作业 驱动开发

    2024-04-21 17:20:04       34 阅读
  2. Linux嵌入式驱动开发-内核定时器

    2024-04-21 17:20:04       34 阅读
  3. Linux内核驱动开发-006内核定时器

    2024-04-21 17:20:04       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-21 17:20:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-21 17:20:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-21 17:20:04       82 阅读
  4. Python语言-面向对象

    2024-04-21 17:20:04       91 阅读

热门阅读

  1. 解决端口是0问题,解决mysql无法看到3306端口监听

    2024-04-21 17:20:04       34 阅读
  2. 【软件测试】单元测试+集成测试+系统测试

    2024-04-21 17:20:04       31 阅读
  3. typescript 编译配置

    2024-04-21 17:20:04       37 阅读
  4. Edge浏览器:使用心得与深度探索

    2024-04-21 17:20:04       31 阅读
  5. arm 作业 24/4/17

    2024-04-21 17:20:04       32 阅读
  6. 小程序插件引入宿主的函数

    2024-04-21 17:20:04       33 阅读
  7. docker 安装nacos最新版本单机版

    2024-04-21 17:20:04       32 阅读
  8. 【PHP快速上手(十四)】

    2024-04-21 17:20:04       33 阅读
  9. python学习笔记22 excel汇总

    2024-04-21 17:20:04       77 阅读
  10. 【云计算】混合云组成、应用场景、风险挑战

    2024-04-21 17:20:04       63 阅读