IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> i.mx6ull使用设备树驱动0.96寸I2C接口的oled -> 正文阅读

[嵌入式]i.mx6ull使用设备树驱动0.96寸I2C接口的oled

前言:我是linux驱动开发的初学者,也是第一次写博客,难免会有许多不周到的地方,我写这篇博客的初衷是为了记录自己学习的点滴,当然如果这篇文章能帮到你的话就更好了。

1.实验目的

因为我手上的板子是正点原子Linux mini开发板,所以没有集成Ap3216c这个I2C外设,所以我用i2c接口的oled替代,也是考验我对I2C驱动的掌握情况。

2.实验器材

硬件数量
正点原子Linux mini开发板1
0.96寸oled(i2c接口)1
杜邦线4

3.实验步骤

<1> 按照正点原子视频搭建好使用设备树的I2C驱动框架。
<2> 然后再将它这个例程里面的有关于Ap3216c的初始化及读写数据相关代码删掉。
<3> 参考下面这个大佬的代码把oled相关的代码放到上述搭建好的框架中。
链接: https://www.cnblogs.com/Recca/p/12760575.html.

4.实验代码

这个是oled.h

#ifndef _oled_H
#define _oled_H

/* oled 相关寄存器 */
#define OLED_CMD    0x40
#define OLED_DATA   0x00

#endif

oled.c里有关于oled的函数

/* oled functions */
/* cmd: 0是命令,1是数据 */
static int oled_send_byte(unsigned char data, unsigned char cmd)
{
	int ret = 0;
	if (cmd)
	{
		ret = Oled_Wirte_Reg(&I2C_Oled, 0x00, data);
		/* 使用内核文档推荐的SMBus API */
		// ret = i2c_smbus_write_byte_data(I2C_Oled->private_data, 0x00, data);
	}
	else
	{
		ret = Oled_Wirte_Reg(&I2C_Oled, 0x40, data);
		/* 使用内核文档推荐的SMBus API */
		// ret = i2c_smbus_write_byte_data(I2C_Oled->private_data, 0x00, data);
	}
	if (ret)
		return -EIO;
	return 0;
}

//屏幕旋转180度
static void OLED_DisplayTurn(u8 i)
{
	if(i==0)
		{
			oled_send_byte(0xC8,1);//正常显示
			oled_send_byte(0xA1,1);
		}
	if(i==1)
		{
			oled_send_byte(0xC0,1);//反转显示
			oled_send_byte(0xA0,1);
		}
}

//清屏函数
void OLED_Clear(void)
{
	u8 i,n;
	for(i=0;i<8;i++)
	{
	    oled_send_byte(0xb0 + i, 1);     //设置页地址(0~7)
        oled_send_byte(0x00, 1);         //设置显示位置—列低地址
        oled_send_byte(0x10, 1);         //设置显示位置—列高地址
	    for(n=0;n<128;n++)
		{
			oled_send_byte(0, 0);
		}
  }
}

//OLED设置坐标
static void oled_set_pos(unsigned int x, unsigned int y)
{
    unsigned char temp = 0;

    temp = 0xb0 + y;
    oled_send_byte(temp, 1);

    temp = ((x & 0xf0) >> 4) |0x10;
    oled_send_byte(temp, 1);

    temp = x & 0x0f;
    oled_send_byte(temp, 1); 
}


/*
  OLED显示一个字符
  x - 横坐标,范围在0-127
  y - 纵坐标,范围在0-7
*/
static void oled_show_char(unsigned char x, unsigned char y, unsigned char data)
{
    unsigned char c=0,i;    
    c = data - ' ';    //得到偏移后的值            

    if(x > 127)
    {    
        x = 0;
        y = y + 2;
    }
    
    if(16 == I2C_Oled.size)
    {
        oled_set_pos(x, y);    
        for(i=0; i<8; i++)
            oled_send_byte(F8X16[c*16 + i], 0);
        
        oled_set_pos(x, y+1);
        for(i=0; i<8; i++)
            oled_send_byte(F8X16[c*16 + i + 8], 0);
    }
    else 
    {    
        oled_set_pos(x, y);
        for(i=0; i<6; i++)
            oled_send_byte(F6x8[c][i], 0);
    }
}

static void oled_show_string(unsigned char x, unsigned char y, unsigned char *buf)
{
    unsigned char i = 0;
    while (buf[i] != '\0')
    {        
        oled_show_char(x, y, buf[i]);
        x += 8;
        if(x > 120)
        {    
            x = 0;
            y += 2;
        }
        i++;
    }
}


/* oled init */
void oled_init(void)
{
	oled_send_byte(0xAE, 1);    //display off
	oled_send_byte(0x00, 1);    //set low column address
	oled_send_byte(0x10, 1);    //set high column address
	oled_send_byte(0x40, 1);    //set start line address    
	oled_send_byte(0xB0, 1);    //set page address
	oled_send_byte(0x81, 1);    //contract control
	oled_send_byte(0xFF, 1);    //128   
	oled_send_byte(0xA1, 1);    //set segment remap 
	oled_send_byte(0xA6, 1);    //normal / reverse
	oled_send_byte(0xA8, 1);    //set multiplex ratio(1 to 64)
	oled_send_byte(0x3F, 1);    //1/32 duty
	oled_send_byte(0xC8, 1);    //Com scan direction
	oled_send_byte(0xD3, 1);    //set display offset
	oled_send_byte(0x00, 1);

	oled_send_byte(0xD5, 1);    //set osc division
	oled_send_byte(0x80, 1);

	oled_send_byte(0xD8, 1);    //set area color mode off
	oled_send_byte(0x05, 1);

	oled_send_byte(0xD9, 1);    //Set Pre-Charge Period
	oled_send_byte(0xF1, 1);

	oled_send_byte(0xDA, 1);    //set com pin configuartion
	oled_send_byte(0x12, 1);

	oled_send_byte(0xDB, 1);    //set Vcomh
	oled_send_byte(0x30, 1);

	oled_send_byte(0x8D, 1);    //set charge pump enable
	oled_send_byte(0x14, 1);
	oled_send_byte(0xAF, 1);    //turn on oled panel
}

与应用层(open,write等)交互函数

static int i2c_open(struct inode *inode, struct file *filp)
{
	filp->private_data = &I2C_Oled; /* 设置私有数据 */
	/* oled 初始化 */
	oled_init();
	OLED_Clear();
	return 0;
}

static ssize_t i2c_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
    
	int ret = 0;
	ret = copy_from_user(I2C_Oled.buffer, buf, cnt);
	if (ret < 0) {
		printk("copy from user failed!\r\n");
		return -1;
	}
	OLED_DisplayTurn(1); // 反转显示
	oled_show_string(8, 8, I2C_Oled.buffer);
	printk("driver: i2c_write ok!\n");
	printk("the buffer is %s", I2C_Oled.buffer);
    return 0;
}

static int i2c_release(struct inode *inode, struct file *filp)
{
	OLED_Clear();
    return 0;
}

应用程序代码

int main(int argc,char *argv[])
{
    int fd,ret = 0;
    unsigned int i = 0;
    unsigned char buf[] = "www.oss.com";
    char *filename;
    filename = argv[1];
    fd = open(filename,O_RDWR);
    if(fd < 0)
    {
        printf("file %s open error\r\n",filename);
        return -1;
    }
    ret = write(fd, buf, sizeof(buf));
        if (ret < 0)
        {
            printf("wirte data to kernel error\r\n");
            return -1;
        }
    while (1);    
    close(fd);
    return 0;
}

实验结果

在这里插入图片描述

总结 :以上代码比较粗糙,望读者见谅!也难免存在些bug,如有发现烦请告知。最后,多调多试,总会成功的,求知路上,逐渐迷茫着,慢慢地这样钢铁就练成了!

本文章为原创文章,如若转载请声明,谢谢!文中引用和参考了那位大佬的博客,如有侵犯,烦请告知,必删!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:42:22  更:2021-09-04 17:43:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:00:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码