lcd_driver.c

来自「linux 12232液晶显示驱动,可根据具体电路的IO口做适当修改.」· C语言 代码 · 共 285 行

C
285
字号
/*****************************************************************************//* *	lcd_driver.c -- driver for a C12232-8 LCD displays * *	(C) Copyright 2000-2008, guo (jqguowhm@sohu.com) *	(C) Copyright 2000-2008, g Inc. (www.g.com)  *//*****************************************************************************/#include <linux/config.h>#include <linux/version.h>#include <linux/types.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/mm.h>#include <linux/delay.h>#include <asm/param.h>#include <asm/uaccess.h>#include "44b.h"/*****************************************************************************//* *	Hardware specifics for LCD on the board. *	This is a 15 character by 2 line device. *//* LCD display specifics */#define	G_LCD_LINENUM	2#define	G_LCD_LINELENGTH	15#define LCD_DRIVER	"g LCD Driver v 0.1"/* *	Define driver major number. */#define	G_LCD_MAJOR	120/*****************************************************************************//* *	Define normal text LCD control commands. */#define	G_LCD_CLEAR		0x01		/* Clear all of LCD display */#define	G_LCD_RETURN	0x02		/* Cursor to start of line */#define	G_LCD_MODE		0x04		/* Mode command */#define	G_LCD_MODE_INCR	0x02		/* Increment cursor on data */#define	G_LCD_MODE_DECR	0x00		/* Decrement cursor on data */#define	G_LCD_MODE_SHIFT	0x01		/* Display shift when full */#define	G_LCD_MODE_NOSHIFT	0x00		/* No display shift */#define	G_LCD_DISP		0x08		/* Display command */#define	G_LCD_DISP_ON	0x04		/* Turn display on */#define	G_LCD_DISP_OFF	0x00		/* Turn display off */#define	G_LCD_DISP_CUR_ON	0x02		/* Turn cursor on */#define	G_LCD_DISP_CUR_OFF	0x00		/* Turn cursor off */#define	G_LCD_DISP_BLNK_ON	0x01		/* Blinking cursor on */#define	G_LCD_DISP_BLNK_OFF	0x00		/* Blinking cursor off */#define	G_LCD_SHIFT		0x10		/* SHift command */#define	G_LCD_SHIFT_CUR	0x00		/* Cursor shift */#define	G_LCD_SHIFT_DISP	0x08		/* Display shift */#define	G_LCD_SHIFT_RIGHT	0x04		/* Right shift */#define	G_LCD_SHIFT_LEFT	0x00		/* Left shift */#define	G_LCD_FUNC		0x20		/* Function command */#define	G_LCD_FUNC_4BIT	0x00		/* 4 bit data bus */#define	G_LCD_FUNC_8BIT	0x10		/* 8 bit data bus */#define	G_LCD_FUNC_1LINE	0x00		/* 1 line display */#define	G_LCD_FUNC_2LINE	0x08		/* 2 line display */#define	G_LCD_FUNC_FONT	0x00		/* Standard font *//*****************************************************************************/static void g_lcd_writechar(unsigned char c, unsigned char rwrs){	unsigned char i;		rPDATC |= 0x04;//PC2 high, chip selected 	/*synchronize*/	for(i=0; i<5; i++){		rPDATC |= (0x2);//PC1 high, SID sync bit 1		rPDATC &= ~(0x1);//PC0 low, 		udelay(1);		rPDATC |= (0x1);//PC0 high, 		udelay(1);			}		//rPDATC &= ~(0x1<<1)//PC1  SID RW bit	rPDATC =(rPDATC&(~(0x1<<1)))|(((rwrs>>1)&(0x1))<<1);//PC1 one bit	rPDATC &= ~(0x1);//PC0 low, 	udelay(1);	rPDATC |= (0x1);//PC0 high, 	udelay(1);		//rPDATC &= ~(0x1<<1)//PC1  SID RS bit	rPDATC =(rPDATC&(~(0x1<<1)))|(((rwrs)&(0x1))<<1);//PC1 one bit	rPDATC &= ~(0x1);//PC0 low, 	udelay(1);	rPDATC |= (0x1);//PC0 high, 	udelay(1);	rPDATC &= ~(0x1<<1);//PC1 low, SID 0	rPDATC &= ~(0x1);//PC0 low, 	udelay(1);	rPDATC |= (0x1);//PC0 high, 	udelay(1);			//four higher bits 		for(i=7; i>3; i--){		rPDATC =(rPDATC&(~(0x1<<1)))|(((c>>i)&(0x1))<<1);//PC1 one bit		rPDATC &= ~(0x1);//PC0 low, 		udelay(1);		rPDATC |= (0x1);//PC0 high, 		udelay(1);		}	for(i=0; i<4; i++){		rPDATC &= ~(0x1<<1);//PC1 low, SID RW=0		rPDATC &= ~(0x1);//PC0 low, 		udelay(1);		rPDATC |= (0x1);//PC0 high, 		udelay(1);			}		//four lower bits	for(i=3; i>=0; i--){		rPDATC =(rPDATC&(~(0x1<<1)))|(((c>>i)&(0x1))<<1);//PC1 one bit		rPDATC &= ~(0x1);//PC0 low, 		udelay(1);		rPDATC |= (0x1);//PC0 high, 		udelay(1);		}	for(i=0; i<4; i++){		rPDATC &= ~(0x1<<1);//PC1 low, SID RW=0		rPDATC &= ~(0x1);//PC0 low, 		udelay(1);		rPDATC |= (0x1);//PC0 high, 		udelay(1);			}		udelay(72000);}/* *	LCD initial hardware setup. */static void g_lcd_hwsetup(){	/*	 *	Initialize the LCD controller.	 *	Some data sheets recommend doing the init write twice...	 */	g_lcd_writechar(G_LCD_FUNC | G_LCD_FUNC_8BIT ,0x00);	g_lcd_writechar(G_LCD_FUNC | G_LCD_FUNC_8BIT ,0x00);	g_lcd_writechar(G_LCD_DISP | G_LCD_DISP_ON,0x00);	g_lcd_writechar(G_LCD_MODE | G_LCD_MODE_INCR,0x00);	g_lcd_writechar(G_LCD_CLEAR,0x00);	}/*****************************************************************************/static int g_lcd_open(struct inode *inode, struct file *filp){	return(0);}/*****************************************************************************/static int g_lcd_release(struct inode *inode, struct file *filp){	return 0;}/*****************************************************************************/static void g_lcd_resetposn(void){	g_lcd_writechar(0x80,0x00);}/*****************************************************************************/static void g_lcd_clear(void){	g_lcd_writechar(G_LCD_CLEAR,0x00);}/*****************************************************************************/static ssize_t g_lcd_write(struct file *filp, const char *buf, size_t count, loff_t *ppos){	char	*p, c;	int	num;	p = (char *) buf;		if(*p == 0){		g_lcd_clear();			return 0;	}		for (num = 0; num < count; num++) {		get_user(c, p++);		if(c == 0x00) break;		g_lcd_writechar(c, 0x01);		}	return(num);}/*****************************************************************************/static int g_lcd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){	int	rc = 0;	switch (cmd) {	case 1: /* Directly address X/Y cursor position */		/*		 * This ioctl is essentailly a duplication of the		 * 0x1f escape code code in the write routine.		 * This version allows a wider range of values to be set		 */		g_lcd_resetposn();		break;			default:		rc = -EINVAL;		break;	}	return(rc);}/*****************************************************************************//* *	Exported file operations structure for driver... */struct file_operations	g_lcd_fops = {	write:		g_lcd_write,	/* write */	ioctl:		g_lcd_ioctl,	/* ioctl */	open:		g_lcd_open,		/* open */	release:	g_lcd_release,	/* release */};/*****************************************************************************/static int __init g_lcd_init(void){	int	rc;	/* Register g_lcd as character device */	if ((rc = register_chrdev(G_LCD_MAJOR, "lcd", &g_lcd_fops)) < 0) {		printk(KERN_WARNING "G_LCD: can't get major %d\n",			G_LCD_MAJOR);		return (-EBUSY);	}	printk("G_LCD: Copyright (C) 2000-2008, Guo "		"(jqguowhm@sohu.com)\n");	/* Hardware specific initialization */	g_lcd_hwsetup();	return 0;}module_init(g_lcd_init);/*****************************************************************************/

⌨️ 快捷键说明

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