⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kbd_drv.c

📁 这是一个用于嵌入式用ep7312驱动源码
💻 C
字号:
#include <linux/slab.h>
#include <linux/init.h>
#include <asm/irq.h>

#include "ep7312_sys.h"

// ioctl 命令ID
#define KBD_GETKEY		1

// 定义键盘的主设备号
#define KEYBOARD_MAJOR 	59 

static char KeyValue;			/* 键值 */

// 设置键盘设备
void setup_kbd(void)
{
	// 设置系统寄存器
	SYSCON1 &= ~0xf;
	SYSCON1 |= 0x8;
	SYSCON2 |= 0x000000008;
	PADDR |= 0xfffffffff;

	// 初始化键值
	KeyValue = 0;	
}

// 键盘中断服务程序
void kbd_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	unsigned char LHB_PortA;		/* 端口A数据寄存器的低4位 */
	unsigned char row, col;			/* 按键的行列值 */
	unsigned char keypressed;		/* 是否有键按下的标志 */
	
	
	// 屏蔽键盘中断
	disable_irq(16);

	printk("kbd_Interrupt\n");
	// 获取端口A数据寄存器的低4位
	LHB_PortA = PADR & 0xf;
	
	// 判断列值:
	// 系统寄存器1的低4位为1000B, 列值为0
	// 系统寄存器1的低4位为1001B, 列值为1
	// 系统寄存器1的低4位为1010B, 列值为2
	// 系统寄存器1的低4位为1011B, 列值为3
	col = (SYSCON1 & 0xF) - 0x8;
	// 判断行值:
	// 端口A数据寄存器的低4位为0001B, 行值为0
	// 端口A数据寄存器的低4位为0010B, 行值为1
	// 端口A数据寄存器的低4位为0100B, 行值为2
	// 端口A数据寄存器的低4位为1000B, 行值为3
	keypressed = 0;
	for (row = 0; row < 4; row++)
	{
		if ((LHB_PortA >> row) & 0x1)
		{
			keypressed = 1;
			break;
		}
	}

	printk("keypressed = %d\n", keypressed);
	printk("row = %d, col = %d\n", row, col);
	// 计算键值
	if(keypressed)
	{	
		KeyValue = (row * 4 + 1) + col;
	}
	else
		enable_irq(16);
}

// 获取一个键值
int kbd_kernel_getkey()
{
	int i, j, k;

	// 开启键盘中断
	enable_irq(16);

	// 初始化键值
	KeyValue=0;
	// 循环将各列扫描线为高电平,
	// 检测是否有键按下
	for (i = 0; i < 4; i++)
	{
		// 循环置列线为高电平
		// 系统寄存器1的低4位为1000B, 列线0高电平
		// 系统寄存器1的低4位为1001B, 列线1高电平
		// 系统寄存器1的低4位为1010B, 列线2高电平
		// 系统寄存器1的低4位为1011B, 列线3高电平
		SYSCON1 &= ~0xf;
		SYSCON1 |= i % 4 + 8;
		
		// 延时循环, 避免键盘抖动
		for (j = 0; j < 1000; j++)
			for (k = 0; k < 650; k++)
				;
		
		// 如果有键按下, 则返回键值
		printk("kbd_kernel_getkey(): KeyValue = %d\n", KeyValue );
		if (KeyValue)
		{
			return KeyValue;
		}
	}

	// 无键按下, 返回0
	return 0;
}

// 打开键盘设备文件
int kbd_kernel_open(struct inode * inode, struct file * file)
{
	printk("<1> kbd_kernel_open()\n");
	return 0;
}

// 对键盘设备文件进行读写之外的其它操作
int kbd_kernel_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
{
	printk("kbd_kernel_ioctl()\n");

	switch (cmd)
	{
		// 接收一个按键
		case KBD_GETKEY:
			return kbd_kernel_getkey();

		default:
			printk("Unknown Keyboard command ID.\n");
	}

	return 0;
}

// 键盘设备文件操作结构
struct file_operations Kbd_fops = {
	open:		kbd_kernel_open,		/* 打开设备文件 */
	ioctl:		kbd_kernel_ioctl,		/* 设备文件的其它操作 */
};

// 初始化键盘设备
int kbd_kernel_init(void)
{
	int result;			/* 注册设备结果 */

	// 注册键盘设备
	printk("\nRegistering Keyboard Device\t--->\t");
	result = register_chrdev(KEYBOARD_MAJOR, "keyboard_ep7312", &Kbd_fops);
	printk("%d", result);
    if (result < 0) 
    {
		printk(KERN_INFO "[FAILED: Cannot register keyboard_ep7312!]\n");

		return result;
    }
	else
		printk("[OK]\n");

	printk("Initializing Keybaord Deviec\t--->\t");
	// 设置键盘设备
	setup_kbd();
	// 注册键盘中断
	if (request_irq(16, kbd_Interrupt, 0, "kbd_interrupt", NULL)) 
	{
		printk(KERN_INFO "[FAILED: Cannot register keybaord interrupt!]\n");

		return -EBUSY;
	}
	else
		printk("[OK]\n");

	// 显示成功加载信息
	printk("\nEP7312 Keyboard Driver installed.\n");
	printk("Written by BIT200009123.\n");

	return 0;
}

// 释放键盘设备
static void kbd_kernel_exit(void)
{    
	printk("Unregistering Keyboard Device\t--->\t");
	// 注销键盘中断
    free_irq(16, NULL);	 
	// 注销键盘设备
    unregister_chrdev(KEYBOARD_MAJOR, "keyboard_ep7312");
	printk("[OK]\n");

	return;
}	

// 初始化模块
module_init(kbd_kernel_init);
// 卸载模块
module_exit(kbd_kernel_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -