IMX257 输入子系统(二)之键盘模拟

发布时间:2024-08-14  

接下来,我们使用IMX257的IO引脚中断+Linux输入子系统实现一个模拟键盘按键。实现的效果是,我们使用IO模拟按键L、按键S和Enter键 这三个按键。

 

这次我们就不再多废话了,直接上程序,大家看代码:

 实验效果图:

 如图所示: 我们依次按下三个按键

第一个按键 显示的键值为 38   ,也就是我们的L键

第二个按键  31   自然就是S 键

第三个按键  28  自然就是enter键

驱动代码:

  1 /******************************

  2     linux key_inputSystem

  3  *****************************/

  4 #include   

  5 #include   

  6 #include   

  7 #include   

  8 #include   

  9 #include   

 10 #include   

 11 #include   

 12 #include   

 13 #include   

 14 #include   

 15   

 16 #include   

 17 

 18 

 19 #include 'mx257_gpio.h'

 20 #include 'mx25_pins.h'

 21 #include 'iomux.h'

 22 

 23 #define Driver_NAME 'key_input'

 24 

 25 #define GPIO2_9     MX25_PIN_A23

 26 #define GPIO2_10    MX25_PIN_A24

 27 #define GPIO2_11    MX25_PIN_A25

 28 

 29 //定义各个按键按下的键值

 30 struct pin_desc{

 31     unsigned int pin;

 32     char *name;

 33     unsigned int key_val;

 34 };

 35 //当按键按下时,键值分别为 以下值

 36 struct pin_desc pins_desc[3] = {

 37     {GPIO2_9,  'KEY_L_9',    KEY_L},

 38     {GPIO2_10,  'KEY_R_10',    KEY_S},

 39     {GPIO2_11, 'KEY_Enter_11',    KEY_ENTER},

 40 };

 41 

 42 static struct input_dev *key_input_dev;//输入子系统设备结构体

 43 static struct timer_list key_timer;    //定时器结构体

 44 static struct pin_desc *pin_desc_irq; //保存发生中断的引脚信息

 45 

 46 //定时器到时函数

 47 static int key_timer_function(unsigned long data){    

 48     struct pin_desc *pin_desc_tmp = pin_desc_irq;    //发生中断的引脚信息

 49     unsigned int pinval_tmp;        //按键键值缓冲

 50     if(!pin_desc_tmp)

 51         return 0;

 52     pinval_tmp = gpio_get_value(IOMUX_TO_GPIO(pin_desc_tmp->pin));//获取键值

 53     if(pinval_tmp){

 54         //松开 :0   按下:1

 55         input_event(key_input_dev,EV_KEY,pin_desc_tmp->key_val ,0);

 56         input_sync(key_input_dev);                //报告完毕,通知接收者

 57     }else{

 58         input_event(key_input_dev,EV_KEY,pin_desc_tmp->key_val ,1);

 59         input_sync(key_input_dev);                //报告完毕,通知接收者

 60     }

 61     return 0;

 62 }

 63 /* 中断程序key_irq */

 64 static irqreturn_t key_irq_function(int irq, void *dev_id)

 65 {

 66     pin_desc_irq = (struct pin_desc *)dev_id; //获取中断引脚的信息

 67     mod_timer(&key_timer,jiffies+HZ/50);    //开启定时器,时间20ms

 68 

 69     return IRQ_RETVAL(IRQ_HANDLED);

 70 }

 71 //初始化函数

 72 static int __init  key_input_init(void)

 73  {

 74     printk('<0>nHello,this is %s module!nn',Driver_NAME);

 75       

 76     mxc_request_iomux(GPIO2_9, MUX_CONFIG_ALT5);//设备引脚为GPIO模式

 77     mxc_request_iomux(GPIO2_10, MUX_CONFIG_ALT5);//设备引脚为GPIO模式

 78     mxc_request_iomux(GPIO2_11, MUX_CONFIG_ALT5);//设备引脚为GPIO模式

 79      gpio_request(IOMUX_TO_GPIO(GPIO2_9), 'GPIO2_9');//申请IO端口使用

 80      gpio_request(IOMUX_TO_GPIO(GPIO2_10), 'GPIO2_10');//申请IO端口使用

 81      gpio_request(IOMUX_TO_GPIO(GPIO2_11), 'GPIO2_11');//申请IO端口使用

 82     gpio_direction_input(IOMUX_TO_GPIO(GPIO2_9));//设备引脚为输入

 83     gpio_direction_input(IOMUX_TO_GPIO(GPIO2_10));//设备引脚为输入

 84     gpio_direction_input(IOMUX_TO_GPIO(GPIO2_11));//设备引脚为输入

 85     //设备引脚为上拉输入

 86     mxc_iomux_set_pad(GPIO2_9, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU);

 87     mxc_iomux_set_pad(GPIO2_10, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU);

 88     mxc_iomux_set_pad(GPIO2_11, PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PU);

 89     //申请中断

 90     if(request_irq(IOMUX_TO_IRQ(GPIO2_9), key_irq_function, IRQF_TRIGGER_FALLING, 'key_GPIO2_9', &pins_desc[0]))

 91         return -1;

 92     if(request_irq(IOMUX_TO_IRQ(GPIO2_10), key_irq_function, IRQF_TRIGGER_FALLING, 'key_GPIO2_10', &pins_desc[1]))

 93         return -1;

 94     if(request_irq(IOMUX_TO_IRQ(GPIO2_11), key_irq_function, IRQF_TRIGGER_FALLING, 'key_GPIO2_11', &pins_desc[2]))

 95         return -1;

 96     

 97     //input输入子系统设置

 98     key_input_dev = input_allocate_device();//分配一个input_dev结构体

 99     //设置能产生哪些事件

100     set_bit(EV_KEY, key_input_dev->evbit); //按键事件

101     set_bit(KEY_L, key_input_dev->keybit); // L键 按键

102     set_bit(KEY_S, key_input_dev->keybit); // S键 按键

103     set_bit(KEY_ENTER, key_input_dev->keybit); // ENTER键 按键

104     set_bit(KEY_LEFTSHIFT, key_input_dev->keybit); // LEFTSHIFT键 按键

105     //注册

106     input_register_device(key_input_dev);

107 

108     init_timer(&key_timer);    //初始化定时器

109     key_timer.function = &key_timer_function;    //设置定时器处理函数

110     add_timer(&key_timer);    //将该定时器加入内核

111     

112     printk('<0>have setting all pins to gpio interrupt mod by IRQF_TRIGGER_FALLING !n');

113     printk('Input system initialize successfu!nn');

114     return 0;

115 }

116 //exit

117 static void __exit key_input_exit(void)

118 {

119     printk('<0>nGoodbye,%s!nn',Driver_NAME);

120     /* free gpios */

121     free_irq(IOMUX_TO_IRQ(GPIO2_9),  &pins_desc[0]);

122     free_irq(IOMUX_TO_IRQ(GPIO2_10),  &pins_desc[1]);

123     free_irq(IOMUX_TO_IRQ(GPIO2_11),  &pins_desc[2]);

124     mxc_free_iomux(GPIO2_9, MUX_CONFIG_ALT5);

125     mxc_free_iomux(GPIO2_10, MUX_CONFIG_ALT5);

126     mxc_free_iomux(GPIO2_11, MUX_CONFIG_ALT5);

127     gpio_free(IOMUX_TO_GPIO(GPIO2_9));

128     gpio_free(IOMUX_TO_GPIO(GPIO2_10));

129     gpio_free(IOMUX_TO_GPIO(GPIO2_11));

130 

131     del_timer(&key_timer);        //删除定时器

132     input_unregister_device(key_input_dev);    //注销驱动

133     input_free_device(key_input_dev);        //释放结构体内存

134     printk('Input system unregister successfu!nn');

135 }

136 

137 /* 这两行指定驱动程序的初始化函数和卸载函数 */

138 module_init(key_input_init);

139 module_exit(key_input_exit);

140 

141 /* 描述驱动程序的一些信息,不是必须的 */

142 MODULE_AUTHOR('Lover雪');

143 MODULE_VERSION('0.1.0');

144 MODULE_DESCRIPTION('IMX257 key Driver');

145 MODULE_LICENSE('GPL');


应用程序代码:


 1 #include

 2 #include

 3 #include

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9 #include

10 #include

11 #include

12 #include 'mx257_gpio.h'

13 

14 

15 int main(int argc, char **argv)

16 {

17     int fd;

18     int key_value,i=0,count;

19     struct input_event ev_key;

20     

21     fd = open('/dev/input/event1',O_RDWR);

22     if(fd < 0){

23         printf('can't open !!!n');

24         exit(1);

25     }

26     printf('open successful!n');

27     while(1){

28         count = read(fd,&ev_key,sizeof(struct input_event));

29         for(i = 0; i<(int)count/sizeof(struct input_event); i++){

30             if(EV_KEY == ev_key.type)

31                 printf('type: %d ,code: %d ,value: %d n',ev_key.type, ev_key.code,ev_key.value);

32             if(EV_SYN == ev_key.type)

33                 printf('syn eventnn');

34         }

35     }

36     close(fd);

37     return 0;

38 }


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>