SCL(clock)时钟信号
SDA(data)数据总线
数据位的有效性规定
I²C总线进行数据传输时,时钟信号为高电平期间。数据总线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或者低电平状态才允许变化。
时序图
起始信号和终止信号
当时钟信号高电平,
SDA变低电平,为起始信号,若SDA变高电平,为终止信号
起始信号产生后 ,总线处于占用状态
终止信号产生后,总线处于空闲状态
void start()//起始信号
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop()//终止信号
{
sda=0;
delay();
scl=1;
delay();
sda=0;
delay();
}
数据传送格式
(1)字节传送与应答
一帧=一个字节+应答位=9位,一个字节八位,第九位是应答位
从机如果接收不了信号,就将SDA数据线置于高电平 ,中断通信;若主机要中断通信,就要发送一个终止信号,从机应答,就能终端通信。
void responds()//应答信号
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
(2)数据帧格式
灰色为主机 白色为从机
发送数据
在起始信号后必须传送一个从机地址(7位),第八位是数据的传送放方向位(R/T),0表示主机发送数据给从机T(transmit),1表示主机接受从机数据R(receive)
读数据
E²PROM
这里用的是AT24C02
芯片地址1010(固定的)
地址控制字格式1010 A2A1A0 R/W, A2 A1 A0接高低电平后得到三位确定的编码,和1010形成确定的7位编码,即地址码。R/W为芯片读写控制位,0表示写操作,1表示读操作。(为了便于观察最后一位0或1,我们这里的A2A1A0全都接地)
片内子地址寻址:有256个,地址码相当于大楼的地址,子地址相当于大楼内的每一个房间号,0-255,共256个
字节写入方式
void write_byte(uchar date)//写地址
{
uchar i,temp;
temp=date;
scl=0;
delay();
for(i=0;i<8;i++)
{
temp=temp<<1;
sda=CY;//最高位
delay();
scl=1;
delay();
scl=0;
delay();
}
sda=1;
delay();
}
接下来解释补充
左移:最高位向左移动,移入PSW的CY位,最低位补0;右移最低位移除,最高位保留。
temp=temp<<1;//左移一位
数据是一个一个送出来的,具体如下
指定地址读操作
start();//启动
write_byte(0xa0);//器件地址+写
responds();//应答
write_byte(3);//子地址
responds();//应答
start();//这里要多一个应答
write_byte(0xa1);//器件地址+读
responds();//应答
P1=read_byte();//赋值
stop();//停止
while(1);
其中read_byte 具体如下
uchar read_byte()
{
uchar i,j,k=0;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
j=sda;
k=(k<<1)|j;
scl=0;
delay();
}
return k;
}
k的起始数值为0,相当于0000 0000B
或运算,有1为1,全0位0
对于 “ k=(k<<1) | j; ”解释如下
具体事例
#include #define uchar unsigned char #define uint unsigned int sbit sda=P2^0; sbit scl=P2^1; void delay() { ;; } void delay1(uchar z) { uchar x,y; for(x=z;x>0;x--) for(y=100;y>0;y--); } void start()//ÆðʼÐźŠ{ sda=1; delay(); scl=1; delay(); sda=0; delay(); } void stop()//ÖÕÖ¹ÐźŠ{ sda=0; delay(); scl=1; delay(); sda=1; delay(); } void responds()//Ó¦´ðÐźŠ{ uchar i=0; scl=1; delay(); while((sda==1)&&(i<255)) i++; scl=0; delay(); } void write_byte(uchar date)//дµØÖ· { uchar i,temp; temp=date; scl=0; delay(); for(i=0;i<8;i++) { temp=temp<<1; sda=CY;//×î¸ßλ delay(); scl=1; delay(); scl=0; delay(); } sda=1; delay(); } uchar read_byte() //¶ÁÊý¾Ý { uchar i,j,k=0; scl=0; delay(); sda=1; delay(); for(i=0;i<8;i++) { scl=1; delay(); j=sda; k=(k<<1)|j; scl=0; delay(); } return k; } void init() { scl=1; sda=1; } void write_add(uchar address, uchar date) { start();//ÆðʼÐźŠwrite_byte(0xa0);//Æ÷¼þµØÖ· ¸ßËÄλ¹Ì¶¨1010 0±íʾҪд device adress responds(); write_byte(address);//д 0-256 word adress responds(); write_byte(date);//data responds(); stop(); } uchar read_add(uchar address) { uchar date; delay1(100); start(); write_byte(0xa0);//µØÖ· responds(); write_byte(address); responds(); start();//»»·½Ïò write_byte(0xa1);//Æ÷¼þµØÖ· ºóÃæ±ä1 ÒòΪÊǶÁ responds(); date=read_byte(); stop(); return date; } void main() { init();//³õʼ»¯ write_add(23,0xaa); delay1(100); P1=read_add(23); while(1); }
上一篇:手把手教学51单片机 | 第五课 独立键盘 矩阵键盘
下一篇:手把手教学51单片机 | 1602液晶
推荐阅读最新更新时间:2024-11-16 22:48
推荐帖子
- CMOS电路中空闲引脚的处理方法
- 由于CMOS电路具有极高的输入阻抗,极易感应干扰电压而造成逻辑混乱,甚至损坏。因此,对于CMOS数字电路空闲的引脚不能简单地不管,应根据CMOS数字电路的种类、引脚功能和电路的逻辑要求,分不同情况进行处置。1、对于多余的输出端,一般将其悬空即可。如下图所示;2、CMOS数字电路往往在一个集成块中包含有若干个互相独立的门电路或触发器。对于一个集成块中多余不用的门电路或触发器,应将其所有输入端接到系统的正电源VDD,如下图所示。也可将一个集成块中多余不用的门电路或触
- tiankai001 综合技术交流
- 做研发的一点心得体会!
- 出来作研发也一年了,很有些体会。在这里想与大家分享下!1.不要把自己搞成“实验机器”,要多在课题开展前进行详细的课题论证,信息搜集和筛选。企业一般做课题都很着急,课题进度要求很快,作为研发人员,要做大量的实验,筛选路线,打通路线,优化工艺,放大。其中最容易省略第一步,一般直接查文献,有几篇国内的,直接开做。有时忙活一个月,才发现路线选得有问题,三废多,成本高,或者做不出理想的产率,风风火火的又去查文献,查1,2片又开始新的路线。这样做其实事倍功半的。而且做月度总结时就只有一点,做的实验
- songbo 单片机
- 网页post数据给嵌入式服务器,怎么样才能一个包发给服务器呢?
- 我们公司的嵌入式web服务器只能接收第一个包的数据。而且只能用post方法。一般数据post都分好几个包传倒服务器的。我想问下做网页的时候怎样才能使数据在一个包里发到服务器。网页post数据给嵌入式服务器,怎么样才能一个包发给服务器呢?接分是王道!这个简单啊,网上搜一下就得到答案了.友情Up!使用MySQL的嵌入式服务器,能够在客户端应用程序中使用具备全部特性的MySQL服务器。主要优点:?只要一个动态库就可以了,不需要安装ODBC驱动。?增加了速度,并使得嵌入
- fgaggag 嵌入式系统
- TUSB9261 -- USB3.0转SATA接口桥接芯片 烧录指南
- TUSB9261是TI的一款USB3.0转SATA接口的桥接芯片,其相关的参考资料如下:http://www.ti.com/product/TUSB9261在使用过程中,因为需要对SPIflash做programming,所以会涉及到一定的操作步骤,很多人对此有些疑虑,其实只需要TUSB9261和USB口设计正确,。特别是在板子设计调试时,需要直接通过板载的方式直接进行SPIflash烧录的时候,可以按照下述的步骤来进行。从板卡角度上来看,只需要,只需要通
- fish001 微控制器 MCU
- 改装原装电池为增强数码摄像机电池的技巧
- 本帖最后由jameswangsynnex于2015-3-319:57编辑SONY的特点之一就是标准配置低。比如记忆卡,8M容量简直就是鸡肋。又比如标配电池,容量小,使用时间短。所以大家买机,一般都要多配大容量卡、厚电池。对于手头这些“食之无味、弃之可惜”的鸡肋,其实只要动动手,鸡肋也可以升级的。虽然最近网上说小容量ms卡可破解的传言只是假消息,但电池是绝对可以改装的。以下贴出改造手头数块F330的pp,望能抛砖引玉。早一点的sonyDV标配是这种电池。7.2V5.0WH(
- lorant 移动便携
- CYT4BF芯片的掉电检测(BOD)问题
- 如题,如图该芯片手册中的BOD怎么还分high-voltage和low-voltage图片中的上升沿检测点,下降沿检测点怎么理解?CYT4BF芯片的掉电检测(BOD)问题ConfigurableoptionsforrobustBODTwothresholdlevels(2.7Vand3.0V)forBODonVDDDandVDDAOnethresholdlevel(1.1V)forBODonVCCD高压
- shaorc 单片机
设计资源 培训 开发板 精华推荐
- 数字钟1
- LTC3703、36V72V 至 12V/5A 同步降压转换器
- LT3580、1.2MHz、5V 至 12V 升压转换器实现了超过 88% 的效率
- 用于完整 3V、12 位、1MHz 模数转换系统的 AD8604ARZ-REEL 运算放大器的典型应用
- AD8061AR-EBZ,AD8061ARZ 单高速运算放大器评估板,采用 8 引脚 SOIC 封装
- 带MUX可正反插的TYPE-C转HDMI+USB3+PD+VGA
- LTC2936 的典型应用 - 具有 EEPROM 和比较器输出的可编程十六进制电压监控器
- 使用 Infineon Technologies AG 的 IR3551 的参考设计
- 具有外部偏置或同步功能的 CS51413 1.5 A、260 kHz 和 520 kHz 低压降压稳压器的典型应用电路
- 具有输入电流、输出电流和温度感测/限制功能的 20V、2.5A 单片同步降压 SWITCHER+