其实一早就做完了,不过前一个版本有些显示不准确,现在在好些地方加上延时,终于搞定了!!!
源码奉上:
lcd12864.h
/*************************************
NAME:lcd12864.h
AUTHOR:vtk321
*************************************/
#ifndef lcd12864_H
#define lcd12864_H
#define lcd12864_MAJOR 244
#define DEVICE_NAME "lcd12864"
#define lcd12864_DATA_0 S3C2410_GPF1 //定义并行数据IO口
#define lcd12864_DATA_1 S3C2410_GPF3
#define lcd12864_DATA_2 S3C2410_GPF4
#define lcd12864_DATA_3 S3C2410_GPF5
#define lcd12864_DATA_4 S3C2410_GPF6
#define lcd12864_DATA_5 S3C2410_GPF7
#define lcd12864_DATA_6 S3C2410_GPG0
#define lcd12864_DATA_7 S3C2410_GPG3
#define lcd12864_DATA_CFG0_OUTP S3C2410_GPF1_OUTP
#define lcd12864_DATA_CFG1_OUTP S3C2410_GPF3_OUTP
#define lcd12864_DATA_CFG2_OUTP S3C2410_GPF4_OUTP
#define lcd12864_DATA_CFG3_OUTP S3C2410_GPF5_OUTP
#define lcd12864_DATA_CFG4_OUTP S3C2410_GPF6_OUTP
#define lcd12864_DATA_CFG5_OUTP S3C2410_GPF7_OUTP
#define lcd12864_DATA_CFG6_OUTP S3C2410_GPG0_OUTP
#define lcd12864_DATA_CFG7_OUTP S3C2410_GPG3_OUTP
#define lcd12864_DATA_CFG7_INP S3C2410_GPG3_INP
#define lcd12864_E S3C2410_GPG5 //使能控制
#define lcd12864_RW S3C2410_GPG6 //读写控制
#define lcd12864_RS S3C2410_GPG7 //RS=“H”表示DB7~DB0 为显示数据 RS=“L”表示DB7~DB0为控制指令
#define lcd12864_RST S3C2410_GPG9 //复位
#define lcd12864_E_CFG_OUTP S3C2410_GPG5_OUTP
#define lcd12864_RW_CFG_OUTP S3C2410_GPG6_OUTP
#define lcd12864_RS_CFG_OUTP S3C2410_GPG7_OUTP
#define lcd12864_RST_CFG_OUTP S3C2410_GPG9_OUTP
#endif //lcd12864_H
gt2440_12864.c
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/unistd.h>
#include <asm/irq.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/clk.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include "lcd12864.h"
#define lcd12864_E_cfg s3c2410_gpio_cfgpin(lcd12864_E, lcd12864_E_CFG_OUTP)
#define lcd12864_RW_cfg s3c2410_gpio_cfgpin(lcd12864_RW, lcd12864_RW_CFG_OUTP)
#define lcd12864_RS_cfg s3c2410_gpio_cfgpin(lcd12864_RS, lcd12864_RS_CFG_OUTP)
#define lcd12864_RST_cfg s3c2410_gpio_cfgpin(lcd12864_RST, lcd12864_RST_CFG_OUTP)
#define lcd12864_E_H s3c2410_gpio_setpin(lcd12864_E, 1)
#define lcd12864_E_L s3c2410_gpio_setpin(lcd12864_E, 0)
#define lcd12864_RW_H s3c2410_gpio_setpin(lcd12864_RW, 1)
#define lcd12864_RW_L s3c2410_gpio_setpin(lcd12864_RW, 0)
#define lcd12864_RS_H s3c2410_gpio_setpin(lcd12864_RS, 1)
#define lcd12864_RS_L s3c2410_gpio_setpin(lcd12864_RS, 0)
#define lcd12864_RST_H s3c2410_gpio_setpin(lcd12864_RST, 1)
#define lcd12864_RST_L s3c2410_gpio_setpin(lcd12864_RST, 0)
#define BUSY_SET s3c2410_gpio_cfgpin(lcd12864_DATA_7,lcd12864_DATA_CFG7_INP)
#define BUSY_RESET s3c2410_gpio_cfgpin(lcd12864_DATA_7,lcd12864_DATA_CFG7_OUTP)
#define BUSY_STU s3c2410_gpio_getpin(lcd12864_DATA_7)
#define BUSY_H s3c2410_gpio_setpin(lcd12864_DATA_7,1)
static unsigned long lcd12864_data_table[]={
lcd12864_DATA_0,
lcd12864_DATA_1,
lcd12864_DATA_2,
lcd12864_DATA_3,
lcd12864_DATA_4,
lcd12864_DATA_5,
lcd12864_DATA_6,
lcd12864_DATA_7,
};
static unsigned int lcd12864_data_cfg_table[]=
{
lcd12864_DATA_CFG0_OUTP,
lcd12864_DATA_CFG1_OUTP,
lcd12864_DATA_CFG2_OUTP,
lcd12864_DATA_CFG3_OUTP,
lcd12864_DATA_CFG4_OUTP,
lcd12864_DATA_CFG5_OUTP,
lcd12864_DATA_CFG6_OUTP,
lcd12864_DATA_CFG7_OUTP,
};
static void lcd12864_pin_init(void) //初始化引脚
{
int i;
for (i = 0;i < 8;i++)
{
s3c2410_gpio_cfgpin(lcd12864_data_table[i], lcd12864_data_cfg_table[i]);
s3c2410_gpio_setpin(lcd12864_data_table[i], 0);
}
lcd12864_E_cfg;
lcd12864_RW_cfg;
lcd12864_RS_cfg;
//lcd12864_RST_cfg;
lcd12864_E_L;
lcd12864_RW_L;
lcd12864_RS_L;
//lcd12864_RST_L;
}
/************* 复位 *************
static void reset(void)
{
s3c2410_gpio_setpin(lcd12864_RST, 0);
mdelay(21);
s3c2410_gpio_setpin(lcd12864_RST, 1);
mdelay(21);
}*/
/*************** 判LCD忙函数 ***************/
static void lcd_busy(void)
{
mdelay(20); //适当加入延时
lcd12864_E_L;
BUSY_H;
BUSY_SET;
lcd12864_RS_L;
lcd12864_RW_H;
while(1)
{
lcd12864_E_H;
mdelay(5);
if(!BUSY_STU)break;
lcd12864_E_L;
}
lcd12864_E_L;
BUSY_RESET;
}
/*************** 写入指令 *****************/
static void lcd12864_w_cmd(unsigned char cmd)
{
int i;
unsigned char ccmd = cmd;
lcd_busy();
lcd12864_RS_L;
lcd12864_RW_L;
lcd12864_E_L;
mdelay(10); //适当加入延时
for(i=0;i<8;i++)
{
if(ccmd & 0x01)
{
s3c2410_gpio_setpin(lcd12864_data_table[i],1);
}
else
{
s3c2410_gpio_setpin(lcd12864_data_table[i],0);
}
ccmd = ccmd>>1;
}
mdelay(10); //适当加入延时
lcd12864_E_H;
mdelay(20);
lcd12864_E_L;
}
/*************** 写入字符数据 *****************/
static void lcd12864_w_data(unsigned char data)
{
int ii;
unsigned char cdata = data;
lcd_busy();
lcd12864_RS_H;
lcd12864_RW_L;
lcd12864_E_L;
mdelay(10); //适当加入延时
for(ii=0;ii<8;ii++)
{
if(cdata & 0x01)
{
s3c2410_gpio_setpin(lcd12864_data_table[ii], 1);
}
else
{
s3c2410_gpio_setpin(lcd12864_data_table[ii], 0);
}
cdata = cdata>>1;
}
mdelay(10); //适当加入延时
lcd12864_E_H;
mdelay(20);
lcd12864_E_L;
}
/*************** 设定显示位置 ****************/
static void lcd12864_position(unsigned char x, unsigned char y)
{
unsigned char pos;
if(x == 0) x = 0x80;
if(x == 1) x = 0x90;
if(x == 2) x = 0x98;
if(x == 3) x = 0x88;
pos = x + y;
lcd12864_w_cmd(pos); //光标移至该地址,并从该地址起显示
}
/*************** lcd12864显示字符数据 ****************/
static void lcd12864_display(char* data)
{
int i = 0;
/*unsigned char dis_char[30];
dis_char = data1;
for(;*data1 != '\0';data1++,data2++)
*data2 = *data1;
p2 = '\0';
if(posx==4)
posx=0;
else
posx++;
lcd12864_position(0, 0);*/
lcd12864_position(0,0) //12864一行可显示16个16*16点阵的字
while(data[i]!= '\0')
{
if(i>=16)
lcd12864_position(1,0); //换行
else if(i>=32)
lcd12864_position(2,0); //换行
else if(i>=48)
lcd12864_position(3,0); //换行
else if(i==64)
{
lcd12864_w_cmd(0x01); //清除lcd12864显示内容
lcd12864_position(0,0); //换行
}
lcd12864_w_data(data[i]);
i++;
}
}
/************* 初始化lcd12864 **************/
static void lcd12864_init(void)
{
//reset();
mdelay(20);
lcd12864_w_cmd(0x30); //基本指令操作
mdelay(10);
lcd12864_w_cmd(0x0c); //显示开,关光标
mdelay(10);
lcd12864_w_cmd(0x06);
mdelay(10);
lcd12864_w_cmd(0x01); //清除lcd12864显示内容
mdelay(10);
}
static void lcd12864_init_display(void)
{
lcd12864_w_cmd(0x80);
lcd12864_display("0123456789abcdef");
lcd12864_w_cmd(0x90);
lcd12864_display("12864 cf 2440");
lcd12864_w_cmd(0x88);
lcd12864_display("AUTHOR:vtk321");
lcd12864_w_cmd(0x98);
lcd12864_display("/**************/");
}
static ssize_t lcd12864_write(struct file* filp, const char * buf, size_t size, loff_t *offset)
{
char* cbuf;
cbuf= kmalloc(size, GFP_KERNEL);
copy_from_user(cbuf, buf, size);
//lcd12864_position(0, 0);
lcd12864_display(cbuf);
kfree(cbuf);
return 0;
}
static int lcd12864_open(struct inode *inode, struct file *filp)
{
lcd12864_pin_init();
lcd12864_init();
lcd12864_w_cmd(0x01); //清除lcd12864显示内容
printk( "12864 opened\n");
return 0;
}
static int lcd12864_release(struct inode *inode, struct file *filp)
{
printk( "12864 closed\n");
return 0;
}
static struct file_operations dev_fops = {
owner: THIS_MODULE,
write: lcd12864_write,
open: lcd12864_open,
release: lcd12864_release,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
ret = misc_register(&misc);
printk(DEVICE_NAME" initialized\n");
lcd12864_pin_init();
lcd12864_init();
lcd12864_init_display();
return ret;
}
static void __exit dev_exit(void)
{
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("vtk321");
MODULE_DESCRIPTION("lcd12864 control for 2440");
Makefile
ARCH := arm
CROSS_COMPILE := arm-linux-
KVER := 2.6.30.4
KSRC := /linux-$(KVER)
obj-m:=gt2440_12864.o
all:
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd)
.PHONY:clean
clean:
rm -fr *.mod.c *.mod *.o .*.cmd *.ko *~
rm .tmp_versions -fr ; rm Module.symvers -fr
rm -fr Module.markers ; rm -fr modules.order
源码下载:
http://download.youkuaiyun.com/detail/kaisuvi/5202184