什么是I2C

首先需要知道什么是I2C协议。I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息(摘自百度百科)。I2C主要有两条线,一条SDA数据线,一条SCL时钟线。由于I2C支持主机与多从机之间的通信,所以在传输数据之前先进行寻址操作,才能与对应的从机建立通信。多从机的存在可能出现多个从机同时需要占用总线的情况,这时候就要通过总线仲裁来选择与某个从机进行通信了。每次通信发送或接收的数据为8位一个字节。

I2C时序图详解及通信协议程序

空闲时的SCL和SDA两条线都为高电平,每次通信结束后都需要释放总线,将SCL和SDA拉高。

起始信号和结束信号

起始信号和结束信号时序图如下:
可以看到起始信号是这样产生的:先将SDA数据总线拉低,再将SCL时钟线拉低;而结束信号与其实信号相反,先把SCL时钟线拉高后再将SDA数据总线拉高。
程序代码如下:

//起始信号
void I2C_start()
{I2C_SCL_1;I2C_SDA_1;I2C_Delay();I2C_SDA_0;I2C_Delay();I2C_SCL_0;
}
//结束信号
void I2C_stop()
{I2C_SDA_0;I2C_SCL_1;I2C_Delay();I2C_SDA_1;
}

数据传输

I2C要求在SCL高电平期间数据线保持稳定,在低电平期间SDA可以产生电平跳变和数据变化。
发送数据代码如下:

void I2C_sendbyte(uint8_t send_data)
{uint8_t i;for(i=0;i<8;i++){if(send_data&(0X80>>i)) I2C_SDA_1; else I2C_SDA_0;I2C_SCL_1; I2C_Delay(); I2C_SCL_0;}
}

接收数据如下:

uint8_t I2C_readbyte(uint8_t ack)
{uint8_t read_data=0;uint8_t i;uint8_t readbit;for(i=0;i<8;i++){if(I2C_SDA_0) readbit=0; else readbit=1;I2C_Delay();I2C_SCL_1;I2C_Delay();I2C_SCL_0;read_data= (read_data|readbit)<<1;}I2C_Delay();//应答信号if(ack==0)I2C_NACK();elseI2C_ACK();return Data;
}

应答信号

有应答信号(ACK)和非应答信号(NACK)两种,代码如下:

void I2C_ACK(void)       //  应答信号
{I2C_SDA_0;I2C_Delay();I2C_SCL_1;I2C_Delay();I2C_SCL_0;I2C_SDA_1;
}void I2C_NACK(void)        //非应答信号
{I2C_SDA_1;I2C_Delay();I2C_SCL_1;I2C_Delay();I2C_SCL_0;I2C_Delay();I2C_SDA_0;
}

还有一个等待从机发送应答信号的函数:

uint8_t waitACK()
{uint8_t receive;I2C_SDA_1;I2C_Delay();I2C_SCL_1;I2C_Delay();if(I2C_SDA_1)receive=1;else   receive=0;I2C_SCL_0;I2C_Delay();return receive;
}

通信协议

在对某个芯片的寄存器进行读写操作的时候,需要严格按照时序图的操作来执行:

I2C的通讯协议大概分为几个步骤:
1.主机发出起始信号
2.主机发出寻址信号并确认本次操作是读还是写(由寻址信号的最后一位是0还是1决定,0为写,1为读)
3.从机发送应答信号,主机接收
4.主机发送数据信号,从机接收
5.从机发送应答信号,主机接收
6.主机发送停止信号,从机接收,然后结束一次通信。

写入寄存器时的代码如下:

void I2C_write_reg(uint8_t slaveaddr,uint8_t regaddr,uint8_t*writebuffer,uint8_t Wlen)
{uint8_t writeflag=0;uint8_t i;uint8_t error;I2C_start();                      //起始信号I2C_sendbyte(slaveaddr|0x00);     //寻址信号:从机地址+写操作if(waitACK)                          //等待从机应答信号error|=0x01;I2C_sendbyte(regaddr);               //寄存器地址if(waitACK)error|=0x02;for(i=0;i<Wlen;i++)                    //写入数据{I2C_sendbyte(writebuffer[i]);if(waitACK)error|=0x04;}I2C_stop();                            //停止信号
}

读取从机数据的代码如下。需要注意每读取完一个字节(8位)数据后,都需要发送一次应答信号,当最后一个字节数据读取完毕之后发送非应答信号和结束信号以结束本次通信:

void I2C_read_reg(uint8_t slaveaddr,uint8_t regaddr,uint8_t*readbuffer,uint8_t Rlen)
{uint8_t error=0;uint8_t i=0;I2C_start();I2C_sendbyte(slaveaddr|0x00);if(waitACK)error|=0x01;I2C_sendbyte(regaddr);if(waitACK)error|=0x02;I2C_sendbyte(slaveaddr|0x01);if(waitACK)error|=0x04;for(i=0;i<=(Rlen-1);i++){*readbuffer=I2C_readbyte(1);    //每读取完一个字节,都需要给从机一个应答信号readbuffer++;}*readbuffer=I2C_readbyte(0);     //最后一个字节读取完发送非应答信号I2C_stop();}

51单片机模拟I2C协议相关推荐

  1. 51单片机模拟I2C程序

    IIC即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦公司研发出来的.是一种两线式串行总线,两条线可以挂多个参与通信的器件,即多机模式.一般由控制器作为主机. ...

  2. 51单片机模拟I2C读写M24LR04

    目录 一. 有关M24LR04的介绍 二. I2C的读写时序 三. 参考代码 四. 调试中遇到的问题 一. 有关M24LR04的介绍 M24LR04是ST公司的一款NFC芯片,支持ISO15693和I ...

  3. 51单片机模拟PS2协议制作5X5矩阵工业键盘

    根据客户的要求利用单片机制作一个小的工控键盘,将下面对应的键值发送到电脑显示,利用的协议就是PS2,单片机型号为stc89c52rc,晶振为12M: 1 0 6 5 4 3 2 7 8 9 减号 等号 ...

  4. 使用51单片机模拟IIC从机,实现主机(51单片机)对模拟从机的读写操作

    51单片机.IIC从机模拟.IIC协议.iiC读写 1.思路 1.1写数据 1.2读数据 2.从机IIC协议 2.1起始信号和结束信号 2.2从机读取和写数据 2.3从机发送和接收ACK 2.4判断主 ...

  5. 51单片机模拟数字键盘输入以及图像显示+Proteus仿真

    51单片机模拟数字键盘输入以及图像显示+Proteus仿真 关于取模 取模软件:pctolcd2002 文字取模方式:阴码–列行式,逆向 主程序代码 //*********************** ...

  6. 51单片机模拟电梯控制(含完整代码)

    51单片机模拟电梯控制 前言 一.普中51-单核-A2开发板 二.系统功能 三 .预定义 四.电梯内按有报警按键,该功能由外部中断功能和蜂鸣器实现 五.延时函数-----电梯每上升,下降一层和开门关门 ...

  7. 51单片机模拟电子琴+Proteus仿真

    51单片机模拟电子琴+Proteus仿真 Proteus仿真 示例程序 #include<reg51.h> #include<intrins.h>#define uchar u ...

  8. STM32模拟I2C协议获取MLX90615红外温度传感器测温数据(Open Drain管脚配置)

    STM32模拟I2C协议获取MLX90615红外温度传感器测温数据(Open Drain管脚配置) STM32的GPIO管脚可以配置为Open Drain输出模式,并且有两个功能: 可以设置内部上拉, ...

  9. 51单片机模拟交通信号灯控制系统设计

    51单片机模拟交通信号灯控制系统设计 设计要求: 1.用LED灯模拟十字路口交通灯控制 2.正常情况下双方向轮流通行 3.特殊情况时,A方向通行 4.紧急情况时,A和B方向都不通行 本任务涉及定时控制 ...

最新文章

  1. 9月8日凌晨,字节跳动全员收到邮件!因为这件事,所有人多发半个月工资!字节沸腾!网友酸了!...
  2. SQL开发技巧 join从句
  3. 使用Spring Security进行简单身份验证
  4. java8的新特性_Java8的
  5. 前端学习(1911)vue之电商管理系统电商系统之完成用户的修改弹框询问用户是否删除
  6. rust拆掉墙_rust怎么拆自己的墙
  7. python中0o10_Python基础10—I/O编程
  8. Python列表模拟页面调度LRU算法(京东2016笔试题)
  9. 实现可拖拽,拉伸,吸附功能的甘特图(时间/任务表)
  10. 求出一个整型数组的最大子集和
  11. 【PLY】Lex和Yacc简单示例
  12. flash 林度_flash怎么制作呢 ?
  13. vue实现一键回到顶部
  14. kubernetes完整学习笔记
  15. SIGMOD 2021 论文简析:当公交网络连接满足通勤需求时的公共交通规划 Public Transport Planning
  16. 研究生最全文献查询、下载网站汇总,汇集各个专业权威国外网站!
  17. HTML5学习笔记(三)
  18. linux中Iscpi命令详解(四)
  19. spring揭密学习笔记
  20. XSL3399我开通博客了谢多交流

热门文章

  1. 软件测试模型——V模型 W模型
  2. 解决Podman网络DNS不可用问题
  3. 【matlab】:matlab如何写函数并且调用函数?
  4. JS面向对象编程三大特征
  5. “NetSarang的Xmanager和Xshell多种产品被植入后门事件”分析报告
  6. IP地址转换:int转string
  7. python安装遇到出现0x80072f7d错误的解决办法
  8. Windows打开pages文稿
  9. Modern OpenGL - GLSL着色语言2:GLSL入口函数和GLSL中的变量
  10. disconf mysql_Disconf配置中心配置