linux定时器按键,用定时器实现按键消抖

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 #include

10 #include

11 #include

12

13

14 staticint major;

15

16 static struct class *myKey_class;

17 static struct class_device *myKey_class_dev;

18

19 volatileunsigned long *gpfcon;

20 volatileunsigned long *gpfdat;

21

22 volatileunsigned long *gpgcon;

23 volatileunsigned long *gpgdat;

24

25 //static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

26 //static volatile int ev_press = 0;

27

28 static struct fasync_struct *button_fasyncq;

29

30 //定义原子变量,并初始化为1

31 staticatomic_t

canOpen = ATOMIC_INIT(1);

32

33 //定义一个定时器

34 static struct timer_list buttons_timer;

35

36 //normal:1; press:0;

37 staticunsigned char keyVal = 0;

38

39 struct pin_desc {

40         unsigned int pin;

41         unsigned int key_val;

42 };

43

44 /*

45 * 按键按下键值为0x01,...; 松开键值为0x81,...

46 */

47 struct pin_desc pins_desc[3] = {

48         {S3C2410_GPF0, 0x01},

49         {S3C2410_GPF2, 0x02},

50         {S3C2410_GPG11, 0x03},

51 };

52

53 struct pin_desc *irq_pd;

54

55 staticint myKey_open(struct inode *inode, struct file

*file);

56 staticint myKey_close(struct inode *inode, struct file *file);

57 staticssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);

58 staticint myKey_fasync(int fd, struct file *filp, int on);

59

60

61 static struct file_operations myKey_fops = {

62         .open = myKey_open,

63         .read = myKey_read,

64         .owner = THIS_MODULE,

65         .release = myKey_close,

66         .fasync = myKey_fasync,

67 };

68

69

70 staticirqreturn_t handle_buttons(int irq, void *pin_dc)

71 {

72         /* 每次发生中断,10ms后启动定时器,定时器超时,再读取键值,实现按键消抖 */

73         irq_pd = (struct pin_desc*)pin_dc;

74         mod_timer(&buttons_timer, jiffies+HZ/100);        //修改定时器超时时间,启动定时器

75

76         return IRQ_RETVAL(IRQ_HANDLED);

77 }

78

79

80 staticint myKey_open(struct inode *inode, struct file *file)

81 {

82         /*

83 *当原子变量为1时,驱动程序处于空闲状态,可被打开,否则打开失败并返回

84 */

85         if (!atomic_dec_and_test(&canOpen))        //atomic_dec_and_test――原子变量自减,结果为0返回ture,否则返回false

86         {

87                                                                 //atomic_inc――原子变量自加

88                 atomic_inc(&canOpen);        //恢复原子变量为原来值

89                 return-EBUSY;

90         }

91

92         request_irq(IRQ_EINT0, handle_buttons, IRQT_BOTHEDGE, "S2", &pins_desc[0]);

93         request_irq(IRQ_EINT2, handle_buttons, IRQT_BOTHEDGE, "S3", &pins_desc[1]);

94         request_irq(IRQ_EINT19, handle_buttons, IRQT_BOTHEDGE, "S5", &pins_desc[2]);

95

96         return0;

97 }

98

99

100 staticint myKey_close(struct inode *inode, struct file *file)

101 {

102         atomic_inc(&canOpen);        //关闭驱动,恢复原子变量默认值

103

104         free_irq(IRQ_EINT0, &pins_desc[0]);

105         free_irq(IRQ_EINT2, &pins_desc[1]);

106         free_irq(IRQ_EINT19, &pins_desc[2]);

107

108         return0;

109 }

110

111 int myKey_fasync(int fd, struct file *filp, int on)

112 {

113         printk("driver: fasync_init\n");

114         fasync_helper(fd, filp, on, &button_fasyncq);

115

116         return0;

117 }

118

119 staticssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)

120 {

121         //无中断进入休眠

122         //wait_event_interruptible(button_waitq, ev_press);

123

124         //ev_press = 0;        //清除中断发生标志

125         copy_to_user(buf, &keyVal, 1);

126         return0;

127 }

128

129

130 void handle_buttons_timer(unsigned long data)

131 {

132         unsigned int kval;

133         struct pin_desc *pinDesc = irq_pd;

134

135         //定时器初次初始化完成,超时处理,此时并未发生过按键中断

136         if (!pinDesc)

137         {

138                 return;

139         }

140

141         kval = s3c2410_gpio_getpin(pinDesc->pin);

142         if (kval)        //松开

143         {

144                 keyVal = 0x80 | pinDesc->key_val;

145         }

146         else {                //按下

147                 keyVal = pinDesc->key_val;

148         }

149

150         //唤醒休眠进程

151         //ev_press = 1;        //中断发生标志

152         //wake_up_interruptible(&button_waitq);

153

154         kill_fasync(&button_fasyncq, SIGIO, POLL_IN);

155 }

156

157

158 staticint __init myKey_init(void)

159 {

160         /* 初始化定时器 */

161         init_timer(&buttons_timer);

162         buttons_timer.expires = 0;        //设置定时器超时,默认初始化完成后进入休眠

163         buttons_timer.function = handle_buttons_timer;        //注册定时器超时处理函数

164         add_timer(&buttons_timer);

165

166         /* 物理地址映射成虚拟地址 */

167         gpfcon = (volatileunsigned long*)ioremap(0x56000050, 16);

168         gpfdat = gpfcon + 1;

169

170         gpgcon = (volatileunsigned long*)ioremap(0x56000060, 16);

171         gpgdat = gpgcon + 1;

172

173         major = register_chrdev(0, "myKey", &myKey_fops);

174

175         myKey_class = class_create(THIS_MODULE, "myKeyclass");

176         myKey_class_dev = class_device_create(myKey_class, NULL, MKDEV(major, 0), NULL, "myKey");

177

178         return0;

179 }

180

181 staticvoid __exit myKey_exit(void)

182 {

183         /* 释放虚拟地址映射 */

184         iounmap(0x56000050);

185         iounmap(0x56000060);

186

187         unregister_chrdev(major, "myKey");

188

189         class_device_unregister(myKey_class_dev);

190         class_destroy(myKey_class);

191         return;

192 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值