I2C总线之(三)---以C语言理解IIC

为了加深对I2C总线的理解,用C语言模拟IIC总线,边看源代码边读波形:

如下图所示的写操作的时序图:

 

读时序的理解同理。对于时序不理解的朋友请参考“I2C总线之(二)---时序”

完整的程序如下:

 

复制代码
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define write_ADD 0xa0
#define read_ADD 0xa1
uchar a;  
sbit SDA=P2^0;
sbit SCL=P2^1;
void SomeNop();     //短延时
void init();    //初始化
void check_ACK(void);
void I2CStart(void);
void I2cStop(void);
void write_byte(uchar dat);//写字节
void delay(uint z);
uchar read_byte();     //读字节
void write(uchar addr,uchar dat);  //指定地址写
uchar read(uchar addr);       //指定地址读
bit flag;  //应答标志位
void main()
{init();write_add(5,0xaa); //向地址5写入0xaadelay(10);      //延时,否则被坑呀!!!P1=read_add(5);      //读取地址5的值while(1);    
}//***************************************************************************  
void delay()//简单延时函数  
{ ;; }  
//***************************************************************************  
void start()  //开始信号 SCL在高电平期间,SDA一个下降沿则表示启动信号  
{     sda=1; //释放SDA总线  
    delay();  scl=1;  delay();  sda=0;  delay();  
}  
//***************************************************************************  
void stop()   //停止 SCL在高电平期间,SDA一个上升沿则表示停止信号  
{  sda=0;  delay();  scl=1;  delay();  sda=1;  delay();  
}
//***************************************************************************  
void respons()  //应答 SCL在高电平期间,SDA被从设备拉为低电平表示应答  
{  uchar i;  scl=1;  delay(); //至多等待250个CPU时钟周期 while((sda==1)&&(i<250))i++;  scl=0;  delay();  
}  
//***************************************************************************  
void init()//总线初始化 将总线都拉高一释放总线  发送启动信号前,要先初始化总线。即总有检测到总线空闲才开始发送启动信号  
{  sda=1;  delay();  scl=1;  delay();  
}  
//***************************************************************************  
void write_byte(uchar date) //写一个字节  
{  uchar i,temp;  temp=date;  for(i=0;i<8;i++)  {  temp=temp<<1;  scl=0;//拉低SCL,因为只有在时钟信号为低电平期间按数据线上的高低电平状态才允许变化;并在此时和上一个循环的scl=1一起形成一个上升沿  
        delay();  sda=CY;  delay();  scl=1;//拉高SCL,此时SDA上的数据稳定  
        delay();  }  scl=0;//拉低SCL,为下次数据传输做好准备  
    delay();  sda=1;//释放SDA总线,接下来由从设备控制,比如从设备接收完数据后,在SCL为高时,拉低SDA作为应答信号  
    delay();  
}  
//***************************************************************************  
uchar read_byte()//读一个字节  
{  uchar i,k;  scl=0;  delay();  sda=1;  delay();  for(i=0;i<8;i++)  {  scl=1;//上升沿时,IIC设备将数据放在sda线上,并在高电平期间数据已经稳定,可以接收啦  
        delay();      k=(k<<1)|sda;  scl=0;//拉低SCL,使发送端可以把数据放在SDA上  
        delay();      }  return k;  
}  
//***************************************************************************  
void write_add(uchar address,uchar date)//任意地址写一个字节  
{  start();//启动  write_byte(0xa0);//发送从设备地址  respons();//等待从设备的响应  write_byte(address);//发出芯片内地址  respons();//等待从设备的响应  write_byte(date);//发送数据  respons();//等待从设备的响应  stop();//停止  
}  
//***************************************************************************  
uchar read_add(uchar address)//读取一个字节  
{  uchar date;  start();//启动  write_byte(0xa0);//发送发送从设备地址 写操作  respons();//等待从设备的响应  write_byte(address);//发送芯片内地址  respons();//等待从设备的响应  start();//启动  write_byte(0xa1);//发送发送从设备地址 读操作  respons();//等待从设备的响应  date=read_byte();//获取数据  stop();//停止  return date;//返回数据  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/252994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结对编程总结

这个项目我和我的结对伙伴共花了两个月时间&#xff0c;之所以选这个项目&#xff0c;因为我们之前都学习过Python&#xff0c;也做过类似的程序&#xff0c;相比较其他项目而言&#xff0c;这个项目更合适&#xff0c;也让我们对词频统计方面的知识加深了了解。写这个程序我们…

JavaScript初学者必看“new”

2019独角兽企业重金招聘Python工程师标准>>> 译者按: 本文简单的介绍了new, 更多的是介绍原型(prototype)&#xff0c;值得一读。 原文: JavaScript For Beginners: the ‘new’ operator 译者: Fundebug 为了保证可读性&#xff0c;本文采用意译而非直译。 <di…

libGDX-wiki发布

为方便大家学习和访问&#xff0c;我将libgdx的wiki爬取到doku-wiki下&#xff0c;专门建立了以下地址。欢迎大家来共同完善。 http://wiki.v5ent.com 转载于:https://www.cnblogs.com/mignet/p/ligbdx_wiki.html

I2C读写时序

1. I2C写时序图&#xff1a; 注意&#xff1a;最后一个byte后&#xff0c;结束标志在第十个CLK上升沿之后&#xff1a; 2. I2C读时序图&#xff1a; 注意&#xff1a;restart信号格式&#xff1b;读操作结束前最后一组clk的最后一个上升沿&#xff0c;主机应发送NACK&#xff0…

网站性能优化

基本概念 1、网站吞吐量&#xff1a;TPS/每秒的事务数&#xff0c;QPS/每秒的查询数&#xff0c;HPS/每秒的HTTP请求数 2、服务器性能指标&#xff1a;系统负载&#xff0c;内存使用&#xff0c;CPU使用&#xff0c;磁盘使用以及网络I/O等 前端优化方法 1、减少HTTP请求&#x…

JAVA-容器(2)-Collection

&#xff08;基于JDK1.8源码分析&#xff09; 一&#xff0c;Collection 所有实现Collection接口的类原则上应该提供两种构造函数&#xff1a; 【1】无参构造-创建一个空的容器 【2】有参构造-创建一个新的Collection&#xff0c;这个新的Collection和传入的Collection具有相同…

软件测试工具LoadRunner中如何定义SLA?--转载

软件测试工具LoadRunner中如何定义SLA&#xff1f; 浏览&#xff1a;2242|更新&#xff1a;2017-04-09 22:50SLA 是您为负载测试场景定义的具体目标。Analysis 将这些目标与软件测试工具LoadRunner在运行过程中收集和存储的性能相关数据进行比较&#xff0c;然后确定目标的 SLA…

最近阅读20171106

java面试题 线上服务内存OOM问题定位三板斧 JVM的GC ROOTS存在于那些地方 mysql innodb怎样做查询优化 ----未阅读 JAVA CAS原理深度分析----未阅读 转载于:https://www.cnblogs.com/Tpf386/p/7793248.html

LinuxI2C驱动--从两个访问eeprom的例子开始

本小节介绍两个在linux应用层访问eeprom的方法&#xff0c;并给出示例代码方便大家理解。第一个方法是通过sysfs文件系统对eeprom进行访问&#xff0c;第二个方法是通过eeprom的设备文件进行访问。这两个方法分别对应了i2c设备驱动的两个不同的实现&#xff0c;在后面的小结会详…

Cookie详解整理

1.Cookie的诞生 由于HTTP协议是无状态的&#xff0c;而服务器端的业务必须是要有状态的。Cookie诞生的最初目的是为了存储web中的状态信息&#xff0c;以方便服务器端使用。比如判断用户是否是第一次访问网站。目前最新的规范是RFC 6265&#xff0c;它是一个由浏览器服务器共同…

骁龙820和KryoCPU:异构计算与定制计算的作用 【转】

本文转载自&#xff1a;https://www.douban.com/group/topic/89037625/ Qualcomm骁龙820处理器专为提供创新用户体验的顶级移动终端而设计。为实现消费者所期望的创新&#xff0c;移动处理器必须满足日益增长的计算需求且降低功耗&#xff0c;同时还要拥有比以往更低的温度&…

LNMP

准备工作 建立一个软件包目录存放 mkdir -p /usr/local/src/ 清理已经安装包 rpm -e httpd rpm -e mysql rpm -e php yum -y remove httpd yum -y remove mysql yum -y remove php #搜索apache包 rpm -qa http* #强制卸载apache包 rpm -e --nodeps 查询出来的文件名 #检查是否卸…

算法复习——计算几何基础(zoj1081)

题目&#xff1a; Statement of the Problem Several drawing applications allow us to draw polygons and almost all of them allow us to fill them with some color. The task of filling a polygon reduces to knowing which points are inside it, so programmers have …

亚马逊Rekognition发布针对人脸检测、分析和识别功能的多项更新

今天亚马逊Rekognition针对人脸检测、分析和识别功能推出了一系列更新。这些更新将为用户带来多项能力的改今&#xff0c;包括从图像中检测出更多人脸、执行更高精度的人脸匹配以及获得图像中的人脸得到更准确的年龄、性别和情感属性。Amazon Rekognition的客户可以从今天开始使…

(转)CentOS分区操作详解

CentOS分区操作详解 原文&#xff1a;http://blog.csdn.net/yonggeit/article/details/77924393 磁盘分区 分区格式的两种选择&#xff1a;MBR和GPT 分区命令&#xff1a; parted的操作都是实时生效的&#xff0c;小心使用&#xff0c;主要是用于大于2T硬盘&#xff0c;支持MBR…

linux驱动中地址空间转换

在linux kernel 中&#xff0c;物理地址是不能直接使用的&#xff0c;必须通过转换才可以。转换分为两种&#xff0c; 静态和动态。 静态就是下面那种&#xff0c;不过&#xff0c;静态的地址转换&#xff0c;还需要在kernel 初始化的时候作映射。 动态映射是使用 ioremap 函…

getClass()和.class的区别

getClass()和.class的区别 在学习反射时想到了这个问题&#xff0c;.getClass()和.class有没有什么区别&#xff1f; 当然&#xff0c;最明显的区别就是.getClass()是一个对象实例的方法&#xff0c;只有对象实例才有这个方法&#xff0c;具体的类是没有的。类的Class类实例是通…

华为敏捷 DevOps 实践:产品经理如何开好敏捷回顾会议

开篇小故事&#xff1a;前几年&#xff0c;一本叫《沉思录》的书在国内突然曝光度很多&#xff0c;因为前某国家领导人“摆案头&#xff0c;读百遍”。《沉思录》是古罗马皇帝马可奥勒写给自己的书&#xff0c;内容大部分是在鞍马劳顿中写的。其实有一句“我们所听到的不过只是…

斐波那契数列的鬼畜的性质

斐波那契数列的鬼畜的性质 斐波那契数列定理1 \(gcd(f[i],f[i1])1\) 利用辗转相减法 证明&#xff1a;\(gcd(f[i],f[i1])\)\(gcd(f[i1]-f[i],f[i])\)\(gcd(f[i-1],f[i])\)\(....\)\(gcd(f[1],f[2])1\) 斐波那契数列定理2 \(f[mn]f[m-1]f[n]f[m]f[n1]\) 证明&#xff1a;\(f[mn]…