大家好,欢迎来到IT知识分享网。
1、前言
2、EEPROM介绍
3、实际产品中EEPROM的使用场景
4、I2C时序分析
参考博客:《I2C通信协议详解和通信流程分析》;
5、根据I2C时序编写I2C通信代码
5.1、I2C通信开始和结束
/* * 函 数 名 : I2C_Start() * 函数功能 : 起始信号:在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿 * 输 入 : 无 * 输 出 : 无 * 备 注 : 起始之后I2C_SDA和I2C_SCL都为0 */ void I2C_Start() {
I2C_SDA = 1; I2C_Delay10us(); I2C_SCL = 1; I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7us I2C_SDA = 0; I2C_Delay10us();//保持时间是>4us I2C_SCL = 0; I2C_Delay10us(); } /* * 函 数 名 : I2C_Stop() * 函数功能 : 终止信号:在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿 * 输 入 : 无 * 输 出 : 无 * 备 注 : 结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲 */ void I2C_Stop() {
I2C_SDA = 0; I2C_Delay10us(); I2C_SCL = 1; I2C_Delay10us();//建立时间大于4.7us I2C_SDA = 1; I2C_Delay10us(); }
5.2、I2C主设备读从设备函数
/* * 函 数 名 : I2cSendByte(uchar num) * 函数功能 : 通过I2C发送一个字节。在I2C_SCL时钟信号高电平期间, * * 保持发送信号I2C_SDA保持稳定 * 输 入 : num ,ack * 输 出 : 0或1。发送成功返回0,发送失败返回-1 * 备 注 : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0 / uchar I2C_SendByte(uchar dat, uchar ack) {
uchar a = 0,b = 0 I2C_SCL = 0; //保证在开始发送数据前时钟线是低电平 for(a=0; a<8; a++)//要发送8位,从最高位开始 {
I2C_SDA = dat >> 7; //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号 dat = dat << 1; I2C_Delay10us(); I2C_SCL = 1; I2C_Delay10us();//建立时间>4.7us I2C_SCL = 0; I2C_Delay10us();//时间大于4us } I2C_SDA = 1; // 主设备释放SDA线给从设备去操作 I2C_Delay10us(); I2C_SCL = 1; // 主设备开始了第9个周期 while(I2C_SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低 {
b++; if(b > 200) //如果超过200us没有应答发送失败,或者为非应答,表示接收结束 {
I2C_SCL = 0; I2C_Delay10us(); return -1; } } I2C_SCL = 0; I2C_Delay10us(); return 0; }
5.3、I2C主设备写从设备函数
/* * 函 数 名 : I2cReadByte() * 函数功能 : 使用I2c读取一个字节 * 输 入 : 无 * 输 出 : dat * 备 注 : 接收完一个字节I2C_SCL=0 */ uchar I2C_ReadByte() {
uchar a = 0,dat = 0; I2C_SDA = 1; //主设备释放SDA线给从设备去操作 I2C_Delay10us(); // 按道理这里应该有一个SCL = 0的 I2C_SCL = 0; for(a=0; a<8; a++)//接收8个字节 {
I2C_SCL = 1; // 通知从设备我要开始读了,可以放1bit数据到SDA了 I2C_Delay10us(); dat <<= 1; // 读取的时候是高位在前的 dat |= I2C_SDA; I2C_Delay10us(); I2C_SCL = 0; // 拉低,为下一个bit的周期做准备 I2C_Delay10us(); } return dat; }
6、单片机和嵌入式设备的I2C通信区别
7、24c02的原理图分析
7.1、引脚介绍
引脚名称 | 引脚作用 |
---|---|
SCL | I2C的时钟线 |
SDA | I2C的数据线 |
E0、E1、E2 | 决定从地址 |
WE | 写保护引脚,当引脚为高电平时不允许写,当引脚为低电平时允许写 |
7.2、从地址确定
8、24c02的随机读数据操作函数
/* * 函 数 名 : unsigned char At24c02Read(unsigned char addr) * 函数功能 : 读取24c02的一个地址的一个数据 * 输 入 : 无 * 输 出 : 无 / unsigned char At24c02Read(unsigned char addr) {
unsigned char num; I2C_Start(); I2C_SendByte(0xa0, 1); //发送写器件地址 I2C_SendByte(addr, 1); //发送要读取的地址 I2C_Start(); I2C_SendByte(0xa1, 1); //发送读器件地址 num=I2C_ReadByte(); //读取数据 I2C_Stop(); return num; }
9、24c02的字节写数据操作函数
/* * 函 数 名 : void At24c02Write(unsigned char addr,unsigned char dat) * 函数功能 : 往24c02的一个地址写入一个数据 * 输 入 : 无 * 输 出 : 无 / void At24c02Write(unsigned char addr,unsigned char dat) {
I2C_Start(); I2C_SendByte(0xa0, 1);//发送写器件地址 I2C_SendByte(addr, 1);//发送要写入内存地址 I2C_SendByte(dat, 0); //发送数据 I2C_Stop(); }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/121728.html