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

📄 lcd_d.c

📁 lcd驱动报告,看完能有所帮助
💻 C
字号:
#include<linux/kernel.h>
#include<linux/module.h>
#include<asm/uaccess.h>
#include<linux/init.h>
#include<asm/8xx_immap.h>
#include<linux/delay.h>

#include<linux/ioport.h>
#include<asm/io.h> 
#include<linux/fs.h>#ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))#endif

volatile immap_t *immap;

//LCD相关寄存器定义
#define LCD_BASE        0x80000000
#define LCD_CONTROL    0x80000017
#define LCD_DATA_BASE  0x8000001d
//LED相关寄存器定义
#define LED_CONTROL    0x8000001b
#define LED_OFF         0xff
#define LED_ON          0x00
//LCD操作定义
#define LCD_ENH_INS    0x02
#define LCD_ENL_INS    0x00
#define LCD_ENH_DATA   0x03
#define LCD_ENL_DATA   0x01       
#define LCD_ON         0x70
#define LCD_OFF        0x10
#define LCD_FUNCSET    0x3c
#define LCD_INPUT_MODESET    0x60
#define LCD_CLEAR      0x80 
#define LCD_MODESET    0x1c
#define LCD_ROW2       0x03
#define MAJOR_NUM      200
#define GOODOPEN       1
// 设备名,将出现在 /proc/dev 
#define DEVNAME  "lcd_driver"// 设备正被打开吗? 用于防止对同一设备的同时访问 static int Device_Open = 0;

static int device_open(struct inode *,struct file*);
static int device_release(struct inode *,struct file*);
static ssize_t device_write(struct file *,const char *,size_t ,loff_t *);
struct file_operations lcd_ops=
{
 write:   device_write,
 open:    device_open,
 release: device_release,
};//仅定义相关的的结构,其它操作用不到//格式转换
static unsigned char
char_change (unsigned char org_char)
{                                                                                                         unsigned char swap_char = '\0';
  swap_char |= ((org_char & 0x80) >> 7) | ((org_char & 0x40) >> 5)
    | ((org_char & 0x20) >> 3) | ((org_char & 0x10) >> 1)
    | ((org_char & 0x08) << 1) | ((org_char & 0x04) << 3)
    | ((org_char & 0x02) << 5) | ((org_char & 0x01) << 7);
  return swap_char;
}
//写数据时序
static void lcd_data_write(char data)
{
 writeb(char_change(data),LCD_DATA_BASE);
 udelay(15);
 writeb(LCD_ENL_DATA,LCD_CONTROL);//set EN=1,RS=1
 udelay(1);
 writeb(LCD_ENH_DATA,LCD_CONTROL);//set EN=0,RS=1
 udelay(1);
 writeb(LCD_ENL_DATA,LCD_CONTROL);//set EN=1,RS=1
 udelay(40);
}//写命令时序
static void lcd_cmd_write(char cmd)
{
 writeb(cmd,LCD_DATA_BASE);
 udelay(15);
 writeb(LCD_ENL_INS,LCD_CONTROL);//set EN =1,RS=0
 udelay(1);
 writeb(LCD_ENH_INS,LCD_CONTROL);//set EN=0 ,RS=0
 udelay(1);
 writeb(LCD_ENL_INS,LCD_CONTROL);//set EN=1,RS=0
 udelay(40);
}//LCD 初始化操作
static int __init lcd_init(void)
{  int err;
  immap=(immap_t *)(mfspr(IMMR)&0xFFFF0000);//取得IMMR 内容
  immap->im_memctl.memc_br7=0x80000401;//配置CS7相关寄存器
  immap->im_memctl.memc_or7=0xffff0FF4;

  err=register_chrdev(MAJOR_NUM,DEVNAME,&lcd_ops);//注册设备
  if(err!=0)
    printk("<1> unable to get major 200 for LCD device\n");
 if(check_region(LCD_BASE,0x1ff))//检测IO端口
   {
     printk("IO  is used already\n");return -1;
     
   }else
  {request_region(LCD_BASE,0x1ff,DEVNAME);//申请占用此端口//初始化 udelay(10);
 lcd_cmd_write(LCD_MODESET);/* set 8-bit mode*/
 udelay(4);
 lcd_cmd_write(LCD_MODESET); /*set 8-bit mode */
 udelay(1);
 lcd_cmd_write(LCD_MODESET);/* set 8-bit mode*/
 lcd_cmd_write(LCD_OFF);
 lcd_cmd_write(LCD_ON);
 lcd_cmd_write(LCD_INPUT_MODESET);
 lcd_cmd_write(LCD_CLEAR);return 1;}

} 
 


static int device_open(struct inode *rinode,struct file *rfile)
{/* 我们不想同时和两个进程通话 */if (Device_Open)return -1;Device_Open++;
 MOD_INC_USE_COUNT;//rmmod 操作时用
 lcd_cmd_write(LCD_CLEAR);
 lcd_cmd_write(LCD_INPUT_MODESET);
 return 0;
}
static int device_release(struct inode *rinode,struct file *rfile)
{   
  MOD_DEC_USE_COUNT;
 //归还端口
  release_region(LCD_BASE,0x1ff);
  return 0;
}

static ssize_t device_write(struct file *rfile,const char *buffer,size_t length,loff_t *offset)
{ int i;
  
  unsigned  char c;
 
 
 // lcd_init();
 //写时序
  lcd_cmd_write(LCD_FUNCSET);
  lcd_cmd_write(LCD_OFF);
  lcd_cmd_write(LCD_ON);
  lcd_cmd_write(LCD_INPUT_MODESET);
  lcd_cmd_write(LCD_CLEAR);
  
 for(i=0;i<length;i++)
 {
  if(i==8)    lcd_cmd_write(LCD_ROW2);
   get_user(c,buffer+i);
  lcd_data_write(c);
 }
  return 0;
}


static void __exit  lcd_cleanup(void)
{
  int err;
  lcd_cmd_write(LCD_CLEAR);
  err=unregister_chrdev(MAJOR_NUM,DEVNAME);
 if(err!=0)
   printk("<1> Uninstall the %s failed!",DEVNAME);
  release_region(LCD_BASE,0x1ff);
 
}module_init(lcd_init);module_exit(lcd_cleanup);

⌨️ 快捷键说明

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