基于[三星6818]I2C驱动开发的0.96寸oled屏

找OLED屏的原厂找配置源码

下载地址

更改源码适配LINUX系统(源码是MCU使用的),直接附上改后的源码

dev驱动代码(当使用plaform注册驱动时一般要用到两个.c文件一个是设备代码一个是驱动代码)

#eeprom_dev.c
static struct i2c_board_info gec6818_eeprom_info = { 
	//第一个参数必须要与drv下I2C的name一致,参数2为i2c设备地址,一般读写位不要整体右移一位
        I2C_BOARD_INFO("gec6818_eeprom", 0x3c),
};

static struct i2c_client *gec6818_eeprom_client;

static int gec6818_eeprom_dev_init(void)
{
	struct i2c_adapter *i2c_adap;
	
	// 获取设备号为 2 的adpter ,也就是adapter->nr == 2(当使用sda2和sck2时)
	i2c_adap = i2c_get_adapter(2);
	
	
	//直接使用 i2c_new_device 创建 client 自动注册到i2c_bus_type 中去(drv代码probe中有用到)
	//client->name == "gec6818_eeprom" 
	//client->addr = 0x3c
	gec6818_eeprom_client = i2c_new_device(i2c_adap, &gec6818_eeprom_info);
	
	// 释放掉 adapter
	i2c_put_adapter(i2c_adap);
	
	return 0;
}

static void gec6818_eeprom_dev_exit(void)
{
	i2c_unregister_device(gec6818_eeprom_client);
}

module_init(gec6818_eeprom_dev_init);
module_exit(gec6818_eeprom_dev_exit);

drv驱动代码

#eeprom_drv.c
static struct i2c_client *this_client;

static int  gec6818_eeprom_open (struct inode * inode, struct file *file)
{


	printk("gec6818_eeprom_open \n");
	
	return 0;
}

static int  gec6818_eeprom_release (struct inode * inode, struct file *file)
{
	printk("gec6818_eeprom_release \n");
	
	return 0;
}


// buf[0] : addr
// buf[1] : data
//
static ssize_t gec6818_eeprom_write (struct file * file, const char __user * buf, size_t len, loff_t * off)
{
	int rt;
	char wbuf[2]={0};
	
	unsigned char addr, data;
	
	if(len > sizeof wbuf)
		return -EINVAL;

	
	
	rt = copy_from_user(wbuf, buf, 2);//把应用层传下的数据拷贝到内核
	
	if(rt != 0)
		return -EFAULT;

	//写入的地址
	addr = wbuf[0];
	
	//写入的数据
	data = wbuf[1];
	
        //printk("addr = %x, data = %x\n", addr, data);
	
	//传输1字节数据
	rt = i2c_smbus_write_byte_data(this_client, addr, data);

	if(rt < 0)
		return rt; 
	
	return 2;
}

// 传入: buf[0] : addr
// 输出: buf[0] : data
//
static ssize_t gec6818_eeprom_read (struct file *file, char __user *buf, size_t len, loff_t * offs)
{
	int rt=0;
	
	unsigned char addr, data;
	
	rt=copy_from_user(&addr, buf, 1);
	
	if(rt != 0)
		return -EFAULT;	
	
	//读取1字节数据
	rt = i2c_smbus_read_byte_data(this_client, addr);
	
	if(rt < 0)
		return rt;
	
	//若正确,获取读取到的字节
	data = rt & 0xFF;
	
	rt = copy_to_user(buf, &data, 1);
	
	if(rt != 0)
		return -EFAULT;
	
	return 1;
}

static const struct file_operations gec6818_eeprom_fops = {
 	.owner 		= THIS_MODULE,
	.write 		= gec6818_eeprom_write,
	.open 		= gec6818_eeprom_open,
	.release 	= gec6818_eeprom_release,
	.read 		= gec6818_eeprom_read,
};

static struct miscdevice gec6818_eeprom_miscdev = {
	.minor		= MISC_DYNAMIC_MINOR,	//MISC_DYNAMIC_MINOR,动态分配次设备号
	.name		= "gec6818_eeprom",		//设备名称,/dev/gec6818_eeprom	
	.fops		= &gec6818_eeprom_fops,	//文件操作集
};

static int gec6818_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int rt;
	
	//检查是否支持I2C功能
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
	{
		printk("i2c_check_functionality fail\n");
		return -ENODEV;
	}	
	
	//混杂设备的注册
	rt = misc_register(&gec6818_eeprom_miscdev);
	
	if (rt) 
	{
		printk("misc_register fail\n");
		return rt;
	}

	//保存client指针,里面有各种设备信息
	this_client = client;
	
	printk("gec6818_eeprom_probe ok\n");
	
	return 0;
}

static int __devexit gec6818_eeprom_remove(struct i2c_client *client)
{
	misc_deregister(&gec6818_eeprom_miscdev);

	return 0;
}

static const struct i2c_device_id gec6818_eeprom_id[] = {
	{ "gec6818_eeprom", 0 },	//设备类型,ID号
	{ }							//标识结束
};

//添加到内核i2c设备列表
MODULE_DEVICE_TABLE(i2c, gec6818_eeprom_id);

// 分配/设置i2c_driver
static struct i2c_driver gec6818_eeprom_driver = {
	.driver = 
	{
		.name = "gec6818_eeprom",						//用于匹配设备(dev下的name)
		.owner = THIS_MODULE,
	},
	.probe 		= gec6818_eeprom_probe,					//驱动初始化函数
	.remove 	= __devexit_p(gec6818_eeprom_remove),	//驱动删除
	.id_table = gec6818_eeprom_id,						//添加设备ID	
};

//入口函数
static int __init gec6818_eeprom_drv_init(void)
{
	printk("gec6818_eeprom_init\n");
	
	//添加I2C设备
	return i2c_add_driver(&gec6818_eeprom_driver);
}


//出口函数
static void __exit gec6818_eeprom_drv_exit(void)
{
	//删除I2C设备
	i2c_del_driver(&gec6818_eeprom_driver);
	
	printk("gec6818 eeprom exit\n");
}


module_init(gec6818_eeprom_drv_init);
module_exit(gec6818_eeprom_drv_exit)

main函数入口

#eeprom_test.c  //调用驱动程序代码
#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据
#define u8 unsigned char
int fd=-1;
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
        unsigned char buf[2]={0};
        buf[0]=0x00;
        buf[1]=IIC_Command;
        write(fd,buf,2);
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
        unsigned char buf[2]={0};
        buf[0]=0x40;
        buf[1]=IIC_Data;
        write(fd,buf,2);
}

void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
        if(cmd)
        {
                Write_IIC_Data(dat);
        }
        else
        {
                Write_IIC_Command(dat);
        }
}

void OLED_Set_Pos(unsigned char x, unsigned char y)
{ 		OLED_WR_Byte(0xb0+y,OLED_CMD);
        OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
        OLED_WR_Byte((x&0x0f),OLED_CMD);
}

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
        unsigned char c=0,i=0;
        c=chr-' ';
        if(x>128-1){x=0;y=y+2;}
        if(Char_Size ==16)
        {
                OLED_Set_Pos(x,y);
                for(i=0;i<8;i++)
                OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
                OLED_Set_Pos(x,y+1);
                for(i=0;i<8;i++)
                OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
        }
        else
        {
                OLED_Set_Pos(x,y);
                for(i=0;i<6;i++)
                OLED_WR_Byte(F6x8[c][i],OLED_DATA);
        }
}

void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
        unsigned char j=0;
        while (chr[j]!='\0')
        {
                OLED_ShowChar(x,y,chr[j],Char_Size);
                x+=8;
                if(x>120){x=0;y+=2;}
                        j++;
        }
}

void OLED_Clear(void)
{
        unsigned char i,n;
        for(i=0;i<8;i++)
        {
                OLED_WR_Byte (0xb0+i,OLED_CMD);
                OLED_WR_Byte (0x00,OLED_CMD);
                OLED_WR_Byte (0x10,OLED_CMD);
                for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
        }
}

int OLED_init(){
    //OLED 初始化
            OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
            OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
            OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
            OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
            OLED_WR_Byte(0x81,OLED_CMD); // contract control
            OLED_WR_Byte(0xFF,OLED_CMD);//--128
            OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
            OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
            OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
            OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
            OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
            OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
            OLED_WR_Byte(0x00,OLED_CMD);//

            OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
            OLED_WR_Byte(0x80,OLED_CMD);//

            OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
            OLED_WR_Byte(0x05,OLED_CMD);//

            OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
            OLED_WR_Byte(0xF1,OLED_CMD);//

            OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
            OLED_WR_Byte(0x12,OLED_CMD);//

            OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
            OLED_WR_Byte(0x30,OLED_CMD);//

            OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
            OLED_WR_Byte(0x14,OLED_CMD);//

            OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
}
int main(int argc, char **argv)
{
	
	int len;
	
	int i=0;
	
	char buf[8];
	
	//打开gec6818_eeprom设备
	fd = open("/dev/gec6818_eeprom",O_RDWR);
	
	if(fd < 0)
	{
		perror("open /dev/gec6818_eeprom:");
		
		return fd;
		
	}
        OLED_init();//oled初始化
        OLED_Clear();//oled清屏
        OLED_ShowString(24,0,(u8 *)"Teacher.Wen",16);//oled显示字符串
	while(1)
	{
	
	}
	
	close(fd);
	
	return 0;
}

效果图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I&You

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值