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 + -
显示快捷键?