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协议

相关推荐
脚踏实地皮皮晨35 分钟前
002002002_DepandencyObject类2
开发语言·windows·算法·c#·visual studio
0566462 小时前
Python康复训练——数据结构
数据结构·windows·python
软萌萌的13 小时前
Python零基础从入门到精通详细教程-数据类型
开发语言·windows·python
东北赵四3 小时前
关于Java泛型的知识点及其相关面试题
java·windows·python
邱邱玩编程5 小时前
环境变量速切脚本【Windows】
windows
upgrador6 小时前
桌面应用开发:Electron 与 NSIS 的关系、打包流程及 Windows 本地构建实战
javascript·windows·electron
脚踏实地皮皮晨7 小时前
003002004_WPF Panel 基类 官方类定义
开发语言·windows·算法·c#·wpf·visual studio
sukalot7 小时前
windows网络适配器驱动开发-双 STA 连接(下)
windows·驱动开发·stm32
IT小盘17 小时前
12-Prompt不等于一句话-System-User-Context三层结构
java·windows·prompt
PieroPc1 天前
Python 写的 Windows凭据添加工具 第二版 解决Win11 23H2, 25H2,26H1,共享文件和打印 一部份问题,不是全部!
开发语言·windows·python