文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>I2C

I2C

时间:2010-07-21  来源:nearfuture_qinyaomin

1:        i2c总线(串行总线),用于CPU与外设直接进行通信。只有两条线:数据线SDA总线),用于CPU与外设直接进行通信。只有两条线:数据线SDA, 控制线SCL。 具有简单性,有效性,"最主要优点"是:多主控,即可以连接多个设备,但同一时刻只有一个设备成为主设备与CPU通信。为主设备时,可以自己控制当前总线的时钟频率及数据传输。
2:
2.1 总线的构成及信号类型         I2C 总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率 100kbps。各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程 中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能。CPU发出的控制信号分为地址码和控制 量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量。这样,各控制电路虽然挂 在同一条总线上,却彼此独立,互不相关。
      I2C总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号。       开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。       结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。        应 答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元 发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。    目前有很多半导体集成电路上都集成了I2C接口。
 2.2        i2c总线是两条线连接多个设备,inter ic.         寻址是通过在scl线上发出寻址信号: 起始,7/10位 地址 + 1位(读/写),(多个后续的数据),终止位。  而地址是由设备的脚决定,一般会有几个固定脚与几个可编程脚。通过编程可以确定设备的地址。当设备收到寻址信号后,判断是不是其地址。
7位寻址,被I2C协会保留,所以一般用10位寻址:s,1111 0xx (R/W) ACK xxxxxxxx    若(R/W) = 0, 则为从MASTER > slave,写 所以10个x为地址  若(R/W) = 1,则为 从 SLAVE > MASTER, 读, 此时先前被寻址了的SLAVE就会发送数据给MASTER。
2.3 i2c是基于8位的 SCL时钟线,由主机提供时钟。 起始位: sda下降,scl保持高 结束位: sda上升,scl保持高。 地址位,一般是10位,被拆分为 xx (r/w) ack xxxxxxxx 数据: 每个字节必须是8位,先传MSB。每个字节后必须跟一个响应位(从机发) 每次从机接收时,可以使SCL为低,从而让主机进入等待状态。

3:"linuxi2c体系结构" 三个层次:  1,i2c核心,内核完成 i2c-core.c  2, i2c总线驱动, 实现 i2c_adapter(总线适配器),i2c_algorithm(通信方法)  3, i2c设备驱动,实现 i2c_driver, i2c_client 通信方法:  通过i2c_msg来表示每次的通信。每次可以收发多个i2c_msg.


//adapter注册,当成是一个platform_bus总线下的设备。 int i2c_add_adapter(struct i2c_adapter *adapter)  res = idr_get_new_above(&i2c_adapter_idr, adapter,__i2c_first_dynamic_bus_num, &id);  i2c_register_adapter(adapter); static int i2c_register_adapter(struct i2c_adapter *adap) {  if (adap->dev.parent == NULL)   adap->dev.parent = &platform_bus;  adap->dev.release = &i2c_adapter_dev_release;  adap->dev.class = &i2c_adapter_class;  res = device_register(&adap->dev); } //i2c_add_adapter()而言,它使用的是动态总线号,即由系统给其分析一个总线号,而i2c_add_numbered_adapter()则是自己指定总线号,

//i2c_driver注册, 即driver先匹配所有adapter,找到正确的,然后检测硬件,生成对应的i2c_client, 然后把i2c_client注册到adapter上。 当 i2c_driver向内核注册时,会被调用attach_adatper,先匹配当前系统中所有adapter,再去检测硬件,当确定硬件存在,则会生 成匹配i2c_client?, 把i2c_client的driver指针指向自己(driver),adapter指针指向其adapter.然后会让这个adapter调用 其client_register. 
注册: static inline int i2c_add_driver(struct i2c_driver *driver) {  return i2c_register_driver(THIS_MODULE, driver); } int i2c_register_driver(struct module *owner, struct i2c_driver *driver) {  driver->driver.owner = owner;  driver->driver.bus = &i2c_bus_type;  res = driver_register(&driver->driver);  //注册代表本 i2c_driver的 内部 driver  class_for_each_device(&i2c_adapter_class, NULL, driver, __attach_adapter); //从目前系统中所的adapter中去匹配 对应的 adapter. } static int __attach_adapter(struct device *dev, void *da ta) {  struct i2c_adapter *adapter = to_i2c_adapter(dev);  struct i2c_driver *driver = da ta;
 i2c_detect(adapter, driver);  //检测硬件
 /* Legacy drivers scan i2c busses directly */  if (driver->attach_adapter)  driver->attach_adapter(adapter); //生成client 并加入到adapter 中。  return 0; } 而一般 i2c_driver的实现时是: static int yy_attach_adapter(struct i2c_adapter *adapter) {  return i2c_probe(adapter, &addr_da ta, yy_detect); }
static int yy_detect (struct i2c_adapter * adapter, int address, int kind) {  struct yy_da ta da ta = kzalloc(sizeof(struct yy_da ta), GFP_KERNEL);  i2c_client new_client = da ta->client;  err = i2c_attach_client(new_client); }
/*  * The following structs are for those who like to implement new bus drivers:  * i2c_algorithm is the interface to a class of hardware solutions which can  * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584  * to name two of the most common.  */ struct i2c_algorithm {  /* If an adapter algorithm can't do I2C-level access, set master_xfer    to NULL. If an adapter algorithm can do SMBus access, set    smbus_xfer. If set to NULL, the SMBus protocol is simulated    using common I2C messages */  /* master_xfer should return the number of messages successfully    processed, or a negative value on error */  int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,   "i2c传输函数"    int num);  int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,  "smbus传输函数"    unsigned short flags, char read_write,    u8 command, int size, union i2c_smbus_da ta *da ta);
 /* To determine what the adapter supports */  u32 (*functionality) (struct i2c_adapter *);     "返回适配器支持的功能" }; /*  * i2c_adapter is the structure used to identify a physical i2c bus along  * with the access algorithms necessary to access it.  */ struct i2c_adapter {  "代表 一个物理的I2C总线"  struct module *owner;  unsigned int id;  unsigned int class;   /* classes to allow probing for */  const struct i2c_algorithm *algo; /* the algorithm to access the bus */  void *algo_da ta;
 /* --- administration stuff. */  int (*client_register)(struct i2c_client *);  int (*client_unregister)(struct i2c_client *);
 /* da ta fields that are valid for all devices  */  u8 level;   /* nesting level for lockdep */  struct mutex bus_lock;  struct mutex clist_lock;
 int timeout;  /* in jiffies */  int retries;  struct device dev;  /* the adapter device */
 int nr;  struct list_head clients;  /* DEPRECATED */  char name[48];  struct completion dev_released; };
/**  * struct i2c_driver - represent an I2C device driver  * @id: Unique driver ID (optional)  * @class: What kind of i2c device we instantiate (for detect)  * @attach_adapter: Callback for bus addition (for legacy drivers)  * @detach_adapter: Callback for bus removal (for legacy drivers)  * @detach_client: Callback for device removal (for legacy drivers)  * @probe: Callback for device binding (new-style drivers)  * @remove: Callback for device unbinding (new-style drivers)  * @shutdown: Callback for device shutdown  * @suspend: Callback for device suspend  * @resume: Callback for device resume  * @command: Callback for bus-wide signaling (optional)  * @driver: Device driver model driver  * @id_table: List of I2C devices supported by this driver  * @detect: Callback for device detection  * @address_da ta: The I2C addresses to probe, ignore or force (for detect)  * @clients: List of detected clients we created (for i2c-core use on ly)  *  * The driver.owner field should be set to the module owner of this driver.  * The driver.name field should be set to the name of this driver.  *  * For automatic device detection, both @detect and @address_da ta must  * be defined. @class should also be set, otherwise on ly devices forced  * with module parameters will be created. The detect function must  * fill at least the name field of the i2c_board_info structure it is  * handed upon successful detection, and possibly also the flags field.  *  * If @detect is missing, the driver will still work fine for enumerated  * devices. Detected devices simply won't be supported. This is expected  * for the many I2C/SMBus devices which can't be detected reliably, and  * the on es which can always be enumerated in practice.  *  * The i2c_client structure which is handed to the @detect callback is  * not a real i2c_client. It is initialized just enough so that you can  * call i2c_smbus_read_byte_da ta and friends on it. Don't do anything  * else with it. In particular, calling dev_dbg and friends on it is  * not allowed.  */ struct i2c_driver {  int id;  unsigned int class;
 /* Notifies the driver that a new bus has appeared. This routine  * can be used by the driver to test if the bus meets its conditions  * & seek for the presence of the chip(s) it supports. If found, it  * registers the client(s) that are on the bus to the i2c admin. via  * i2c_attach_client.  (LEGACY I2C DRIVERS ON LY)  */  int (*attach_adapter)(struct i2c_adapter *);  int (*detach_adapter)(struct i2c_adapter *);
 /* tells the driver that a client is about to be deleted & gives it  * the chance to remove its private da ta. Also, if the client struct  * has been dynamically allocated by the driver in the function above,  * it must be freed here.  (LEGACY I2C DRIVERS ON LY)  */  int (*detach_client)(struct i2c_client *) __deprecated;
 /* Standard driver model interfaces, for "new style" i2c drivers.  * With the driver model, device enumeration is NEVER done by drivers;  * it's done by infrastructure.  (NEW STYLE DRIVERS ON LY)  */  int (*probe)(struct i2c_client *, const struct i2c_device_id *);  int (*remove)(struct i2c_client *);
 /* driver model interfaces that don't relate to enumeration  */  void (*shutdown)(struct i2c_client *);  int (*suspend)(struct i2c_client *, pm_message_t mesg);  int (*resume)(struct i2c_client *);
 /* a ioctl like command that can be used to perform specific functions  * with the device.  */  int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);  "类似ioctl"
 struct device_driver driver;  const struct i2c_device_id *id_table;    "与本驱动 匹配的 设备id"
 /* Device detection callback for automatic device creation */  int (*detect)(struct i2c_client *, int kind, struct i2c_board_info *); "设备检测"  const struct i2c_client_address_da ta *address_da ta;  struct list_head clients; };
/**  * struct i2c_client - represent an I2C slave device  * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;  *  I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking  * @addr: Address used on the I2C bus connected to the parent adapter.  * @name: Indicates the type of the device, usually a chip name that's  *  generic enough to hide second-sourcing and compatible revisions.  * @adapter: manages the bus segment hosting this I2C device  * @driver: device's driver, hence pointer to access routines  * @dev: Driver model device node for the slave.  * @irq: indicates the IRQ generated by this device (if any)  * @list: list of active/busy clients (DEPRECATED)  * @detected: member of an i2c_driver.clients list  * @released: used to synchronize client releases & detaches and references  *  * An i2c_client identifies a single device (i.e. chip) connected to an  * i2c bus. The behaviour exposed to Linux is defined by the driver  * managing the device.  */ struct i2c_client {  unsigned short flags;  /* div., see below  */  unsigned short addr;  /* chip address - NOTE: 7bit  */  /* addresses are stored in the  */  /* _LOWER_ 7 bits  */  char name[I2C_NAME_SIZE];  struct i2c_adapter *adapter;  /* the adapter we sit on  */  struct i2c_driver *driver;  /* and our access routines  */  struct device dev;  /* the device structure  */  int irq;  /* irq issued by device  */  struct list_head list;  /* DEPRECATED */  struct list_head detected;  struct completion released; };

/**  * struct i2c_board_info - template for device creation  * @type: chip type, to initialize i2c_client.name  * @flags: to initialize i2c_client.flags  * @addr: stored in i2c_client.addr  * @platform_da ta: stored in i2c_client.dev.platform_da ta  * @archdata: copied into i2c_client.dev.archdata  * @irq: stored in i2c_client.irq  *  * I2C doesn't actually support hardware probing, although controllers and  * devices may be able to use I2C_SMBUS_QUICK to tell whether or not there's  * a device at a given address.  Drivers commonly need more information than  * that, such as chip type, configuration, associated IRQ, and so on.  *  * i2c_board_info is used to build tables of information listing I2C devices  * that are present.  This information is used to grow the driver model tree  * for "new style" I2C drivers.  For mainboards this is done statically using  * i2c_register_board_info(); bus numbers identify adapters that aren't  * yet available.  For add-on boards, i2c_new_device() does this dynamically  * with the adapter already known.  */ struct i2c_board_info {  char  type[I2C_NAME_SIZE];  unsigned short  flags;  unsigned short  addr;  void  *platform_da ta;  struct dev_archdata  *archdata;  int  irq; }; struct i2c_devinfo {  struct list_head  list;  int  busnum;  struct i2c_board_info  board_info; };
//***************************************************************// struct i2c_msg {  __u16 addr;  /* slave address  */  __u16 flags; #define I2C_M_TEN  0x0010  /* this is a ten bit chip address */ #define I2C_M_RD  0x0001  /* read da ta, from slave to master */ #define I2C_M_NOSTART  0x4000  /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_REV_DIR_ADDR  0x2000  /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK  0x1000  /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK  0x0800  /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_RECV_LEN  0x0400  /* length will be first received byte */  __u16 len;  /* msg length  */  __u8 *buf;  /* pointer to msg da ta  */ };
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载