荔枝派 V3S Linux 应用层 IIC 使用OLED

1.开始

  我想在荔枝派上驱动oled屏,但是在内核中写驱动对我来说肯定是非常麻烦的,所以我退而求其次,想在应用层中操作通用i2c接口来实现oled的驱动程序。

我买的OLED是中景园经典款,四针IIC接口oled。首先我参考了NanoPi的Matrix库,参考他的IIC应用层函数。我发现他多include了一个i2c-dev.h 并且这个函数的内容是比我/usr/inlucde/linux/i2c-dev.h中的内容多的,他多了以下几个函数

static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
                                     int size, union i2c_smbus_data *data)

static inline __s32 i2c_smbus_write_quick(int file, __u8 value)

static inline __s32 i2c_smbus_read_byte(int file)

static inline __s32 i2c_smbus_write_byte(int file, __u8 value)

static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)

static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
                                              __u8 value)

static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)

static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
                                              __u16 value)

static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)

/* Returns the number of read bytes */
static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
                                              __u8 *values)

static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
                                               __u8 length, __u8 *values)

/* Returns the number of read bytes */
static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
                                                  __u8 *values)

static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
                                               __u8 length, __u8 *values)

/* Returns the number of read bytes */
static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
                                                 __u8 length, __u8 *values)

  我在网上查询了这些函数,这个是一种smbus协议,是对应用层i2c的进一步封装。我可以使用这个快速的对i2c数据进行读写。

之后我就参考了别人的OLED代码,开始了移植。

2.问题出现

  我发现我设置好了从机地址之后,进行读写一直出现No Such Device Or Addres 的错误。经过一天的寻找,我终于发现了错误所在。

在网上的那个oled程序,都是将0x78作为从机地址。并且数据手册中也是这样写的,那么我理所当然将0x78作为从机地址。但是接下来我们看数据手册以及代码片段

ssd1306:

数据手册片段:

ssd1306的读写函数片段:

/*********************OLED写数据************************************/
void OLED_WrDat(unsigned char IIC_Data)
{
    IIC_Start();
   IIC_Send_Byte(0x78);            //D/C#=0; R/W#=0
    IIC_Wait_Ack();
   IIC_Send_Byte(0x40);            //write data
    IIC_Wait_Ack();
   IIC_Send_Byte(IIC_Data);
    IIC_Wait_Ack();
    IIC_Stop();
}

mpu6050:

数据手册

代码片段:

//IIC读一个字节
//reg:寄存器地址
//返回值:读到的数据
u8 MPU_Read_Byte(u8 reg)
{
    u8 res;
    IIC_Start();
    IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令
    IIC_Wait_Ack();        //等待应答
    IIC_Send_Byte(reg);    //写寄存器地址
    IIC_Wait_Ack();        //等待应答
    IIC_Start();
    IIC_Send_Byte((MPU_ADDR<<1)|1);//发送器件地址+读命令
    IIC_Wait_Ack();        //等待应答
    res=IIC_Read_Byte(0);//读取数据,发送nACK
    IIC_Stop();            //产生一个停止条件
    return res;
}

大家发现错误没有? 那就是对两个器件写地址的时候,oled的地址没有左移!那么问题就出现在这里,linux中设置好了从机地址后,他的发送时会自动根据读写来对地址进行左移后或上0、1的操作。

所以我这个0x78就是他的已经左移一位了的地址,那么我给linux中设置的从机地址应该是0x78右移一位得出的0x3C!现在我就可以正常读写了。

3.代码

  下面附上我修改的i2c代码驱动地址

原文地址:https://www.cnblogs.com/ZQQH/p/8807204.html

时间: 2024-10-11 23:04:51

荔枝派 V3S Linux 应用层 IIC 使用OLED的相关文章

荔枝派Licheepi nano裸机移植ZLG_GUI和3D旋转立方体

一:前言 以前申请到了荔枝派zero,在发了两个开箱贴后就放在一边吃灰了.后来又购买了荔枝派nano,刷了几个教程中的系统之后又放到一边吃灰了.虽然有屯板子的习惯,却没有使用板子的能力. 后来,经过断断续续的摸索和群里面的新手教程,终于搭建好了Licheepi Nano的交叉编译环境,自己GCC了一个hellowworld传输到了开发板并运行了起来.可是......对,于是又继续吃灰. 再后来,在大神 @晕哥 的 填坑网 (https://debugdump.com/index.html)看到了

Linux应用层直接操作GPIO

Linux应用层直接操作GPIO 在一个老手的指导下,应用层可以直接操作GPIO,具体指设置GPIO的输入输出以及输出电平高或者低.这个大大地提高了灵活性,官方的文档有GPIO Sysfs Interface for Userspace,GPIO Sysfs. 这里我记录一下使用过例子: # RK30_PIN0_PD4 # A0-7 -> 0-7 / B0-7 -> 8-15 / C0-7 -> 16-23 / D0-7 -> 24-31 echo 28 > /sys/cla

浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程【转】

本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程",主要涉及到浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程方面的内容,对于浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程感兴趣的同学可以参考一下. 简介: 本文试图完整地描述 Linux 系统中 C 语言编程中的时间问

基于Linux应用层的6LOWPAN物联网网关及实现方法

本发明涉及一种基于Linux应用层的6LOWPAN物联网网关及实现方法,所述物联网网关包括开发平台以及无线射频模块,其实现方法是:所述6LOWPAN物联网网关的以太网网口收到访问6LOWPAN无线传感器网络中节点的数据包,Linux应用层将以太网数据包格式转化成6LOWPAN物联网的格式,然后通过无线射频模块发送出去:同理,Linux应用层同时监听无线射频模块,收到6LOWPAN无线传感器网络中的数据包,所述Linux应用层将数据包转化成以太网数据包格式,再通过以太网网口把该数据包发送出去.本发

Linux应用层系统时间写入RTC时钟的方法

Linux内核版本:linux-3.0.35 开发板:i.MX6S MY-IMX6-EK200 系统:Ubuntu12 前言:之前写过一篇关于如何通过应用层程序读取系统时间的blog,今天再写一篇如何写入并保存RTC时钟的blog吧. 一.写入时间 1.预备知识: a.mktime 头文件:#include <time.h> 函数:time_t mktime(struct tm *timeptr) 函数说明:mktime()用来将timeptr所指的tm结构体数据换成从公元1970年1月1日0

荔枝派zero从焊接到跑起linux

步骤 焊flash芯片(如果大于16M,需要改烧录工具的源码) 焊引脚,为了串口看数据 焊接flash芯片,需要注意1号脚的位置,flash芯片在开发板背面,1号脚位置是靠近麦克风的那边 以下为编译相关步骤,参考连接,注意,下载的源码,选用spi flash模式 uboot git clone -b v3s-spi-experimental https://github.com/Lichee-Pi/u-boot.git make ARCH=arm CROSS_COMPILE=arm-linux-

linux 应用层使用gpio

使用这个代码之前 首先确认开发版的 “/sys/class/” 目录下有gpio这个文件夹,如果没有就需要配置linux内核 /** * @author emlsyx * @email [email protected] * @create date 2020-02-19 19:11:53 * @modify date 2020-02-19 19:11:53 * @desc [description] */ #include <stdlib.h> #include <stdio.h>

Linux ARM IIC I2C EEPROM 读写操作

检测有几组i2c总线 [email protected]:~# i2cdetect -l i2c-0 i2c        OMAP I2C adapter                 I2C adapter i2c-1 i2c        OMAP I2C adapter                 I2C adapter [email protected]:~# 检查每个总线上的设备在线状态:-y表示yes,0表示/dev/i2c-0 [email protected]:~# i2

Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析

关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸机开发 -- IIC总线 ,下面回顾下 IIC 基础概念 一.IIC 基础概念 IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备.IIC总线产生于在80年代,最初为音频和视频设备开发,如今主要在服务器管理中使用,其中包括单个组件状态的通信.例如管理员可对各个组件进行查询,以管理系统的配置或掌握组件的功能状态,如电源和系统风扇.可随时监