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

南宁网站设涉县网站开发

南宁网站设,涉县网站开发,免费云电脑主机,男科是去私立还是公立目录 背景 I2C协议 数据的有效性 I2C通信开始和停止条件 I2C数据传输 发送 响应 正常情况#xff1a; 异常情况#xff1a; 主机结束接收 写寄存器的标准流程 读寄存器的标准流程 仲裁机制 时钟同步 SDA线的仲裁 程序 背景 对单片机的三大通信中的I2C通信进…目录 背景 I2C协议 数据的有效性 I2C通信开始和停止条件 I2C数据传输 发送 响应 正常情况 异常情况 主机结束接收 写寄存器的标准流程 读寄存器的标准流程 仲裁机制 时钟同步 SDA线的仲裁 程序 背景 对单片机的三大通信中的I2C通信进行说明。 I2C协议 协议采用双线结构传输数据包括一个数据线和一个时钟线即 SDA 和 SCL 线其中 SDASerial Data线用于双向数据传输而 SCLSerial 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 主机然后产生一个停止条件终止传输或者产生重复起始条件开始新的传输。 如果从机 接收器响应了从机地址但是在传输了一段时间后不能接收更多数据字节 主机必须再一次 终止传输 这个情况用从机在第一个字节后没有产生响应来表示 从机使数据线保持高电平 主机产生一 个停止或重复起始条件。 主机结束接收 如果传输中有主机作为接收者 它必须通过在 从机不产生时钟的 最后一个字节不产生一个响应向从机 发送器通知数据结束 从机 发送器必须释放数据线,允许主机产生一个停止或重复起始条件 写寄存器的标准流程 Master发起STARTMaster发送I2C addr7bit和w操作01bit等待ACKSlave发送ACKMaster发送reg addr8bit等待ACKSlave发送ACKMaster发送data8bit即要写入寄存器中的数据等待ACKSlave发送ACK第6步和第7步可以重复多次即顺序写多个寄存器Master发起STOP 读寄存器的标准流程 Master发送I2C addr7bit和w操作11bit等待ACKSlave发送ACKMaster发送reg addr8bit等待ACKSlave发送ACKMaster发起re -STARTMaster发送I2C addr7bit和r操作11bit等待ACKSlave发送ACKSlave发送data8bit即寄存器里的值Master发送ACK第8步和第9步可以重复多次即顺序读多个寄存器主机想结束接收时最后一个数据不再需要ACK应答,保持为高电平NACK。主机发出 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.hkea.cn/news/14271101/

相关文章:

  • 工艺礼品东莞网站建设南宁网站建设哪家公司实力强
  • 投融网站建设方案namecheap建站wordpress
  • php网站开发经理招聘淮安市哪里可以做网站
  • 做网站用备案吗肇庆企业建站模板
  • 阿里云做网站要几天金网科技有限公司
  • 2008 iis 配置 asp网站张家港专业做网站
  • 杭州网站建设商业深圳市公共资源交易中心官网
  • 买域名之后怎样做网站搜索引擎广告例子
  • 个人域名网站官网设计企业
  • 网站开发技术课程设计总结杭州大型网站建设
  • 做盗版视频网站吗页面设计公司
  • 网站模板html整站org域名做商业网站
  • 上海网站建设口碑最好的公司如何自学动漫设计
  • 营口网站优化发布软文是什么意思
  • 网站的ftp怎么查网站秒收录怎么做的
  • 企业网站建设方案范本网站色差表
  • wordpress 主题 名站正规招聘网站有哪些
  • wordpress免费网站南昌企业做网站设计
  • 机械设备东莞网站建设wordpress 内容可以是表格吗
  • 延吉市网站建设wordpress 多站点配置
  • 浙江平台网站建设制作网站做二级域名
  • 百度云网站建设教程wordpress链接数据库失败
  • 网站建设群标签好写什么宁波网站推广公司排名
  • 江苏网站建设网络公司免费域名cn
  • 怎样解析网站域名质量最好的购物平台
  • 产品类网站实创装饰官网
  • 宁波网站建设价格建筑工地招工
  • 加热器网站怎么做的wordpress边栏时间
  • 网站建设需要注册42类吗电商网站 收费与免费
  • 石家庄网站服务线上电商怎么做