手把手教学51单片机第七课 | AT24C02的I²C总线数据传输

最新更新时间:2022-05-28来源: eefocus关键字:51单片机  AT24C02  I²C总线  数据传输 手机看文章 扫描二维码
随时随地手机看文章

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单片机  AT24C02  I²C总线  数据传输 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic565767.html

上一篇:手把手教学51单片机 | 第五课 独立键盘 矩阵键盘
下一篇:手把手教学51单片机 | 1602液晶

推荐阅读

51单片机流水灯控制(5种方法)
实现流程: 1. 新建一个工程(新项目) 2. 查看原理图确定需求(流水灯)对应LED引脚在单片机上的哪个引脚 3. 编写程序(通过查看原理图可以看到我们需要控制整个P2口以控制8个LED灯) 4. 编译程序,下载程序至开发板 5. 查看效果(调试)进制转换表(因为单片机首先处理的是十六进制的数据,所以我们需要将二进制控制需求转换成十六进制去写代码):控制代码:#include <REGX52.H> //头文件#include "Delay.h"#include "intrins.h"/* -----------------------------------------
发表于 2022-09-29
<font color='red'>51单片机</font>流水灯控制(5种方法)
51单片机 定时器时钟
1.main.c注:Sec,Min,Hour可不进行赋值#include <REGX52.H>#include "Delay.h"#include "LCD1602.h"#include "Timer0.h"unsigned char Sec=55,Min=59,Hour=23;void main(){ LCD_Init(); Timer0Init(); LCD_ShowString(1,1,"Clock:"); LCD_ShowString(2,1," : :"); while(1) { LCD_ShowNum(2
发表于 2022-09-28
51单片机 按键控制LED流水灯模式
1.将之前文件中Delay.c.h复制过来,进行添加2.模块化编程3.main.c#include <REGX52.H>#include "Timer0.h"#include "Key.h"#include <INTRINS.H>unsigned char KeyNum,LEDMode;void main(){ P2=0xFE; Timer0Init(); while(1) { KeyNum=Key(); if(KeyNum==1) { LEDMode++; if(LEDMode>=2)LEDMode=0; } } }void Timer0_Routi
发表于 2022-09-28
<font color='red'>51单片机</font> 按键控制LED流水灯模式
51单片机 LCD1602调试工具
本章博客讲述的是关于LCD1602的调试,使用它是为了更加直观的表示出代码所要实现的功能1.首先,需要添加两份驱动文件到新建的工程中来,再插入到新建的工程中来将其复制到新建文件的同一目录下,在进行添加2.写出以下代码进行编译查看效果#include <REGX52.H>#include "LCD1602.h"void main(){ LCD_Init(); LCD_ShowChar(1,1,'A'); LCD_ShowString(1,3,"Hello"); LCD_ShowNum(1,9,123,3); //高位补零,如果最后一位是2则显示23 LCD_
发表于 2022-09-28
<font color='red'>51单片机</font> LCD1602调试工具
51单片机 模块化编程
了解模块化编程1.首先了解一下传统方式编程和模块化编程传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路 模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等2. 模块化编程注意事项.c文件:函数、变量的定义.h文件:可被外部调用的函数、变量的声明任何自定义的变量、函数在调用前必须有定义或声明(同一个.c)使用到的自定义函数的.c文件必须添加到工程参
发表于 2022-09-28
<font color='red'>51单片机</font> 模块化编程
51单片机 动态数码管显示
本章博客写的内容主要围绕动态数码管显示,动态数码管显示与静态数码管显示比较稍有变化,主要在添加延时函数这点上1.首先将上一章节使用子函数方法的代码复制过来将Nixie( , )移到下方while循环中(因为要实现效果为动态的)void main(){ while(1) { Nixie(1,1); Nixie(2,2); Nixie(3,3); }}编译下载后效果为:对于这种效果要进行消影的处理因为单片机编译处理顺序是按照:位选 段选 (清零),位选 段选 ,位选 段选由上一段的段选到下一部分的位选需要进行清零处理接下来主要进行:增添延时函数和清零处理2.在STC-ISP中生成相应的延时函数,函数时间为1ms,并对其进行灵活修改,
发表于 2022-09-28
<font color='red'>51单片机</font> 动态数码管显示

推荐帖子

WEB2.0时代,BLOG的价值在哪里?
WEB2.0时代,BLOG的价值在哪里?[img]htV2006年初火爆一时的BLOG风潮到了这个炎炎夏日似乎清凉了一些,BLOG人们沉静下来开始思考,怎样求新求变,怎样跟得上WEB2.0的时代,怎么样在BLOG里寻找商机?寻找价值?做为了一个BLOGGER,我已经经营两年的BLOG,访客到是不少,可是除了能找到机会收一些广告费,还真找不出WEB2.0时代,BLOG的价值在哪里?[img]htV2006年初火爆一时的BLOG风潮到了这个炎炎夏日似乎清凉了一些,BLOG人们沉静
mdsfnsa RF/无线
不知道现在2440的开发板还能卖多少钱
本帖最后由ddllxxrr于2016-1-716:22编辑现在手里有一块FL2440的开发板在积灰,不知道现在还能卖几个钱?不知道现在2440的开发板还能卖多少钱
Bamboli 淘e淘
锁相环无法锁相新人求解
搞了几天了,我想实现基本功能,锁住相位和频率,输入是250HZ左右能锁住我就满足了,求解电阻电容参数怎么配置啊,我这个电路出了什么问题,一直在22HZ频率振动输出,刚注册的号子只有10个币全奖励了希望问题得到处理啊锁相环无法锁相新人求解
18186571573 模拟电子
nrf52832调试记录之IO引脚配置
本帖最后由志心工作室于2020-11-1814:38编辑 由于本工作室开发的蓝牙心电记录模块采用的是nrf52832作为主控芯片,在开发过程中遇到一些问题会陆续和大家分享:下图是nrf52832芯片QFN48封装的引脚图其中P0.02~P0.05和P0.28~P0.31可配置为ADC采集引脚,其他的IO脚可任意分配到各个外设其中P0.09和P0.10默认分配到NFC功能外设,如果需要设置为普通IO或映射到其他外设需要添加宏CONFIG_NFCT_PINS_AS_GPIO
志心工作室 RF/无线
请教一下关于QZ-DCC9010驱动器
有人用过这个驱动器驱动电机么,怎么我按照说明书上连就是驱动不了啊请教一下关于QZ-DCC9010驱动器
dsdsdsdsds 电子竞赛
单片机中lcm能否用于制作动画????
单片机中lcm能否用于制作动画????单片机中lcm能否用于制作动画????
quwer 嵌入式系统
小广播
设计资源 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved