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

相关推荐
炒茄子20 小时前
Windows:解决电脑开机解锁后黑屏但鼠标可见可移动的问题
windows·计算机外设
luyun0202021 天前
流批了,pdf批量转excel
windows·pdf·excel·figma
vortex51 天前
在 Windows 系统中安装 Oracle、SQL Server(MSSQL)和 MySQL
windows·oracle·sqlserver
路由侠内网穿透1 天前
本地部署开源物联网平台 ThingsBoard 并实现外部访问( Windows 版本)
运维·服务器·windows·物联网·开源
Mr.Lu ‍1 天前
Windows开发,制作开发软件安装程序(二)
windows
skywalk81631 天前
windows装wsl ubuntu24.04 ,里面装qemu ,然后装mac os (windows也可以直接qemu安装macos)(未实践)
windows·ubuntu·macos·qemu
电脑小白技术1 天前
u盘安装系统提示“windows无法安装到这个磁盘,选中的磁盘具有gpt分区表”解决方法
windows·gpt·windows无法安装到磁盘
爱隐身的官人2 天前
Windows配置解压版MySQL5(免安装)
windows·mysql
JH30732 天前
10分钟理解泛型的通配符(extends, super, ?)
java·开发语言·windows
非凡ghost2 天前
MousePlus(鼠标增强工具) 中文绿色版
前端·windows·计算机外设·软件需求