千家信息网

怎么使用pcDuino的外部中断

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇文章给大家分享的是有关怎么使用pcDuino的外部中断,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。按键中断-poll机制我们尝试让
千家信息网最后更新 2026年11月01日怎么使用pcDuino的外部中断

本篇文章给大家分享的是有关怎么使用pcDuino的外部中断,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

按键中断-poll机制

我们尝试让按键具有这样一种功能,如果一定的时间内没有人去按按键,内核就提醒一下,然后我们应用程序得到提醒之后打印time out。

驱动程序

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define GPIO_IRQ 28

#define GPIO_TEST_BASE 0xf1c20800

#define PH_CFG2 (GPIO_TEST_BASE + 0x104)

#define PIO_INT_CFG2 (GPIO_TEST_BASE+ 0x208)

#define PIO_INT_CTL (GPIO_TEST_BASE+ 0x210)

#define PH17_SELECT (6 << 4)

#define PH18_SELECT (6 << 8)

#define PH19_SELECT (6 << 12)

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

/* 中断事件标志, 中断服务程序将它置1,third_drv_read将它清0 */

static volatile int ev_press = 0;

static struct class *keydrv_class;

static unsigned int status;

static irqreturn_t key_irq(int irq, void *dev_id)

{

status =readl(GPIO_TEST_BASE + 0x214 ) ;

ev_press = 1; /* 表示中断发生了 */

wake_up_interruptible(&button_waitq); /* 唤醒休眠的进程 */

writel(status,GPIO_TEST_BASE + 0x214);

return IRQ_HANDLED;

}

static int key_drv_open(struct inode *inode, struct file *file)

{

int error;

int irq_ctl;

/*1,设置中断位*/

irq_ctl =readl(PH_CFG2);

writel(PH19_SELECT|PH17_SELECT|PH18_SELECT| irq_ctl ,PH_CFG2);

/*2,设置中断方式*/

irq_ctl =readl(PIO_INT_CFG2);

writel((0x4<<(1*4))|(0x4 <<(2*4))|(0x4 <<(3*4)) | irq_ctl,PIO_INT_CFG2);

/*3,开中断*/

irq_ctl =readl(PIO_INT_CTL);

writel((0xf <<16)|irq_ctl,PIO_INT_CTL);

error =request_irq(GPIO_IRQ, key_irq,0, "button", 1);

if (error) {

printk("failed toregister keypad interrupt\n");

}

printk(KERN_ALERT"keyopeni\n");

return 0;

}

static unsigned key_drv_poll(struct file *file, poll_table *wait)

{

unsigned int mask = 0;

poll_wait(file,&button_waitq, wait); // 不会立即休眠

if (ev_press)

mask |=POLLIN | POLLRDNORM;

return mask;

}

ssize_t key_drv_read(struct file *file, char __user *buf, size_tsize, loff_t *ppos)

{

/* 如果没有按键动作, 休眠 */

wait_event_interruptible(button_waitq,ev_press);

/* 如果有按键动作, 返回键值 */

copy_to_user(buf,&status, sizeof(unsigned int));

ev_press = 0;

return 1;

}

static ssize_t key_drv_write(struct file *file, const char __user*buf, size_t count, loff_t * ppos)

{

printk(KERN_ALERT"keywrite\n");

return 0;

}

int key_drv_close(struct inode *inode, struct file *file)

{

free_irq(GPIO_IRQ,1);

return 0;

}

static struct file_operations key_drv_fops = {

.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open = key_drv_open,

.write = key_drv_write,

.read = key_drv_read,

.release = key_drv_close,

.poll = key_drv_poll,

};

int major;

static int key_drv_init(void)

{

major =register_chrdev(0, "key_drv", &key_drv_fops);

keydrv_class =class_create(THIS_MODULE,"key_drv");

device_create(keydrv_class,NULL,MKDEV(major,0),NULL,"key");

printk(KERN_ALERT"register\n");

return 0;

}

static void key_drv_exit(void)

{

unregister_chrdev(major,"key_drv"); // 卸载

device_destroy(keydrv_class,MKDEV(major,0));

class_destroy(keydrv_class);

printk(KERN_ALERT"unregister\n");

}

module_init(key_drv_init);

module_exit(key_drv_exit);

MODULE_LICENSE("GPL");

测试程序 test_key.c (706 Bytes, 下载次数: 0, 售价: 5 金钱) :

#include

#include

#include

int kbit = 0;

void PrintBinary(unsigned int c)

{

if (c>>1)PrintBinary(c>>1);

printf("%d:%d",kbit, c&1);

kbit++;

}

int main()

{

int fd;

unsigned int val = 1;

int ret;

struct pollfd fds[1];

fd =open("/dev/key",0666);

if(fd < 0)

{

printf("cannotopen\n");

return 0;

}

fds[0].fd = fd;

fds[0].events =POLLIN;

while(1)

{

kbit = 0;

ret =poll(fds, 1, 5000);

if (ret ==0)

{

printf("timeout\n");

}

else

{

read(fd,&val,sizeof(unsignedint));

PrintBinary(val);

if(val&(1<<17))printf("Back\n");

if(val&(1<<18))printf("home\n");

if(val&(1<<19))printf("menu\n");

}

}

close(fd);

return 0;

}

编译:

gcc test_key.c

测试:

root @ubuntu :/home/ubuntu/driver/key_02# ./a.out

[10049.740000] key openi

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 18:0 home

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 18:0 home

time out

time out

time out

time out

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 Back

0:1 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:015:0 16:0 17:0 Back

以上就是怎么使用pcDuino的外部中断,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

按键 程序 休眠 动作 更多 知识 篇文章 测试 编译 实用 事件 内核 功能 变量 售价 就是 工作会 应用程序 文章 方式 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州紫鲸互联网科技有限公司 科技金融是不是互联网金融 互联网科技公司的优势 互联网金融 科技 狮子座互联网科技有限公司 互联网金融科技委员会 镁科技互联网资讯平台 深圳互联网科技怎么样 海南科技产业互联网平台 须眉科技是互联网公司吗 互联网企业和科技型企业 互联网科技教育视频 互联网科技公司有风险吗 哈尔滨屹滨互联网科技有限公司 消费医药和互联网科技 互联网科技公司营业执照怎么办理 黑云互联网科技有限公司 互联网科技包装股份有限公司上市 保山浩联互联网科技有限公司 小牛互联网科技有限公司地址 涨乐互联网科技 金融科技与互联网金融 互联网金融公司科技 互联网科技logo 互联网 新科技 镁科技互联网资讯平台 千方科技属于互联网企业吗 互联网科技大赛获奖感言 卓翼科技产业互联网合作 杭州科技互联网公司有哪些
0