当前位置: 首页 > news >正文

asp网站例子免费信息推广平台

asp网站例子,免费信息推广平台,大连市建设工程招标信息网,网页微信支付目录 背景 I2C协议 数据的有效性 I2C通信开始和停止条件 I2C数据传输 发送 响应 正常情况: 异常情况: 主机结束接收 写寄存器的标准流程 读寄存器的标准流程 仲裁机制 时钟同步 SDA线的仲裁 程序 背景 对单片机的三大通信中的I2C通信进…

目录

背景

I2C协议

数据的有效性

I2C通信开始和停止条件

I2C数据传输

发送

响应

正常情况:

异常情况:

主机结束接收

写寄存器的标准流程

读寄存器的标准流程

仲裁机制

时钟同步

SDA线的仲裁

程序


背景

对单片机的三大通信中的I2C通信进行说明。

I2C协议

协议采用双线结构传输数据,包括一个数据线和一个时钟线(即 SDA 和 SCL 线),其中 SDA(Serial Data)线用于双向数据传输,而 SCL(Serial Clock)线则用于同步数据传输的时钟信号。通信始终由主设备(Master)控制,从设备(Slave)被动接收和回应。这种简单的线路连接方式使得设备之间的互连变得非常容易。

数据的有效性

SDA 线上的数据必须在时钟的高电平周期保持稳定 (PS:在SCL为高电平的时候,SDA发生发生变化是作为I2C通信开始和结束的信号)数据线的高或低电平状态只有在 SCL 线的时钟
信号是低电平时才能改变。也就是说在 SCL为高电平时,SDA上的信号保持稳定 只有在SCL为低电平时,SDA上的信号才能改变 。数据的接收方会在每个时钟周期的高电平期间读取数据(SDA),因此数据是在SCL为高电平时进行读取的。

I2C通信开始和停止条件

表示起始条件:SCL 是高电平时 SDA 线从高电平向低电平切换
表示结束条件: SCL 是高电平时 SDA 线由低电平向高电平切换表示停止条件
总结:I2C的SCL为高电平时候,SDA发生变化是作为开始/结束的条件
PS:起始和停止条件一般由主机产生 总线在起始条件后被认为处于忙的状态。在停止条件的某段时间后总线被认为再次处于空闲状态。如果产生 重复起始 Sr条件而不产生停止条件总线会一直处于忙的状态,此时的起始条件 S和重复起始 Sr条件在功能上是一样的。

I2C数据传输

发送

发送到 SDA 线上的每个字节必须为 8 位,每次传输可以发送的字节数量不受限制 每个字节后必须跟 一个响应位 ,首先传输的是数据的最高位 MSB,如果从机要完成一些其他功能后 例如一个
内部中断服务程序,才能接收或发送下一个完整的数据字节, 可以使时钟线 SCL 保持低电平迫使主机进入 等待状态. 当从机准备好接收下一个数据字节并释放时钟线 SCL 后数据传输继续.

响应

正常情况:

数据传输必须带响应。 相关的响应时钟脉冲由主机产生。 在响应的时钟脉冲期间, 发送器释放 SDA 线高 在响应的时钟脉冲期间 接收器必须将 SDA 线拉低!  使它在这个时钟脉冲的高电平期间保持稳定的低电平。

异常情况:

从机不能响应从机地址时 例如它正在执行一些实时函数不能接收或发送 从机必须使数据线保持 高电平(NACK) 主机然后产生一个停止条件终止传输或者产生重复起始条件开始新的传输。
如果从机 接收器响应了从机地址但是在传输了一段时间后不能接收更多数据字节 主机必须再一次
终止传输 这个情况用从机在第一个字节后没有产生响应来表示 从机使数据线保持高电平 主机产生一 个停止或重复起始条件。

主机结束接收

如果传输中有主机(作为接收者) 它必须通过在 从机不产生时钟的 最后一个字节不产生一个响应向从机 (发送器)通知数据结束! 从机 发送器必须释放数据线,允许主机产生一个停止或重复起始条件

写寄存器的标准流程

  1. Master发起START
  2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
  3. Slave发送ACK
  4. Master发送reg addr(8bit),等待ACK
  5. Slave发送ACK
  6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
  7. Slave发送ACK
  8. 第6步和第7步可以重复多次,即顺序写多个寄存器
  9. Master发起STOP

读寄存器的标准流程

  1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
  2. Slave发送ACK
  3. Master发送reg addr(8bit),等待ACK
  4. Slave发送ACK
  5. Master发起re -START
  6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
  7. Slave发送ACK
  8. Slave发送data(8bit),即寄存器里的值
  9. Master发送ACK
  10. 第8步和第9步可以重复多次,即顺序读多个寄存器
  11. 主机想结束接收时,最后一个数据不再需要ACK应答,保持为高电平(NACK)。
  12. 主机发出 STOP 信号,停止 I2C 通信

 

主机想结束接收时,最后一个数据不再需要ACK应答,保持为高电平(NACK)。

仲裁机制

如果存在多主机的情况下,才要考虑仲裁机制。I2C总线上的仲裁分两部分:SCL线的同步和SDA线的仲裁。

时钟同步

在 I2C 总线上传送信息时的时钟同步信号是由挂接在 SCL 线上的所有器件的 逻辑“与” (线与,所以需要SCL也是开漏输出)完成的。即如果有多个主机同时产生时钟,那么只有所有主机都发送高电平时,SCL 上才表现为高电平,否则 SCL 都表现为低电平。

SDA线的仲裁

总线仲裁是为了解决多设备同时竞争中线控制权的问题,通过一定的裸机来决定哪个设备能够获得最终的总线控制权。

SDA线的仲裁也是建立在总线具有线“与”逻辑功能的原理上的。节点在发送1位数据后,比较总线上所呈现的数据与自己发送的是否一致(回读机制)。

  • 是,继续发送;
  • 否则,退出竞争;

I2C总线的控制逻辑:低电平优先

SDA线的仲裁可以保证I2C总线系统在多个主节点同时企图控制总线时通信正常进行并且数据不丢失,总线系统通过仲裁只允许一个主节点可以继续占据总线

程序

void I2C_GPIO_Init(void){ //I2C接口初始化GPIO_InitTypeDef  GPIO_InitStructure; 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //启动I2C功能 GPIO_InitStructure.GPIO_Pin = I2C_SCL | I2C_SDA; //选择端口号                      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //选择IO接口工作方式       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    GPIO_Init(I2CPORT, &GPIO_InitStructure);
}void I2C_Configuration(void){ //I2C初始化I2C_InitTypeDef  I2C_InitStructure;I2C_GPIO_Init(); //先设置GPIO接口的状态I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//设置为I2C模式I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = HostAddress; //主机地址(从机不得用此地址)I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//允许应答I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //7位地址模式I2C_InitStructure.I2C_ClockSpeed = BusSpeed; //总线速度设置 	I2C_Init(I2C1,&I2C_InitStructure);I2C_Cmd(I2C1,ENABLE);//开启I2C					
}void I2C_SAND_BUFFER(u8 SlaveAddr,u8 WriteAddr,u8* pBuffer,u16 NumByteToWrite){ //I2C发送数据串(器件地址,寄存器,内部地址,数量)I2C_GenerateSTART(I2C1,ENABLE);//产生起始位while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); //清除EV5I2C_Send7bitAddress(I2C1,SlaveAddr,I2C_Direction_Transmitter);//发送器件地址while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//清除EV6I2C_SendData(I2C1,WriteAddr); //内部功能地址while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//移位寄存器非空,数据寄存器已空,产生EV8,发送数据到DR既清除该事件while(NumByteToWrite--){ //循环发送数据	I2C_SendData(I2C1,*pBuffer); //发送数据pBuffer++; //数据指针移位while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//清除EV8}I2C_GenerateSTOP(I2C1,ENABLE);//产生停止信号
}
void I2C_SAND_BYTE(u8 SlaveAddr,u8 writeAddr,u8 pBuffer){ //I2C发送一个字节(从地址,内部地址,内容)I2C_GenerateSTART(I2C1,ENABLE); //发送开始信号while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); //等待完成	I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Transmitter); //发送从器件地址及状态(写入)while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //等待完成	I2C_SendData(I2C1,writeAddr); //发送从器件内部寄存器地址while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待完成	I2C_SendData(I2C1,pBuffer); //发送要写入的内容while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待完成	I2C_GenerateSTOP(I2C1,ENABLE); //发送结束信号
}
void I2C_READ_BUFFER(u8 SlaveAddr,u8 readAddr,u8* pBuffer,u16 NumByteToRead){ //I2C读取数据串(器件地址,寄存器,内部地址,数量)while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1,ENABLE);//开启信号while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));	//清除 EV5I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Transmitter); //写入器件地址while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//清除 EV6I2C_Cmd(I2C1,ENABLE);I2C_SendData(I2C1,readAddr); //发送读的地址while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //清除 EV8I2C_GenerateSTART(I2C1,ENABLE); //开启信号while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); //清除 EV5I2C_Send7bitAddress(I2C1,SlaveAddr,I2C_Direction_Receiver); //将器件地址传出,主机为读while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); //清除EV6while(NumByteToRead){if(NumByteToRead == 1){ //只剩下最后一个数据时进入 if 语句I2C_AcknowledgeConfig(I2C1,DISABLE); //最后有一个数据时关闭应答位I2C_GenerateSTOP(I2C1,ENABLE);	//最后一个数据时使能停止位}if(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){ //读取数据*pBuffer = I2C_ReceiveData(I2C1);//调用库函数将数据取出到 pBufferpBuffer++; //指针移位NumByteToRead--; //字节数减 1 }}I2C_AcknowledgeConfig(I2C1,ENABLE);
}
u8 I2C_READ_BYTE(u8 SlaveAddr,u8 readAddr){ //I2C读取一个字节u8 a;while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1,ENABLE);while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_Cmd(I2C1,ENABLE);I2C_SendData(I2C1,readAddr);while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTART(I2C1,ENABLE);while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Receiver);while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));I2C_AcknowledgeConfig(I2C1,DISABLE); //最后有一个数据时关闭应答位I2C_GenerateSTOP(I2C1,ENABLE);	//最后一个数据时使能停止位a = I2C_ReceiveData(I2C1);return a;
}

PS:因为总线的线与特性,SCL和SDA都要设置为开漏输出

http://www.hrbkazy.com/news/9035.html

相关文章:

  • wpsppt网站链接怎么做如何建网站详细步骤
  • 建设一个网站平台要多少钱网络营销工具平台
  • 网站的用途企业网站设计
  • 网站建设站点如何让网站快速收录
  • 高端网站制作的公司社交媒体营销三种方式
  • 网站seo啥意思怎么做网络营销推广平台
  • 外包网络推广公司怎么选谷歌seo优化技巧
  • 哪些网站可以做百科参考资料湛江今日头条
  • 做绿化生意有什么网站口碑营销推广
  • 做seo网站要多少钱seo对网络推广的作用是什么?
  • 做服装加工哪个网站比较好百度指数代表什么
  • wordpress悬浮窗杭州seo网站推广
  • 湛江定制建站seo专业培训机构
  • 只做乡村旅游的网站电子商务与网络营销题库
  • 微信网站应用开发个人网站怎么做
  • 兰州公司网站制作免费的网站推广软件
  • 精准客源 获客哪里有网站推广优化
  • 福田做网站的成都seo招聘
  • 一个最简单的产品展示的asp网站应该如何做免费的拓客平台有哪些
  • 潍坊公司网站制作网站页面优化内容包括哪些
  • 做网站公司不给源码建设网站前的市场分析
  • 外贸网站建设收益西安网站公司推广
  • 自己怎么用h5做网站b站推广引流最佳方法
  • 可以注销的网站百度搜索风云榜
  • 嘉兴网站制作星讯网络科技百度青岛代理公司
  • 网站如何做关键词seo火蝠电商代运营公司
  • 做网站可以申请专利吗网站seo推广员招聘
  • 购物网站的功能板块it学校培训学校哪个好
  • 企业品牌网站建设怎么做百度seoo优化软件
  • 移动端低代码开发平台网站快速排名优化报价