I2C组件(新)
来源:互联网 发布:写小说 软件 编辑:程序博客网 时间:2024/05/29 13:37
/** * 文件名:I2C.h */#ifndef _I2C_H#define _I2C_H#define I2Cdelay(); { \ _nop_(); _nop_(); _nop_(); _nop_(); \}typedef enum ackType { ACK = 0, NAK = 1} ack_t;sbit I2C_SCL = P3^7; //检查引脚是否正确!sbit I2C_SDA = P3^6;void I2Cstart();void I2Cstop();bit I2Cwrite(uint8_t dat);uint8_t I2Cread(ack_t ackbit);#endif // _I2C_H
/** * 文件名:I2C.c * 描 述:I2C总线驱动模块(新) * 备 注:基于IO口模拟实现,总线时序延时等皆由软件方式实现 * 时钟信号SCL的产生和延时很重要 */#include <reg52.h>#include <intrins.h>#include "stdint.h"#include "I2C.h"/* 产生总线起始信号 */void I2Cstart() { I2C_SDA = 1; //首先确保sda、scl都是高电平 I2C_SCL = 1; I2Cdelay(); //保持状态一段时间 I2C_SDA = 0; //先拉低sda(在scl为高电平期间,sda出现下降沿) I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl(使得可以往数据线sda上写数据)}/* 产生总线停止信号 */void I2Cstop() { //I2C_SCL = 0; //首先确保sda、scl都是低电平(时钟信号scl之前已经置0了) I2C_SDA = 0; I2Cdelay(); //之前i2c已经工作过,是以时钟信号scl为0结束的,此时需要把该时钟状态保持一段时间 I2C_SCL = 1; //先拉高scl I2Cdelay(); //保持状态一段时间 I2C_SDA = 1; //再拉高sda(在scl为高电平期间,sda出现上升沿) I2Cdelay(); //保持状态一段时间}/* i2c总线写操作,dat-待写入字节,返回值-从机应答位的值 */bit I2Cwrite(uint8_t dat) { bit ack; //用于暂存应答位的值 uint8_t mask; //用于探测字节内某一位值的掩码变量 //从高位到低位依次进行 for (mask = 0x80; mask != 0; mask >>= 1) { if ((mask & dat) == 0) //该位的值输出到sda上(之前已经保证scl为低电平了,此时可以写数据) I2C_SDA = 0; else I2C_SDA = 1; I2Cdelay(); //保持状态一段时间 I2C_SCL = 1; //拉高scl(使得从机可以从sda上读数据) I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl,完成一个位周期,为下一次写数据做好准备 } I2C_SDA = 1; //8位数据发送完后,主机释放sda,以检测从机应答 I2Cdelay(); //保持状态一段时间,此时从机将应答值写到sda上 I2C_SCL = 1; //拉高scl ack = I2C_SDA; //读取此时的sda值,即为从机的应答值 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl完成应答位,并保持住总线,为下一次写数据做好准备 return (~ack); //应答值取反以符合通常的逻辑: //0=不存在或忙或写入失败,1=存在且空闲或写入成功}/** * I2C总线读操作,并发送非应答(1)/应答(0)信号。 * 参数:非应答(1)/应答(0) * 返回值:读到的字节 */uint8_t I2Cread(ack_t ackbit) { uint8_t mask, dat; I2C_SDA = 1; //首先确保主机释放sda,之前已确保scl为0 //从高位到低位依次进行 for (mask = 0x80; mask != 0; mask >>= 1) { I2Cdelay(); //延时一段时间,此时从机将数据位写到sda上 I2C_SCL = 1; //拉高scl,主机开始读 if (I2C_SDA == 0) //读取sda的值 dat &= ~mask; //为0时,dat中对应位清零 else dat |= mask; //为1时,dat中对应位置1 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl,以使从机发送出下一位 } I2C_SDA = ackbit; //8位数据发送完后,主机发送非应答/应答信号 I2Cdelay(); //保持状态一段时间 I2C_SCL = 1; //拉高scl,使得从机可以读这个应答信号 I2Cdelay(); //保持状态一段时间 I2C_SCL = 0; //再拉低scl完成应答位,并保持住总线 return dat;}
0 0
- I2C组件(新)
- I2C组件
- 新组件
- Linux 下I2C设备驱动新框架
- 新路程----hi3516a i2c驱动 kernel panic
- 新路程------hi3516a i2c设备reset
- 新路程------imx6 i2c clk频率修改
- 其它新组件
- 新组件发布推迟
- android新组件
- Android新组件-CoordinatorLayout
- OpenStack新组件打包
- i2c adapter、i2c总线控制器、I2C bus(帖子)
- Pentaho技术白皮书中文版(三)--构建新组件
- 深入Android 【三】 —— 组件入门(新)
- I2C总线(转)
- I2C总线(2)
- 详解I2C(一)
- 优化php执行效率的40条小技巧
- C++第三章
- Windows Authentication with Chrome and IIS
- 01-背包问题---Bone Collector
- Android客户端程序通过Web Service实现对服务器端数据库的查询
- I2C组件(新)
- 关于java.lang.OutOfMemoryError: PermGen space问题的解决办法
- hibernate4 DetachedCriteriaBuilder的基本案例
- 【数据库之事务(一)】事务是什么,以及事务四个特性,以及事务并发问题和隔离级别
- Maven生命周期
- Where is my java?
- ubuntu调节屏幕亮度
- Java中设置classpath、path、JAVA_HOME的作用
- static_cast用法浅析