I2C

SMBus 是 I2C 协议的一个子集,具体见完全开发手册
参考资料:
⚫ Linux 内核文档: Documentation\i2c\smbus-protocol.rst
⚫ SMBus 协议:
http://www.smbus.org/specs/
⚫ SMBus_3_0_20141220.pdf
⚫ I2CTools:
https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/

硬件结构


硬件结构

只需要两根线
SCL
SDA
主设备和从设备都能修改SDA这条线上的电平【也都能改SCL的,原理一样的】
两个设备控制一条线的电压,不能直接输出电压,会短路。
所以两个设备控制的是mos管,只要设备置1 使mos管接地,就能拉低电压。
加一个上拉电阻,让电平维持在高电平。
所以,只有俩人都撒手,才是高电平,只要有一个人扯着,就是低电平。

image.png

IIC的信号动作定义
两个设备都能控制线上的电平,这样的线居然只需要两根就能多设备通信了。
那两根线,各自有【低电平】【高电平】【向低电平跳变】【向高电平跳变】这几种情况。可以组合使用。

通信需要传数据,而且需要信号来做格式区分。串口是用起始位,数据,[可有可无的校验位],停止位。 所以别的通信的基础操作也是这三个吧。【IIC如果非要校验,是通过 多发一帧数据 来实现的,真奢侈啊】


image.png

SCL在高电平的时候 SDA的数据才是有效的。


image.png

SCL在低电平的时候,SDA要变换电平。而且从设备如果没准备好数据,就会主动拉低SCL,让主设备知道要等着。
SCL在跳变的时候不管事,没啥作用,就是要跳变。。因为只有当两边都撒手,电压才能为1的,所以只有当SCL为1的时候才能确认SDA的数据。


image.png

无论读写都需要主设备发起start信号并指定目标设备地址,而且设备都要先回应,然后一方读/写之后另一方要回应。
串口是一对一的,不像总线有那么多设备,所以串口没收到很快就能发现,不需要靠发送回应数据进行确认。
但是,在IIC通信中,起始信号是必须的,结束信号和应答信号都不是必需的。 也就是说,虽然没有应答信号就会确认不了,但你不在乎的话就没关系。

大部分时间是主设备在控制SCL进行数据传输,
从设备要应答的原理就是:在需要应答的时候,主设备撒手了SDA和SCL,如果从设备没在 那也SCL和SDA都被撒手了,那SCL为1读到了为1的SDA,就是凉凉;如果从设备在线,那就会主动把SDA拉低,所以应答信号是低电平。


image.png

应用到数据读写,需要规定一些发送内容的信息格式
上一小节提到的读写格式只是最基础的读写动作。而实际上在进行读写的时候还必须要指定数据的寄存器地址。所以地址本身也是数据,需要被发送过去。

image.png

要读从设备里的数据,还得指定从设备里的数据寄存器的地址。所以要先发一个写指令,向那个设备发去它的寄存器的地址。然后再开始新的起始信号,读取从设备传回的数据。
I2C系统的重要结构体


举例:设备地址为 0x50 的 EEPROM,要读取它里面存储地址为 0x10 的一个字节,
应该构造几个 i2c_msg?要构造 2 个 i2c_msg
c) 第一个 i2c_msg 表示写操作,把要访问的存储地址 0x10 发给设备
d) 第二个 i2c_msg 表示读操作
代码如下

image.png

这个例子要发送两次开始指令,所以需要定义两个msg变量来发送。
第0个的buf是主设备要求的目标寄存器地址,是写命令
第1个的buf是一个存储用的变量,保存接收到的data

在终端查看IIC设备情况


列出所有的IIC总线。上图显示有0 1 2 三个IIC总线


image.png

在第0个IIC总线上 挂着3个设备,字母UU表示在地址0x1a 0x22 的设备已经有驱动程序了 直接显示地址0x1e的那个设备是没有对应驱动程序的。【总之,设备地址是到手了】
然后按照模块的数据手册去操作寄存器就行


image.png

下图里,Usage后面是信息格式,[ ]里的是可选设置

【注意:下面提到的两个指令是SMBus协议里的指令】【SMBus对于IIC就好像CANopen对于CAN。SMBus协议多限制了一些电压条件,而且必须在一次性传输多个数据之前先发一帧数据说清楚”总数据的长度“然后再发送具体数据】
我们用写指令 通过0号I2CBUS 往0x1e这个地址挂载的设备里的 0号寄存器 写入0x4 让这个从设备进行复位。


image.png

我们用读指令 通过0号I2CBUS 从0x1e这个地址挂载的设备里的 0xc号寄存器 读取数据,如果要一次性读俩字节,就加个w


image.png

下面这个指令是IIC的基础指令

image.png

image.png

在写代码的时候使用IIC通信


image.png

不过,有封装好的可以用。。


原文链接:https://blog.csdn.net/qq_42635852/article/details/125944715
————————————————

编写APP直接访问EEPROM

[(98条消息) Linux系统驱动之编写APP直接访问EEPROM_韦东山的博客-CSDN博客]


#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
#include "i2cbusses.h"
#include <time.h>


/* ./at24c02 <i2c_bus_number> w "100ask.taobao.com"
 * ./at24c02 <i2c_bus_number> r
 */

int main(int argc, char **argv)
{
    unsigned char dev_addr = 0x50;
    unsigned char mem_addr = 0;
    unsigned char buf[32];

    int file;
    char filename[20];
    unsigned char *str;

    int ret;

    struct timespec req;
    
    if (argc != 3 && argc != 4)
    {
        printf("Usage:\n");
        printf("write eeprom: %s <i2c_bus_number> w string\n", argv[0]);
        printf("read  eeprom: %s <i2c_bus_number> r\n", argv[0]);
        return -1;
    }

    file = open_i2c_dev(argv[1][0]-'0', filename, sizeof(filename), 0);
    if (file < 0)
    {
        printf("can't open %s\n", filename);
        return -1;
    }

    if (set_slave_addr(file, dev_addr, 1))
    {
        printf("can't set_slave_addr\n");
        return -1;
    }

    if (argv[2][0] == 'w')//第2个字符串的第0个字节,0 1 2的2
    {
        // write str: argv[3]
        str = argv[3];

        req.tv_sec  = 0;
        req.tv_nsec = 20000000; /* 20ms */
        
        while (*str)
        {
            // mem_addr, *str
            // mem_addr++, str++
            ret = i2c_smbus_write_byte_data(file, mem_addr, *str);
            if (ret)
            {
                printf("i2c_smbus_write_byte_data err\n");
                return -1;
            }
            // wait tWR(10ms)
            nanosleep(&req, NULL);
            
            mem_addr++;
            str++;
        }
        ret = i2c_smbus_write_byte_data(file, mem_addr, 0); // string end char
        if (ret)
        {
            printf("i2c_smbus_write_byte_data err\n");
            return -1;
        }
    }
    else
    {
        // read
        ret = i2c_smbus_read_i2c_block_data(file, mem_addr, sizeof(buf), buf);
        if (ret < 0)
        {
            printf("i2c_smbus_read_i2c_block_data err\n");
            return -1;
        }
        
        buf[31] = '\0';
        printf("get data: %s\n", buf);
    }
    
    return 0;
    
}
image.png
写一个字节就要进入等待一个写循环时间tWR,然后再写下一个字节

10ms

(https://blog.csdn.net/thisway_diy/article/details/119906374?ops_request_misc=&request_id=&biz_id=102&utm_term=%E7%BC%96%E5%86%99APP%E7%9B%B4%E6%8E%A5%E8%AE%BF%E9%97%AEEEPROM&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-119906374.nonecase&spm=1018.2226.3001.4187)

image.png

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容