2440,嵌入式linux平台12864驱动(调试完成)

本文介绍了一个12864 LCD显示屏的驱动程序实现细节,包括GPIO配置、初始化过程、显示控制等关键部分,并提供了完整的源代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

其实一早就做完了,不过前一个版本有些显示不准确,现在在好些地方加上延时,终于搞定了!!!


源码奉上:

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值