📄 lcddrv1.c
字号:
#ifdef MODULE#include <linux/module.h>#include <linux/version.h>#else#define MOD_INC_USE_COUNT#define MOD_DEC_USE_COUNT#endif//#define __KERNEL__#include <linux/kernel.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/ioport.h>#include <linux/fcntl.h>#include <asm/uaccess.h>#include <asm/io.h>#define IOPMOD (*(volatile unsigned *)0x3ff5000)#define IOPDATA (*(volatile unsigned *)0x3ff5008)#define EXTACON0 (*(volatile unsigned *)0x3ff3008)#define EXTACON1 (*(volatile unsigned *)0x3ff300c)#define EXTDBWTH (*(volatile unsigned *)0x3ff3010)#define LCD_COM (*(volatile unsigned int *)0x3600000)//lcd命令寄存器处于arm io0区#define LCD_DATA (*(volatile unsigned int *)0x3600000) //lcd数据寄存器 //#define HPI_addr (*(volatile unsigned *)0x3604000) //hpi地址处于arm io1区void Delay(unsigned int x);void delay_10us(void);void delay_40us(void);void delay_100us(void);void delay_10ms(void);void delay_40ms(void);void initial_lcd(void); //初始化液晶void write_lcd_com(unsigned int lcd_command); //写命令void write_lcd_data_byte(unsigned int lcd_data); //写数据字节void write_lcd_data_word(unsigned int lcd_data); //写数据字void lcd_test(void);#define LCD_WRITE_COM 0x4800static int lcd_open(struct inode *,struct file *);static int lcd_release(struct inode *,struct file *);static int lcd_write(struct file *,char *,int,loff_t *);static int lcd_ioctl(struct inode *lcd_node,struct file *lcd_file,unsigned int cmd,unsigned int arg);static int major=240;char lcd_name[]="lcddrv";unsigned int lcd_com_flag=0;static struct file_operations lcd_fops={ open: (void(*))lcd_open, write:(void(*))lcd_write, ioctl:(void(*))lcd_ioctl, release:(void(*))lcd_release,};static int __init lcd_init_module(void){ int retv; retv=register_chrdev(major,lcd_name,&lcd_fops); if(retv<0) { printk("<1>register fail!\n"); return retv; } if(major==0) major=retv; printk("<1>lcddrv register ok!\n"); return 0;}static void __exit lcd_cleanup_module(void){ int retv; retv=unregister_chrdev(major,lcd_name); if(retv<0) { printk("<1>ungersiter fail!\n"); return; } printk("<1>lcddrv bye!\n");}module_init(lcd_init_module);module_exit(lcd_cleanup_module);static int lcd_open(struct inode *lcd_node,struct file *lcd_file){ IOPMOD=0xffffffff; EXTDBWTH=0x0ff03002;//io区全为32位宽度,dram0区32位宽度,rom0区1位宽度//0x05503002;//0x0503003 EXTACON0= 0xfffffff;//时序最长 EXTACON1= 0xfffffff;//时序最长 initial_lcd();//初始化液晶 printk("lcd initialed ok!\n"); return 0;}static int lcd_release(struct inode *lcd_node ,struct file *lcd_file){ printk("file closed\n"); return 0;}static int lcd_write(struct file *lcd_file,char *buf,int len ,loff_t *loff){ unsigned int lcddata_fromuser; unsigned int temp; if(copy_from_user((char *)&lcddata_fromuser,buf,len)) return -EFAULT; // temp=lcddata_fromuser; if(lcd_com_flag==1) //写命令 { write_lcd_com(lcddata_fromuser); printk("lcdcom=%x\n",lcddata_fromuser); lcd_com_flag=0; } else { write_lcd_com(lcddata_fromuser>>16); write_lcd_data_word(lcddata_fromuser&0x0000ffff); printk("lcddata=%x\n",lcddata_fromuser); } // write_lcd_com(0x0087); // write_lcd_data_word(0xbdda); // write_lcd_com(0x85);//(0x00850000); // write_lcd_data_word(0xdfc8);//(0xdfc80000);//呷 /* write_lcd_com(0x0080);//(0x00800000); //写命令 光标地址 write_lcd_data_word(0xdfc8);//(0xdfc80000);//呷 printk("<1>write com ok!\n"); write_lcd_data_word(0xb6f0);//(0xb5a30000); //写显示的字的编码 担 write_lcd_com(0x0081);//(0x00810000); write_lcd_data_word(0xb6f0);//(0xb6f00000);//告 write_lcd_com(0x0082);//(0x00820000); write_lcd_data_word(0xb7d0);//(0xb7d00000);//娶 write_lcd_com(0x0083);//(0x00830000); write_lcd_data_word(0xc9b3);//(0xc9b30000);//沙 write_lcd_com(0x0084);//(0x00840000); write_lcd_data_word(0xbdda);//(0xbdda2000);//节 write_lcd_com(0x85);//(0x00850000); write_lcd_data_word(0xdfc8);//(0xdfc80000);//呷 */ return len;}static int lcd_ioctl(struct inode *lcd_node,struct file *lcd_file,unsigned int cmd,unsigned int arg){ int retv; switch(cmd) { case LCD_WRITE_COM: lcd_com_flag=1; break; default: break; } return 0;}////液晶相关函数void initial_lcd() //初始化液晶 { delay_40ms(); write_lcd_com(0x0030);//(0x00300000); delay_100us();// Delay(1); write_lcd_com(0x0030);//(0x00300000); delay_40us();//Delay(1); write_lcd_com(0x000e);//(0x000e0000);//开显示、光标开,不闪烁 delay_100us();//Delay(1); write_lcd_com(0x0001);//(0x00010000); //清屏 delay_10ms();// Delay(1); write_lcd_com(0x0006);//(0x00060000); delay_40us(); // Delay(1); } void write_lcd_com(unsigned int lcd_command)//写命令 { IOPDATA=IOPDATA&0xfffef0ff;//0x00000000;// 命令寄存器 rs为0,rw为0写,oe=0lvc4245有效 LCD_COM=lcd_command<<16;//lcd_command; delay_10us();//delay_40us();//Delay(1); IOPDATA=(IOPDATA&0xfffef0ff)|0x00000c00;// rw为1读,lvc4245无效 }void write_lcd_data_byte(unsigned int lcd_data) //写字节 { IOPDATA=(IOPDATA&0xfffef0ff)|0x00010000;//数据寄存器 ,rs为1,rw为0写,lvc4245有效 LCD_DATA=lcd_data<<16;//lcd_data; delay_10us(); //delay_40us(); //Delay(1); IOPDATA=(IOPDATA&0xfffef0ff)|0x00000c00;//0x00000c00;// rw为1读,lvc4245无效 }void write_lcd_data_word(unsigned int lcd_data)//写字 { IOPDATA=(IOPDATA&0xfffef0ff)|0x00010000;// 数据寄存器,rs为1,rw为0写,lvc4245有效 LCD_DATA=lcd_data<<8;//lcd_data>>8; delay_10us();//delay_40us(); // Delay(1); LCD_DATA=lcd_data<<16;//lcd_data&0x00ff0000; delay_10us();//delay_40us(); //Delay(1); IOPDATA=IOPDATA=(IOPDATA&0xfffef0ff)|0x00000c00;//0x00000c00;// rw为1读,lvc4245无效 return; }void Delay(unsigned int x){ unsigned int i,j,k; for(i=0;i<=x;i++) for(j=0;j<0xff;j++) for(k=0;k<0xff;k++);}void delay_10us() { int i; for(i=0;i<300/*500*/;i++); //40us=2000 circles }void delay_40us() { int i; for(i=0;i<600/*2000*/;i++); //40us=2000 circles }void delay_100us() { int i; for(i=0;i<1800/*5400*/;i++); //100us=5000 circles }void delay_10ms() { int i; for(i=0;i<166800/*500500*/;i++); //10ms=500000 circles } void delay_40ms() { int i; for(i=0;i<6666800/*20000500*/;i++); //40ms=20000000 circles }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -