AT24C02使用详解

这篇文章是写给一个学弟看的,关于IIC,关于24C02的单字节写入\读取..页写入和读取,,学弟总是害怕协议,,,我总是对人家说,本来就这样的,协议就是人家这样规定的,,,如果你早生几十年你也可能规定个IIC协议......

我的单片机和24C02通信,,,我的单片机就叫主机,,,24C02叫从机

先看IIC

IIC协议规定开始传输数据的时候要先发一个起始信号,,,目的应该是告诉从机要开始通信了,准备准备

终止信号就是拜拜啦,再见!

起始信号就是 在SCL在高电平期间SDA来一个下降沿,,终止信号就是在SCL在高电平期间SDA来一个上升沿(所以协议上才会说,在正常传输数据的时候,只有在SCL为低电平的时候,数据线SDA的高低电平状态才允许改变,要不然岂不是和起始信号或者终止信号冲突了)

/*******************************************************************

起动总线函数

函数原型: void  Start_I2c();

功能:    启动I2C总线,即发送I2C起始条件.

********************************************************************/voidStart_I2c()

{

SDA=1;/*发送起始条件的数据信号*/_Nop();

SCL=1;

_Nop();/*起始条件建立时间大于4.7us,延时*/_Nop();

_Nop();

_Nop();

_Nop();

SDA=0;/*发送起始信号*/_Nop();/*起始条件锁定时间大于4μs*/_Nop();

_Nop();

_Nop();

_Nop();

SCL=0;/*钳住I2C总线,准备发送或接收数据*/_Nop();

_Nop();

}

voidStop_I2c()

{

SDA=0;/*发送结束条件的数据信号*/_Nop();/*发送结束条件的时钟信号*/SCL=1;/*结束条件建立时间大于4μs*/_Nop();

_Nop();

_Nop();

_Nop();

_Nop();

SDA=1;/*发送I2C总线结束信号*/_Nop();

_Nop();

_Nop();

_Nop();

}

发送完起始信号就能传输数据了

下面是程序

voidSendByte(unsignedcharc)

{

unsignedcharBitCnt;//SCL=0; 起始信号最后是SCL=0;所以不用写了for(BitCnt=0;BitCnt<8;BitCnt++)/*要传送的数据长度为8位*/{if((c<

SDA=1;

}else{

SDA=0;

}

_Nop();

SCL=1;/*置时钟线为高,通知被控器开始接收数据位*/_Nop();

_Nop();/*保证时钟高电平周期大于4μs*/_Nop();

_Nop();

_Nop();

SCL=0;

}

_Nop();

_Nop();

SDA=1;/*8位发送完后释放数据线,准备接收应答位*/_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();

_Nop();if(SDA==1)/*判断是否接收到应答信号*/ack=0;//没有接收到应答信号elseack=1;//接收到应答信号SCL=0;

_Nop();

_Nop();

}

现在说一下接收,,,假设上面发送完0xaa以后,从机就返回给我们数据(11001100, 0xcc),当然SCL为低电平的时候模块准备数据,,SCL为高电平的时候,从机就把数据放在了SDA上,这样循环8次,一个8位数据就过来了

整体上应该是

Start_I2c();起始信号程序

SendByte(0xaa);

判断下ack是不是等于1,应答了(是继续执行还是停止看自己了)

Data = RcvByte();//接收数据

Ack_I2c(1);//发送非应答,就是SDA=1;,这个程序在下面

Stop_I2c();发送停止信号

接收程序如下

unsignedcharRcvByte()

{

unsignedcharretc;

unsignedcharBitCnt;

retc=0;

SDA=1;/*置数据线为输入方式*/for(BitCnt=0;BitCnt<8;BitCnt++)

{

_Nop();

SCL=0;/*置时钟线为低,准备接收数据位*/_Nop();

_Nop();/*时钟低电平周期大于4.7μs*/_Nop();

_Nop();

_Nop();

SCL=1;/*置时钟线为高使数据线上数据有效*/_Nop();

_Nop();

retc=retc<<1;if(SDA==1)retc=retc+1;/*读数据位,接收的数据位放入retc中*/_Nop();

_Nop();

}

SCL=0;

_Nop();

_Nop();return(retc);

}

应答或者非应答程序如下

/********************************************************************

应答子函数

函数原型:  void Ack_I2c(bit a);

功能:      主控器进行应答信号(可以是应答0或非应答1信号,由位参数a决定)

********************************************************************/voidAck_I2c(bit a)

{if(a==0)SDA=0;/*在此发出应答或非应答信号*/elseSDA=1;

_Nop();

_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();/*时钟低电平周期大于4μs*/_Nop();

_Nop();

_Nop();

SCL=0;/*清时钟线,钳住I2C总线以便继续接收*/_Nop();

_Nop();

}

IIC其实就这样了,主要看支持IIC通信的芯片的资料了,写好这些就是IIC通用的了

资料链接

https://wenku.baidu.com/view/3fc8558002d276a200292ef9.html

现在看芯片资料如何写进去一个字节

关于器件的地址

写就是0xa0;;;;读就是0xa1

所以写函数就是

/**

* @brief  向24C02写数据

* @param  Data--数据

* @param  Address--地址

* @param  None

* @retval None

* @example

**/unsignedcharWriteData(unsignedcharData,unsignedcharAddress)

{

Start_I2c();

SendByte(0xa0);//最后一位为0写入if(ack==0)return(0);

SendByte(Address);//发送地址if(ack==0)return(0);

SendByte(Data);//发送数据if(ack==0)return(0);

Stop_I2c();//结束总线return(1);

}

关于应答哈我的SendByte(unsigned char  c)函数里面发送完8位数据后就写了应答,然后把应答标志给ack,,后面直接判断的ack

现在想想为什么叫应答...直接说判断从机正没正确接收到数据就完了呗,就是把SDA拉高,然后把SCL拉高,等一会然后判断SDA引脚有没有被从机拉低,拉低了就说明好了......没拉低从机可能接收的数据不正确

_Nop();

_Nop();

SDA=1;                /*8位发送完后释放数据线,准备接收应答位*/

_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();

_Nop();

if(SDA==1)/*判断是否接收到应答信号*/

ack=0;//没有接收到应答信号

else

ack=1;//接收到应答信号

SCL=0;

_Nop();

_Nop();

}

再看从任意地址读一个数据

注意哈第一个发送的器件地址是0xa0,后面的是0xa1

所以程序如下

/**

* @brief  从24C02读出数据

* @param  None

* @param  Address--地址

* @param  None

* @retval 读到的数据

* @example

**/unsignedcharReadData(unsignedcharAddress)

{

unsignedcharData =0;

Start_I2c();

SendByte(0xa0);//最后一位为0if(ack==0)return(0);

SendByte(Address);//发送地址if(ack==0)return(0);

Start_I2c();

SendByte(0xa1);//最后一位为1if(ack==0)return(0);

Data=RcvByte();

Ack_I2c(1);//发送非就答位Stop_I2c();//结束总线return(Data);

}

现在看页写

把程序先放上,对了写的时候的开始地址最好是0,8,16,24,32,40,68,,,,8的倍数,要不然数据可能有错误,当然我用的芯片页写最多一次能写入8个字节.....感觉有点少哈......可以在现在的基础上再做一个函数实现哈,,或者用写单字节的for循环下....

/**

* @brief  向24C02写数据----页写,,,最多一次写入8个字节,多了会覆盖前面的

* @param  Data--数据

* @param  StartAddress--开始的地址--最大255

* @param  None

* @retval None

* @example

**/unsignedcharPageWrite(unsignedchar*Data,unsignedcharAddress,unsignedcharcnt)

{

Start_I2c();

SendByte(0xa0);//最后一位为0写入if(ack==0)return(0);

SendByte(Address);//发送地址if(ack==0)return(0);while(cnt--)

{

SendByte(*Data++);//发送数据if(ack==0)return(0);

DelayMs(10);

}

Stop_I2c();//结束总线return(1);

}

现在看页读

看程序

/**

* @brief  从24C02读出数据----页读

* @param  Data--数据指针

* @param  StartAddress--开始的地址--最大255

* @param  None

* @retval None

* @example

**/unsignedcharPageRead(unsignedchar*Data,unsignedcharAddress,unsignedcharcnt)

{

Start_I2c();

SendByte(0xa0);//最后一位为0if(ack==0)return(0);

SendByte(Address);//发送要读的地址if(ack==0)return(0);

Start_I2c();

SendByte(0xa1);//最后一位为1if(ack==0)return(0);while(cnt--)

{*Data  =RcvByte();

Data++;

Ack_I2c(0);//发送应答位DelayMs(10);

}

Ack_I2c(1);//发送非应答位Stop_I2c();//结束总线return(1);

}

说一下读的时候最好开始读取的地址是8的倍数,读取的数据个数也是8的倍数,,,我测试的如果不是这样有时候,第二次页读的时候就会读错........

这芯片和8干上了............

还有一个立即读,,,看明白就行,就是立即返回当前读地址加1后的那个数据

源码链接

链接:http://pan.baidu.com/s/1i4M7BId%20密码:r9ov

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • 在使用单片机的过程中,I2C 通信可以说是最被广泛使用和采纳的协议之一,采用 I2C 协议可以占用更少的资源,链接...
    noparkinghere阅读 2,078评论 0 8
  • IIC通信实验 IIC简介 I²C(Inter-Integrated Circuit)字面上的意思是集成电路之间,...
    btskyrmb阅读 1,884评论 0 2
  • i2c总线协议: 历史:是飞利浦公司在80年代,为研发音视频模块的通讯而产生。因其具有的诸多优点,而沿用至今。 优...
    ibo阅读 1,434评论 1 1
  • 串行通信的几个名词: 全双工:数据线有2条,分别用来发送和接收。半双工:数据线只有1条,用来发送和接收,分时复用。...
    X_xxieRiemann阅读 1,558评论 0 0
  • 1、嵌入式系统的定义 (1)定义:以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本...
    荣卓然阅读 1,791评论 0 5