如果你使用的是linux系统
给你贴一个我几年前写的驱动,控制指示灯和液晶背光的驱动。
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/syscalls.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/delay.h>
/*******Driver Config Macro***********************************************/
#define USING_BEEP 1
//#define KEYBOARD_IRQS 1
#define USING_DEBUG_INFOR 1
#define KERNEL_2_6_8
#ifndef KERNEL_2_6_8
#define KERNEL_2_6_20
#endif
/*******LED Register Macro************************************************/
#define LED_DATA_REGS GPIO_PBDR
#define LED_DIRC_REGS GPIO_PBDDR
/*******Beep Macro********************************************************/
#define BEEP_MASK 0x01
#define BEEP_ON 0x01
/*******Mask Macro********************************************************/
#define LCD_POWER_MASK 0x10
#define KEYBOARD_MASK 0x08
#define LED_MASK_ALL 0x06
#define LED_MASK_FIRST 0x04
#define LED_MASK_SECOND 0x02
/*******LED Command Macro*************************************************/
#define LED_CMD_LED1_ON 0x01
#define LED_CMD_LED2_ON 0x02
#define LED_CMD_LED1_OFF 0x10
#define LED_CMD_LED2_OFF 0x20
#ifdef USING_BEEP
#define BEEP_CMD_ON 0x04
#define BEEP_CMD_OFF 0x40
#endif
#define LCD_CMD_PWOER_ON 0x08
#define LCD_CMD_PWORE_OFF 0x80
/*******Driver Name Macro*************************************************/
#define LED_NAME "EP9315 Led Driver"
/*******IRQ Number Macro**************************************************/
#define IRQ_NUM_KEYBOARD IRQ_GPIO
/*******Function Declear Macro********************************************/
#ifdef KEYBOARD_IRQS
static void keyboard_init(void);
static irqreturn_t ep93xx_keyboard_isr(int irq, void *dev_id, struct pt_regs *regs);
#endif
static void delay(long t);
static void led_init(void);
static void led_first_on(void);
static void led_first_off(void);
static void led_second_on(void);
static void led_second_off(void);
MODULE_LICENSE("GPL"); // License.
MODULE_AUTHOR("Guoyun He"); // Author
MODULE_DESCRIPTION("EP9315 Led Driver"); // Descripition
static int major = 0; // default to dynamic major.
#ifdef KERNEL_2_6_8
MODULE_PARM(major, "i");
#endif
#ifdef KERNEL_2_6_20
module_param(major, int, 0);
#endif
MODULE_PARM_DESC(major, "Major device number"); // Module parameter description.
/**************************************************************************
* Function Name: static void delay(long t).
* Function Desc: delay sometime.
* Input: t - delay seconds.
* Return: None.
**************************************************************************/
static void delay(long t)
{
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(t);
}
/**************************************************************************
* Function Name: static irqreturn_t ep93xx_keyboard_isr(int irq,
* void *dev_id, struct pt_regs *regs).
* Function Desc: ep93xx keyboard isr.
* Input: irq -
* dev_id -
* regs -
* Return: None.
**************************************************************************/
#ifdef KEYBOARD_IRQS
static irqreturn_t ep93xx_keyboard_isr(int irq, void *dev_id, struct pt_regs *regs)
{
u32 tmp, mm;
static unsigned long tt = 0;
static unsigned long lasttick = 0x00;
static unsigned char isr_st = 0x00;
//tmp = inl( GPIO_RAWINTSTSTISB );
tmp = inl( GPIO_INTSTATUSB );
tmp &= KEYBOARD_MASK;
if( tmp == KEYBOARD_MASK )
{
outl( tmp, GPIO_BEOI );
if( ( ( jiffies - lasttick ) > 7 ) && ( isr_st != 0x00 ) )
{
isr_st = 0x00;
}
if( isr_st == 0x00 )
{
tt = jiffies;
isr_st = 0x01;
}
else if( isr_st == 0x01 )
{
if( 5 < (jiffies-tt) )
{
isr_st = 0x02;
tt = jiffies;
}
}
else if( isr_st == 0x02 )
{
if( 5 < (jiffies-tt) )
{
isr_st = 0x03;
tt = jiffies;
}
}
else if( isr_st == 0x03 )
{
if( 5 < (jiffies-tt) )
{
isr_st = 0x04;
tt = jiffies;
}
}
else if( isr_st == 0x04 )
{
if( 5 < ( jiffies-tt ) )
{
tmp = inl( GPIO_PBDR ); // Read LCD Power contrl REGs.
mm = tmp & LCD_POWER_MASK; //
if( mm == LCD_POWER_MASK )
{
tmp &= ~LCD_POWER_MASK;
}
else
{
tmp |= LCD_POWER_MASK;
}
outl( tmp, GPIO_PBDR ); // Out put.
isr_st = 0x00;
}
}
lasttick = jiffies;
}
return (IRQ_HANDLED);
}
#endif
#ifdef KEYBOARD_IRQS
/**************************************************************************
* Function Name: static void keyboard_init(void).
* Function Desc: Init Keyboard Interface.
* Input: None.
* Return: None.
**************************************************************************/
static void keyboard_init(void)
{
u32 tmp;
tmp = inl( GPIO_PBDDR ); // Read keyboard direction REGs.
tmp &= ~KEYBOARD_MASK; // Set to input mode.
outl( tmp, GPIO_PBDDR ); // Write the REGs.
tmp = inl( GPIO_BINTEN ); // Reads the Port B Interrupt register.
tmp &= ~KEYBOARD_MASK; // Disable interrupt.
outl( tmp, GPIO_BINTEN ); // Writes to the REGs.
tmp = inl( GPIO_BINTTYPE1 ); // Read Port B interrupt type register1.
//tmp |= KEYBOARD_MASK; // Set to edge sensitive.
tmp &= ~KEYBOARD_MASK; // Set to leverl sensitive.
outl( tmp, GPIO_BINTTYPE1 ); // Write back.
tmp = inl( GPIO_BINTTYPE2 ); // Read Port B interrupt type register2.
tmp &= ~KEYBOARD_MASK; // Set to failling edge.
//tmp |= KEYBOARD_MASK; // Set to Rising edge.
outl( tmp, GPIO_BINTTYPE2 ); // Write back.
tmp = inl( GPIO_BINTEN ); // Read the Port B Interrupt register.
tmp |= KEYBOARD_MASK; // Disable interrupt.
outl( tmp, GPIO_BINTEN ); // Write back.
tmp = inl( GPIO_PBDDR ); // Read LCD Power direction REGs.
tmp |= LCD_POWER_MASK; // Sets to output mode.
outl( tmp, GPIO_PBDDR ); // Write to the REGs.
tmp = inl( GPIO_PBDR ); // Read LCD Power contrl REGs.
tmp |= LCD_POWER_MASK; // Set the bit.
outl( tmp, GPIO_PBDR ); // Out put.
}
/**************************************************************************
* Function Name: static void keyboard_exit(void).
* Function Desc: Exit Keyboard Interface.
* Input: None.
* Return: None.
**************************************************************************/
static void keyboard_exit(void)
{
u32 tmp;
tmp = inl( GPIO_PBDDR ); // Read keyboard direction REGs.
tmp |= KEYBOARD_MASK; // Set to output mode.
outl( tmp, GPIO_PBDDR ); // Write the REGs.
tmp = inl( GPIO_BINTEN ); // Reads the Port B Interrupt register.
tmp &= ~KEYBOARD_MASK; // Disable interrupt.
outl( tmp, GPIO_BINTEN ); // Writes to the REGs.
tmp = inl( GPIO_PBDDR ); // Read LCD Power direction REGs.
tmp |= LCD_POWER_MASK; // Sets to output mode.
outl( tmp, GPIO_PBDDR ); // Write to the REGs.
tmp = inl( GPIO_PBDR ); // Read LCD Power contrl REGs.
tmp |= LCD_POWER_MASK; // Set the bit.
outl( tmp, GPIO_PBDR ); // Out put.
}
#endif
#ifdef USING_BEEP
/**************************************************************************
* Function Name: static void set_beep_on(void).
* Function Desc: Sets the beep on.
* Input: None.
* Return: None.
**************************************************************************/
static void set_beep_on(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS );
tmp &= ~BEEP_ON;
outl( tmp, LED_DATA_REGS );
}
/**************************************************************************
* Function Name: static void set_beep_off(void).
* Function Desc: Sets the beep off.
* Input: None.
* Return: None.
**************************************************************************/
static void set_beep_off(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS );
tmp |= BEEP_ON;
outl( tmp, LED_DATA_REGS );
}
/**************************************************************************
* Function Name: static void beep_init(void).
* Function Desc: Sets the beep pin as input pin, and init it.
* Input: None.
* Return: None.
**************************************************************************/
static void beep_init(void)
{
u32 tmp;
tmp = inl( LED_DIRC_REGS );
tmp |= BEEP_MASK;
outl( tmp, LED_DIRC_REGS );
set_beep_on();
delay(30); // Delay 30us.
set_beep_off();
}
#endif
/**************************************************************************
* Function Name: void led_init(void).
* Function Desc: Init the led gepio.
* Input: None.
* Return: None.
**************************************************************************/
static void led_init(void)
{
u32 tmp;
tmp = inl( LED_DIRC_REGS );
tmp |= LED_MASK_ALL;
outl( tmp, LED_DIRC_REGS );
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp &= ~LED_MASK_ALL; // Set the led bits off.
//tmp |= LED_MASK_ALL; // Set all the led on.
outl( tmp, LED_DATA_REGS ); // Output.
delay(30); // Delay 30us.
}
/**************************************************************************
* Function Name: void lcd_init(void).
* Function Desc: Init the lcd gepio.
* Input: None.
* Return: None.
**************************************************************************/
static void lcd_init(void)
{
u32 tmp;
tmp = inl( LED_DIRC_REGS );
tmp |= LCD_POWER_MASK;
outl( tmp, LED_DIRC_REGS );
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp &= ~LCD_POWER_MASK; // power on the black led of the LCD.
outl( tmp, LED_DATA_REGS ); // Output.
delay(30); // Delay 30us.
}
/**************************************************************************
* Function Name: void led_first_on(void)
* Function Desc: Sets the first led on.
* Input Para: None.
* Return: None.
**************************************************************************/
static void led_first_on(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp |= LED_MASK_FIRST; // Set the first led bit.
outl( tmp, LED_DATA_REGS ); // Output.
}
/**************************************************************************
* Function Name: void led_first_off(void)
* Function Desc: Sets the first led off.
* Input Para: None.
* Return: None.
**************************************************************************/
static void led_first_off(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp &= ~LED_MASK_FIRST; // Clear the first led.
outl( tmp, LED_DATA_REGS ); // Output.
}
/**************************************************************************
* Function Name: void led_second_on(void)
* Function Desc: Sets the second led on.
* Input Para: None.
* Return: None.
**************************************************************************/
static void led_second_on(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp |= LED_MASK_SECOND; // Set the second led bits.
outl( tmp, LED_DATA_REGS ); // Output.
}
/**************************************************************************
* Function Name: void led_second_off(void)
* Function Desc: Sets the second led off.
* Input Para: None.
* Return: None.
**************************************************************************/
static void led_second_off(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp &= ~LED_MASK_SECOND; // Clear the second led bit.
outl( tmp, LED_DATA_REGS ); // Output.
}
/**************************************************************************
* Function Name: void lcd_power_on(void)
* Function Desc: Sets the first led on.
* Input Para: None.
* Return: None.
**************************************************************************/
static void lcd_power_on(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp &= ~LCD_POWER_MASK; // Set the first led bit.
outl( tmp, LED_DATA_REGS ); // Output.
}
/**************************************************************************
* Function Name: void lcd_power_off(void)
* Function Desc: Sets the first led off.
* Input Para: None.
* Return: None.
**************************************************************************/
static void lcd_power_off(void)
{
u32 tmp;
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp |= LCD_POWER_MASK; // Clear the first led.
outl( tmp, LED_DATA_REGS ); // Output.
}
/**************************************************************************
* Function Name: static ssize_t ep9315_led_read(struct file *fl,
* char __user *buff, size_t len, loff_t *ppos)
* Function Desc: Read the led GPIO register.
* Input Para: fl - file pointer.
* buff - the buff you want puts the read data in.
* len - the length of the data you want to read.
* Return : 1 - read ok.
* -ENOBUFS - failed.
* Notice : You can only set len to 1.
**************************************************************************/
static ssize_t ep9315_led_read(struct file *fl, char __user *buff,
size_t len, loff_t *ppos)
{
u32 tmp;
*ppos = 0; // Avoid complie error.
if (len > 1) // Check the read lenght.
{
return -ENOBUFS; // Return error information.
}
tmp = inl( LED_DATA_REGS ); // Read the register.
tmp &= LED_MASK_ALL; // Masked with the led mask.
buff[0] = (tmp & 0xFF);
return 1; // return the data lenght.
}
/**************************************************************************
* Function Name: static ssize_t ep9315_led_write(struct file *fl,
* const char __user *buf, size_t len, loff_t *ppos)
* Function Desc: This function write a char to the led register.
* Input Para: fl - File pointer.
* buf - data wants to write.
* len - lenght wants to write.
* Return : data lenghts has been wrote.
* Notice : This file just write 1 byte to the led register.
**************************************************************************/
static ssize_t ep9315_led_write(struct file *fl, const char __user *buf,
size_t len, loff_t *ppos)
{
u32 tmp;
char ch;
*ppos = 0;
// Just avoid the complie warnning.
if (len > 1) // Check the write length.
{
return -ENOBUFS; // Return error msg.
}
tmp = inl( LED_DATA_REGS ); // Read register.
tmp &= ~LED_MASK_ALL; //
ch = buf[0];
ch &= LED_MASK_ALL;
tmp |= ch;
tmp = outl( tmp, LED_DATA_REGS );
return 1; //
}
/**************************************************************************
* Function Name: int ep9315_led_ioctl(struct inode *node, struct file *fl,
* unsigned int cmd, unsigned long arg)
* Function DESC:
* Input:
* Output: 0 - Ok.
* 1 - invide command.
**************************************************************************/
static int ep9315_led_ioctl(struct inode *node, struct file *fl,
unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case LED_CMD_LED1_ON:
led_first_on();
break;
case LED_CMD_LED1_OFF:
led_first_off();
break;
case LED_CMD_LED2_ON:
led_second_on();
break;
case LED_CMD_LED2_OFF:
led_second_off();
break;
case LCD_CMD_PWOER_ON:
lcd_power_on();
break;
case LCD_CMD_PWORE_OFF:
lcd_power_off();
break;
#ifdef USING_BEEP
case BEEP_CMD_ON:
set_beep_on();
break;
case BEEP_CMD_OFF:
set_beep_off();
break;
#endif
default:
return 1;
break;
}
return 0;
}
/**************************************************************************
* Function Name: int ep9315_led_open(struct inode *node, struct file *fl)
* Function DESC: Open file function. Two led will be set in this function.
* Input: fl - handle.
* Output: 0 - Open file successed.
**************************************************************************/
static int ep9315_led_open(struct inode *node, struct file *fl)
{
return 0;
}
/**************************************************************************
* Function Name: int ep9315_led_release(struct innode *node, struct file *fl)
* Function DESC: Close file function. Two led will be clear in this function.
* Input: fl - handle.
* Output: 0 - Close file failed.
***************************************************************************/
static int ep9315_led_release(struct inode *node, struct file *fl)
{
return 0;
}
/**************************************************************************
* Structure Name: ep9315_led_fops.
* Structure Type: file_operations.
* Structure Desc: EP9315 LED driver file ops.
***************************************************************************/
static struct file_operations ep9315_led_fops =
{
.owner = THIS_MODULE, // Almost all the time, it is simply initialized to THIS_MODULE.
.write = ep9315_led_write, // Sends data to the device.
.read = ep9315_led_read, // Used to retrieve data from the device.
.ioctl = ep9315_led_ioctl, // The ioctl system call offers a way to issue device-specific commands.
.open = ep9315_led_open, // The first operation performed on the device file,
.release = ep9315_led_release, // This operation is invoked when the file structure is being released.
};
/**************************************************************************
* Function Name: int __init ep9315_led_init(void).
* Function DESC: led driver init function.
* Input: None.
* Output: 0 - regiseted ok.
***************************************************************************/
static int __init ep9315_led_init(void)
{
int retv = 0;
led_init();
lcd_init();
beep_init();
printk(KERN_DEBUG LED_NAME ": EP9315 Led Driver interfaces.\n"); //
retv = register_chrdev(major,LED_NAME,&ep9315_led_fops); // Regiseter the driver.
if (retv < 0) //
{
printk(KERN_ERR LED_NAME ": unable to register character device.\n"); //
return retv; // Return.
}
if ( !major ) //
{
major = retv; //
printk(KERN_DEBUG LED_NAME ": got dynamic major %d.\n",major); //
}
printk("EP9315 Led Driver registered at major %d.\n", major); // print register information.
#ifdef KEYBOARD_IRQS
retv = request_irq( IRQ_NUM_KEYBOARD, ep93xx_keyboard_isr,
SA_INTERRUPT, "SDQ800 keyboard", &ep93xx_keyboard_isr );
if( retv )
{
printk( KERN_WARNING "SDQ800 Keyboard: failed to get keyboard IRQ:%d.\n",
IRQ_NUM_KEYBOARD );
return retv;
}
printk( "SDQ800 Keyboard get IRQ Number OK! IRQ Num:%d.\n", IRQ_NUM_KEYBOARD );
keyboard_init();
#endif
return 0;
}
/**************************************************************************
* Function Name: void __exit ep9315_led_cleanup(void).
* Function DESC:
* Input: None.
* Output: None.
**************************************************************************/
static void __exit ep9315_led_cleanup(void)
{
int retv;
if(major) //
{
#ifdef KEYBOARD_IRQS
free_irq(IRQ_NUM_KEYBOARD, &ep93xx_keyboard_isr);
keyboard_exit();
#endif
led_first_on();
led_second_on();
set_beep_off();
retv = unregister_chrdev(major, LED_NAME); // unregister the dirver.
if (retv < 0) // check if unregister successed.
{
printk(KERN_ERR LED_NAME " :unregister failed!\n"); // print error messages.
return; // 直return.
}
printk( LED_NAME ":unregister OK!\n");
}
}
module_init(ep9315_led_init);
module_exit(ep9315_led_cleanup);
在Qt中使用时,把设备文件打开,用ioctl 来控制就行。不清楚的看看linux C编程和Linux设备驱动相关的书籍。