设为首页 加入收藏

TOP

TQ2440按键点亮LED驱动程序(一)
2014-11-23 19:49:11 】 浏览:761
Tags:TQ2440 按键 点亮 LED 驱动程序

一,硬件分析:


1.打开TQ2440的底板原理图找到按键测试的模块,如下图所示:


TQ2440按键点亮LED驱动程序


从图我们知道,控制按键k1 k2 k3 k4 的管脚为EINT1 EINT4 EINT2 EINT0 ,当按键按下时,管脚输出低电平,当按键没有被按下时,管脚输出高电平。


2.打开TQ2440核心板原理图找到EINT1 EINT4 EINT2 EINT0所对应的cpu控制引脚,如下图所示:


TQ2440按键点亮LED驱动程序


从图我们可以知道,EINT1 EINT4 EINT2 EINT0 对应的cpu控制引脚为GPF1 GPF4 GPF2 GPF0 。


3.打开s3c2410的芯片手册查看引脚GPF1 GPF4 GPF2 GPF0 ,如下图所示 :


TQ2440按键点亮LED驱动程序


如图我们知道如何将cpu引脚 GPF1 GPF4 GPF2 GPF0 设置成中断模式,比如我要将GPF0设置成为中断模式,我只需要将其寄存器二进制的第1位和第0位设置成为1和0即可,但是我们只需要知道原理即可,具体将引脚设置成为中断模式,我们可以利用linux内核中的一些宏来实现。


二,按键点亮LED驱动程序源码Button6.c :


#include
#include
#include
#include
#include
#include
#include //定义 IRQ_TYPE_EDGE_BOTH
#include
#include
#include
#include
#include
#include
#include

#define DEVICE_NAME "button6" //设备名称
#define DEVICE_MAJOR 2898 //主设备号
#define LED_ON 1 //定义LED亮为1
#define LED_OFF 0 //定义LED暗为0

//定义按键中断结构体
struct button_irq
{
int irq; //中断号
int pin; //中断控制引脚
int pin_setting; //中断控制引脚的设置(设置控制引脚为中断模式)
int number; //按键编号
char *name; //按键名称
};

//按键数组,包含4个按键的信息
//S3C2410_GPF0_EINT0在Regs-gpio.h中
static struct button_irq button_irqs [] =
{
{IRQ_EINT1, S3C2410_GPF1, S3C2410_GPF1_EINT1, 0, "KEY1"}, //按键K1
{IRQ_EINT4, S3C2410_GPF4, S3C2410_GPF4_EINT4, 1, "KEY2"}, //按键K2
{IRQ_EINT2, S3C2410_GPF2, S3C2410_GPF2_EINT2, 2, "KEY3"}, //按键K3
{IRQ_EINT0, S3C2410_GPF0, S3C2410_GPF0_EINT0, 3, "KEY4"}, //按键K4
};

//保存按键值的数组
//volatile关键字意义:每次读和写都是用内存中的值而不是CPU寄存器的值
static volatile int key_values [] = {0, 0, 0, 0};

static unsigned long led_table [] ={ S3C2410_GPB5, S3C2410_GPB6, S3C2410_GPB7, S3C2410_GPB8,};//LED控制引脚
//LED控制引脚的设置(设置引脚为输出模式)
static unsigned int led_cfg_table [] ={ S3C2410_GPB5_OUTP, S3C2410_GPB6_OUTP, S3C2410_GPB7_OUTP, S3C2410_GPB8_OUTP,};

//等待队列:
//等待队列头,当应用程序读取按键时,如果此时没有按键按下,程序就休眠
static DECLARE_WAIT_QUEUE_HEAD(button_waitq); //定义并初始化等待队列
static volatile int ev_press = 0; //按键是否被按的标志(按下和松开都算)

//中断处理函数
static irqreturn_t buttons_interrupt(int irq, void *dev_id)
{
struct button_irq *button_irqs = (struct button_irq*)dev_id; //获取request_irq注册中断时关联的参数信息
int up = s3c2410_gpio_getpin(button_irqs->pin); //注册中断
if (up)
key_values[button_irqs->number] = (button_irqs->number + 1) + 0x80;
else
key_values[button_irqs->number] = (button_irqs->number + 1); //根据中断注册情况设置按键的值
ev_press = 1; //表示中断发生了
wake_up_interruptible(&button_waitq); //唤醒休眠的进程
return IRQ_RETVAL(IRQ_HANDLED);//返回中断信息
}

//定义open方法
static int buttons_open(struct inode *inode, struct file *file)
{
int i;
int err;
for (i = 0; i < 4; i++)
{
s3c2410_gpio_cfgpin(button_irqs[i].pin,button_irqs[i].pin_setting); //设置中断控制引脚为中断模式
err = request_irq(button_irqs[i].irq, buttons_interrupt, NULL, button_irqs[i].name, (void *)&button_irqs[i]); //申请中断
if (err) //返回值为非零值表示申请中断不成功
break;
}
if (err) //申请中断错误处理
{
for (; i >= 0; i--)
{
//释放已经注册的中断
disable_irq(button_irqs[i].irq);
free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
}
return -EBUSY; //返回值表示中断已被占用且不能共享
}
//配置LED引脚为输出模式
for (i = 0; i < 4; i++)
{
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
}
return 0;
}

//定义close方法
static int buttons_close(struct inode *inode, struct file *file)
{
int i;
for (i = 0; i < 4; i++)
{
// 释放已经注册的中断
disable_irq(button_irqs[i].irq);
free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
}
return 0;
}

//定义read方法
s

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇STL之pair类型详细分析 下一篇STL之iterator(迭代器)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目