How to eliminate jitter
After an interrupt occurs, delay for a period of time (jitter time t) before reading the key value;
The method to achieve this delay here is to use a timer;
When a key interrupt occurs, the timer is started, and the key value is read after the timer delays for t seconds.
Examples
driver.c
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 static int major;
15
16 static struct class *myKey_class;
17 static struct class_device *myKey_class_dev;
18
19 volatile unsigned long *gpfcon;
20 volatile unsigned long *gpfdat ;
21
22 volatile unsigned long *gpgcon;
23 volatile unsigned 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 //Define atomic variables and initialize them 1
31 static atomic_t canOpen = ATOMIC_INIT(1);
32
33 //Define a timer
34 static struct timer_list buttons_timer;
35
36 //normal:1; press:0;
37 static unsigned char keyVal = 0;
38
39 struct pin_desc {
40 unsigned int pin;
41 unsigned int key_val;
42 };
43
44 /*
45 * The key value when the key is pressed is 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 static int myKey_open(struct inode *inode, struct file *file);
56 static int myKey_close(struct inode *inode, struct file *file);
57 static ssize_t myKey_read(struct file *file, char __user *buf , size_t size, loff_t *ppos);
58 static int 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 static irqreturn_t handle_buttons(int irq, void *pin_dc)
71 {
72 /* Every time an interrupt occurs, the timer is started after 10ms. When the timer times out, the key value is read to achieve key debounce*/
73 irq_pd = (struct pin_desc*)pin_dc;
74 mod_timer(&buttons_timer, jiffies+HZ/100); //Modify the timer timeout and start the timer
75
76 return IRQ_RETVAL(IRQ_HANDLED);
77 }
78
79
80 static int myKey_open(struct inode *inode, struct file *file)
81 {
82 /*
83 *When the atomic variable is 1, the driver is in idle state and can be opened, otherwise the opening fails and returns
84 */
85 if (!atomic_dec_and_test(&canOpen)) //atomic_dec_and_test--Atomic variable self-decrement, the result is 0 and returns true, otherwise returns false
86 {
87 //atomic_inc--Atomic variable self-increment
88 atomic_inc(&canOpen); //Restore the atomic variable to the original value
89 return -EBUSY;
90
103
104 free_irq(IRQ_EINT0, &pins_desc[0]); 105 } 96 97 108 static int myKey_close(struct inode *inode, struct file *file) 109 { 110 atomic_inc(&canOpen); //Close the driver and restore the default value
of
atomic
variables 111
112
free_irq(IRQ_EINT0, &pins_desc[0]); 113 114 free_irq(IRQ_EINT19, handle_buttons,
IRQT_BOTHEDGE, "S5", &pins_desc[2]); 115
}
96
97
118 static int myKey_close(struct inode *inode, struct file *file)
119 {
120 atomic_inc(&canOpen); //Close the driver and restore the default value of atomic variables
121
122 free_irq(IRQ_EINT2, &pins_desc[1]);
123 free_irq(IRQ_EINT2, &pins_desc[1]);
106 free_irq(IRQ_EINT19, &pins_desc[2]);
107
108 return 0;
109 }
110
111 int myKey_fasync(int fd, struct file *filp, int on)
112 {
113 printk("driver: fasync_ initn");
114 fasync_helper(fd, filp, on, &button_fasyncq);
115
116 return 0;
117 }
118
119 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
120 {
121 //Enter sleep without interruption
122 //wait_event_interruptible(button_waitq, ev_press);
123
124 //ev_press = 0; //Clear interrupt flag
125 copy_to_user(buf, &keyVal, 1);
126 return 0;
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 //Timer initialization completed, timeout processing, no key interrupt occurred at this time
136 if (!pinDesc)
137 {
138 return;
139 }
140
141 kval = s3c2410_gpio_getpin(pinDesc->pin);
142 if (kval) //Release
143 {
144 keyVal = 0x80 | pinDesc->key_val;
145 }
146 else { //Press
147 keyVal = pinDesc->key_val;
148 }
149
150 //Wake up the sleeping process
151 //ev_press = 1; //Interrupt flag
152 //wake_up_interruptible(&button_waitq);
153
154 kill_fasync(&button_fasyncq, SIGIO, POLL_IN);
155 }
156
157
158 static int __init myKey_init(void)
159 {
160 /* Initialize timer*/
161 init_timer(&buttons_timer);
162 buttons_timer.expires = 0; //Set timer timeout, default enters sleep after initialization is completed
163 buttons_timer.function = handle_buttons_timer; //Register timer timeout processing function
164 add_timer(&buttons_timer);
165
166 /* Map physical address to virtual address*/
167 gpfcon = (volatile unsigned long*)ioremap(0x56000050, 16);
168 gpfdat = gpfcon + 1;
169
170 gpgcon = (volatile unsigned 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 return 0;
179 }
180
181 static void __exit myKey_exit(void)
182 {
183 /* Release virtual address mapping*/
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 }
app.c
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7
8 int fd;
9
10 void handle_signal(int signum)
11 {
12 unsigned char keyVal;
13
14 read(fd, &keyVal, 1);
15 printf("keyVal: 0x%xn", keyVal);
16
17 return ;
18 }
19
20
21 int main (void)
22 {
23 int oflag = 0;
24
25 printf("test app!n");
26
27 fd = open("/dev/myKey", O_RDWR);
28 if( fd < 0)
29 {
30 printf("open failed! %dn", fd);
31 return -1;
32 }
33
34 signal(SIGIO, handle_signal);
35
36 fcntl(fd, F_SETOWN, getpid());
37 oflag = fcntl(fd, F_GETFL);
38 fcntl(fd, F_SETFL, oflag | O_ASYNC);
39
40 while(1)
41 {
42 sleep(5);
43 }
44 return 0;
45 }
Makefile
1 KERN_DIR = /work/system/linux-2.6.22.6
2
3 all:
4 make -C $(KERN_DIR) M=`pwd` modules
5
6 clean:
7 make -C $(KERN_DIR) M=`pwd` modules clean
8 rm -rf modules.order
9
10 obj-m += myKey_all.o
Previous article:Detailed Explanation of S3C2440 Memory Controller
Next article:Asynchronous Notification
Recommended ReadingLatest update time:2024-11-15 07:50
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- [ST NUCLEO-H743ZI Review] + 5. CAN communication transceiver test
- Request resume
- MicroPython Hands-on (30) - Blynk for the Internet of Things
- 7nm lithography machine was used to pay off debts, hundreds of employees were laid off, and the 100 billion chip project came to an end!!!
- What do the numbers in the brackets mean? [3:0] and [11:4] What is 11~4?
- When I mentioned that inviting 8 people to search one by one was too much trouble, the administrator reduced the number of people that can be invited from 8 to 4. High, high, high
- Evaluation summary: Allwinner heterogeneous multi-core AI intelligent vision V853 development board
- Common basic settings of timer T0, T1
- [nRF52840 DK Review] Improve custom services - send data
- Application of high-precision current source in gyroscope testing