详解通信协议之IIC通信协议

article/2025/6/24 7:39:55

详解通信协议之IIC通信协议

本文结合AT24C02对IIC通信协议原理进行了描述。

IIC通信协议(以AT24C02为例)

IIC通讯协议(Inter-Integrated Circuit)是由 Philips 公司开发双向同步半双工串行总线,只需要两根线(SDA、SCL)即可在连接于总线上的器件之间传送信息。IIC总线是一种共享的串行总线,是用于两个设备之间的短距离低速速率(250K左右)通信。长距离用can总线。

  1. IIC数据有效性
    数据在时钟线(SCL)为高电平时,数据线(SDA)要稳定保持稳定,时钟线为低电平时,数据线任意变化。
  2. 起始和结束条件
    起始条件:当SCL为高电平时,SDA由高到低的跳变为起始信号。
    结束条件:当SCL为高电平时,SDA由低到高的跳变为结束信号。
    起始信号和结束信号
  3. 应答信号
    当主机向从机发送完一个字节的数据,主机需要从机给出一个应答信号,用来确认是否接收到了数据。从机的应答信号的时钟仍然是主机提供的,应答信号出现在8位数据之后的那一个时钟周期。低电平:表示接收成功,高电平:表示接收失败。
  4. 数据帧格式
    起始信号–>从机地址+数据传输方向(0为主机发送,1为主机接收)–>数据交换–>结束信号。
    在这里插入图片描述

注意:在数据方向进行变换时,需要重新发送起始信号和期间地址+读写状态。

  1. 以AT24C02为例,模拟IIC控制代码
    AT24C02的存储容量为2K,芯片地址为1010,其地址控制字格式为1010-A2A1A0-R/W。其中A2,A1,A0可编程地址选择位。A2,A1,A0引脚接高、低电平后得到确定的三位编码,与1010形成7位编码,即为该器件的地址码。R/W为芯片读写控制位,该位为0是写,1是读。
void I2CInit(void) //IIC引脚初始化,初始化为**开漏输出**,外接上拉电阻提高引脚的驱动能力
{GPIO_InitTypeDef GPIO_InitStructure = {0};GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_6;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*****SDA、SCL引脚模式配置*****/
void SDA_Input_Mode()//设置数据线为输入模式
{GPIO_InitTypeDef GPIO_InitStructure = {0};GPIO_InitStructure.Pin = GPIO_PIN_7;GPIO_InitStructure.Mode = GPIO_MODE_INPUT;GPIO_InitStructure.Pull = GPIO_PULLUP;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SDA_Output_Mode() //设置数据线输出模式配置
{GPIO_InitTypeDef GPIO_InitStructure = {0};GPIO_InitStructure.Pin = GPIO_PIN_7;GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStructure.Pull = GPIO_NOPULL;GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void SDA_Output( uint16_t val ) //设置数据线输出电平
{if ( val ){GPIOB->BSRR |= GPIO_PIN_7;}else{GPIOB->BRR |= GPIO_PIN_7;}
}
void SCL_Output( uint16_t val )  //设置时钟线的输出电平
{if ( val ){GPIOB->BSRR |= GPIO_PIN_6;}else{GPIOB->BRR |= GPIO_PIN_6;}
}
uint8_t SDA_Input(void)  //读取数据线输入状态
{if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET){return 1;}else{return 0;}
}static void delay1(unsigned int n) //80MHz延时0.1us根据自己的主频进行调节
{uint32_t i;for ( i = 0; i < n; ++i);
}
void I2CStart(void)  //起始信号
{SDA_Output(1);     //数据线为高电平为下降沿做准备delay1(20);     //延时2usSCL_Output(1);  //时钟线变为高电平delay1(20);     //延时2usSDA_Output(0);  //时钟线为高时,数据线变为低delay1(20);   //延时2usSCL_Output(0); //时钟线变为低delay1(20);   //延时2us
}
void I2CStop(void) //结束信号
{SCL_Output(0);  //时钟线为低delay1(20);   //延时2usSDA_Output(0); //数据线为低  为上升做准备delay1(20);   //延时2usSCL_Output(1);  //时钟线变为高delay1(20);    //延时2usSDA_Output(1); //时钟线为高时,数据线上升沿结束信号delay1(20);  //延时2us
}unsigned char I2CWaitAck(void) //等待响应信号
{unsigned short cErrTime = 5;SDA_Input_Mode();  //数据线设置为输入模式delay1(20);      //延时2usSCL_Output(1);   //时钟线输出高delay1(20);      //延时2uswhile(SDA_Input())  //判断数据线输出是否为低{cErrTime--;delay1(20);if (0 == cErrTime){SDA_Output_Mode();I2CStop();return ERROR;}}SDA_Output_Mode(); //切换模式SCL_Output(0); //数据线输出0delay1(20);  //延时2usreturn SUCCESS;  //返回成功
}
/*******IIC字符读写*********/
void I2CSendByte(unsigned char cSendByte)  //发送一个字符,也就是8bit数据
{unsigned char  i = 8;while (i--){SCL_Output(0);delay1(20);SDA_Output(cSendByte & 0x80);delay1(20);cSendByte += cSendByte;delay1(20);SCL_Output(1);delay1(20);}SCL_Output(0);delay1(20);
}unsigned char I2CReceiveByte(void) //接收一个字符的数据
{unsigned char i = 8;unsigned char cR_Byte = 0;SDA_Input_Mode();while (i--){cR_Byte += cR_Byte;SCL_Output(0);delay1(20);delay1(20);SCL_Output(1);delay1(20);cR_Byte |=  SDA_Input();}SCL_Output(0);delay1(20);SDA_Output_Mode();return cR_Byte;
}
uchar eeprom_read (uchar address)  ///读取某一地址的数据
{uchar date;I2CStart();          //启动	IICI2CSendByte(0XA0);   //写指令I2CWaitAck();    //等待有效响应I2CSendByte(address);   //发送读取内容的地址I2CWaitAck();    //等待有效响应	I2CStop();     //发送停止信号I2CStart();          //启动	IIC	I2CSendByte(0XA1);   //读数据指令I2CWaitAck();    //等待有效响应date=I2CReceiveByte();  //读取数据I2CWaitAck();//读取完成的应答信号I2CStop();     //发送停止信号return 	date;}void eeprom_write (uchar address,uchar date)  ///给某一地址写数据
{I2CStart();          //启动	IICI2CSendByte(0XA0);   //写指令I2CWaitAck();    //等待有效响应I2CSendByte(address);   //发送内容写到的地址I2CWaitAck();    //等待有效响应I2CSendByte(date);I2CWaitAck();    //等待发送完成I2CStop();     //发送停止信号	
}

初始化引脚之后调用读写就可以了。


http://chatgpt.dhexx.cn/article/g1q4WXwl.shtml

相关文章

IIC(I2C)通信协议详解

简介 I2C 是飞利浦公司设计的&#xff0c;一种很常见的总线协议&#xff0c; I2C 使用两条线在主控制器和从机之间进行数据通信。一条是 SCL(串行时钟线)&#xff0c;另外一条是SDA(串行数据线)&#xff0c;这两条数据线需要接上拉电阻&#xff0c;总线空闲的时候 SCL 和 SDA …

IIC 通信协议

一、IIC 通信协议介绍 IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线&#xff0c;用于连接微控制器及其外围设备。 如今主要在服务器管理中使用&#xff0c;其中包括单个组件状态的通信。例如管理员可对各个组件进行查询&#xff0c;以管理系统…

三大通信协议(二):IIC通信协议

目录 1. 概念2. 硬件连接3. 数据传输协议3.1 开始信号3.2 地址位3.3 读写位&#xff08;R/W&#xff09;3.4 应答位&#xff08;ACK / NACK&#xff09;3.5 数据位&#xff08;8Bit&#xff09;3.6 停止信号 4. 软件编写4.1 初始化4.2 开始信号4.3 IIC发送一个字节数据4.4 IIC读…

IIC通信协议总结

&#xff08;1&#xff09;概述 I2C(Inter-Integrated Circuit BUS) 集成电路总线&#xff0c;该总线由NXP&#xff08;原PHILIPS&#xff09;公司设计&#xff0c;多用于主控制器和从器件间的主从通信&#xff0c;在小数据量场合使用&#xff0c;传输距离短&#xff0c;任意时…

IIC通信协议,搞懂这篇就够了

注&#xff1a;公众号后台发送 “IIC” 即可获取基于STM32上实现软件模拟IIC的完整代码。 I2C(IIC)属于两线式串行总线&#xff0c;由飞利浦公司开发用于微控制器(MCU)和外围设备(从设备)进行通信的一种总线&#xff0c;属于一主多从(一个主设备(Master)&#xff0c;多个从设备…

IIC通讯协议

一、简介 IIC&#xff08;Inter-integerted Circuit&#xff09;集成电路总线&#xff0c;该通信协议由NXP&#xff08;原PHILIPS&#xff09;公司设计&#xff0c;多用于主控制器和从器件间的主从通信&#xff0c;在小数据量场景下使用&#xff0c;传输距离短&#xff0c;任意…

搜狗搜索正式接入微信公众号

搜狗搜索正式接入微信公众号 6月9日中午消息&#xff0c;搜狗搜索今日宣布正式接入微信公众号数据。用户将在搜狗搜索页面查询和浏览微信公众号文章。 据悉&#xff0c;在搜狗搜索框中输入微信公众号关键词&#xff0c;便可在搜索结果页中查看相关微信公众号的文章列表&#xf…

Python爬虫 selenium自动化 利用搜狗搜索爬取微信公众号文章信息

少年最好的地方就是:虽然嘴上说要放弃,心底却总会憋着一口气。——刘同 文章目录 一、需求和网页分析二、selenium爬虫一、需求和网页分析 URL:https://weixin.sogou.com/ 你是否有特别喜欢的一些公众号文章,比如说关于网易云热评的。 我那么多遗憾,那么多期盼,你知道…

RSS订阅微信公众号初探-feed43

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

python爬虫爬取微信公众号历史文章链接

一、最近公司有了要爬取微信公众号文章链接的需求&#xff0c;之前最初接触爬公众号文章的时候&#xff0c;用的是搜狗微信&#xff0c;在这个上面可以搜到相关的微信公众号文章&#xff0c;但是这些链接是有时效性的&#xff0c;第二天链接就打不开了&#xff08;不知道现在是…

python抓取搜狗微信公众号文章

初学python&#xff0c;抓取搜狗微信公众号文章存入mysql mysql表&#xff1a; 代码&#xff1a; import requests import json import re import pymysql# 创建连接 conn pymysql.connect(host你的数据库地址, port端口, user用户名, passwd密码, db数据库名称, charsetut…

搜狗微信文章采集php,[造轮子]爬取搜狗微信公众号文章

背景&#xff1a;想做一个公众号文章资源APP&#xff0c;发现搜狗有搜索公众号文章功能&#xff0c;果断开撸。http://wxiread.com (用CMS搭了个简易的站)。 Step1.分析栏目及接口 搜狗分了20个栏目&#xff0c;分别是 热门,推荐,段子手,养生堂,私房话… 对应地址从 /pcindex/p…

微信公众号的“温柔一刀”,搜狗微信搜索部分功能将被下线

作为搜狗的单一最大股东&#xff0c;腾讯与搜狗之间的联系向来就很紧密&#xff0c;其中包括搜搜被并入搜狗、微信公众号的搜索功能划分给搜狗、腾讯新闻、QQ浏览器等腾讯系产品的搜索功能全部换成搜狗。腾讯对搜狗的支持是显而易见的&#xff0c;但若有利益冲突的情况下&#…

【scrapy爬虫】最新sogou搜狗搜索 机智操作绕过反爬验证码(搜狗微信公众号文章同理)

前情提要 此代码使用scrapy框架爬取特定“关键词”下的搜狗常规搜索结果&#xff0c;保存到同级目录下csv文件。并非爬取微信公众号文章&#xff0c;但是绕过验证码的原理相同。如有错误&#xff0c;希望大家指正。 URL结构 https://www.sogou.com/web?query{关键词}&p…

利用搜狗抓取微信公众号文章

微信一直是一个自己玩的小圈子&#xff0c;前段时间搜狗推出的微信搜索带来了一丝曙光。搜狗搜索推出了内容搜索和公众号搜索两种&#xff0c;利用后者可以抓取微信公众号的最新内容&#xff0c;看了下还是比较及时的。 每个公众号都有一个openid&#xff0c;最早可以直接利用…

html语言判断水仙花数,水仙花数判断讲解

今天要讲解的这道题是 水仙花数判断 题目要求 本题要求实现一个函数&#xff0c;判断任一整数是否为水仙花数(必须是三位数&#xff0c;且数的每一位上数字的立方和与数本身相等)。例如1531^35^33^3112527153&#xff0c;而1或155则不是水仙花数。如果是水仙花数&#xff0c;则…

水仙花数的求解思路

目录 水仙花数输入一个数&#xff0c;求解从0到这个数的所有水仙花数 解题思路源代码&#xff1a;注意事项 水仙花数 在以前的博客之中写过求解水仙花数的博客 详情见下面链接&#xff1a; 求解水仙花数 在这里就主要写求解水仙花数的思路 输入一个数&#xff0c;求解从0到这…

计算水仙花数有哪些

计算水仙花数有哪些 一、介绍水仙花数二、使用while循环计算水仙花数1.源代码2.运行结果 三、使用for循环计算水仙花数1.执行代码部分2.运行结果3.源代码 一、介绍水仙花数 水仙花数指的是三位整数中每个数的立方之和等于本身的数 二、使用while循环计算水仙花数 1.源代码 …

水仙花数

一、描述&#xff1a; 所谓的“水仙花数”是指一个三位数其各位数字的立方和等于该数本身。 例如153是“水仙花数”&#xff0c;因为&#xff1a;153 13 53 33。 在数论中&#xff0c;水仙花数&#xff08;Narcissistic number&#xff09;也称为自恋数、自幂数、阿姆斯壮…

prgrmz的作品集

符号化执行(基于klee)生成测试用例初探 lstm广告点击量预测案例 一般蔬菜类果实无人采摘方案&#xff08;算法&#xff09; 分页页面通用爬虫建模(一般优化问题) 机器学习练习 概率图模型应用例子&#xff1a;图像分割 概率图模型应用例子&#xff1a;立体视觉 概率图模型…