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

STM32 IIC详解(软件模拟)

目录

一、IIC协议基本原理

1.IIC协议概述

2.时序图分析

二、代码分析

1.IIC初始化

2.IIC起始信号

3.IIC发送数据

4.获取应答信号

5.读一个字节

6.产生ACK应答

7.不产生ACK应答


IIC(Inter-Integrated Circuit)在嵌入式系统中是一种常见的数据通信接口,日常工作中许多传感器都是基于IIC来传输数据的,所以掌握这个接口对我们来说非常重要。

一、IIC协议基本原理

1.IIC协议概述

IIC也被称为I2C和I²C,硬件方面由于存在专利,所以日常中我们常以两个IO口用软件模拟IIC来使用。IIC串行总线有两根信号线:数据线SDA和时钟线SCL。IIC总线上的设备通过地址进行区分,不同种类的设备地址不同。只要不超过IIC总线上的电容限制(一般不超过400pf),就可以连接任意数量的从机,在通信时刻,只能有一个作为主机,其他的都为从机。高速IIC总线一般可达400kbps以上。

2.时序图分析

SCL为时钟线,SDA为数据线,SCL和SDA默认都是高电平,两条线相互配合会产生三种信号构成时序。

开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变。
结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变。
应答信号:接收数据的设备在接收到 8位 数据后,向发送数据的设备发出特定的低电平,表示已收到数据。主机设备向从机设备发出一个信号后,等待从机设备发出一个应答信号,主机设备接收到应答信号后,根据实际情况作出是否继续传递信号。若未收到应答信号,由判断为受控单元出现故障。

IIC在开始信号发出后开始发送数据,数据以8位传输,SCL高电平的时候SDA读到的数据有效,然后经历8位数据传输以后,第九次检测应答信号,如果检测到从机将SDA置为低电平,说明从机设备有应答(ACK),如果保持高电平,说明从机设备没有应答(NACK)。

二、代码分析

本文基于STM32F429的HAL库为例讲解IIC的使用,定义宏参数如下图所示

1.IIC初始化

void IIC_Init(void)
{GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOH_CLK_ENABLE();   //使能GPIOH时钟//PH4,5初始化设置GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5;GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出GPIO_Initure.Pull=GPIO_PULLUP;          //上拉GPIO_Initure.Speed=GPIO_SPEED_FAST;     //快速HAL_GPIO_Init(GPIOH,&GPIO_Initure);IIC_SDA=1;IIC_SCL=1;  
}

初始化IIC,使能PH4,PH5推挽输出、上拉、快速,然后又将SDA和SCL拉高。

2.IIC起始信号

void IIC_Start(void)
{SDA_OUT();     //sda线输出IIC_SDA=1;	  	  IIC_SCL=1;delay_us(4);IIC_SDA=0;//拉低电平delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  

在SDA和SCL高电平的同时,将SDA拉低产生一个下降沿。

3.IIC发送数据

void IIC_Send_Byte(u8 txd)
{                        u8 t;   SDA_OUT(); 	    IIC_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){              IIC_SDA=(txd&0x80)>>7;txd<<=1; 	  delay_us(2);IIC_SCL=1;delay_us(2); IIC_SCL=0;	delay_us(2);}	 
}

切换SDA为输出模式,拉低SCL电平,依次发送8位数据, 每次写好SDA位的时候,将SCL拉高后等待2us再拉低。

4.获取应答信号

//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN();      //SDA设置为输入  IIC_SDA=1;delay_us(1);	   IIC_SCL=1;delay_us(1);	 while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//时钟输出0 	   return 0;  
} 

将SDA设置为输入模式,将SDA和SCL拉高,如果SDA在规定时间内依然是拉高的状态,说明从机没有应答,反之则说明从机应答。

5.读一个字节

读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++;   delay_us(1); }					 if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK   return receive;
}

读取数据的时候,先将SDA设置成输入,然后依次拉低拉高SCL 8次,读取8位数据,如果还想继续读取,就产生ACK应答,如果不想继续读取了,就产生nACK应答。

6.产生ACK应答

void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}

先将SCL拉低,然后改SDA为输出模式,拉低SDA后拉高SCL后再拉低。

7.不产生ACK应答

//不产生ACK应答		    
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}		

先将SCL拉低,然后改SDA为输出模式,拉高SDA后拉高SCL后再拉低,就可以告诉从机不再继续读取数据。

总体来说,IIC的通讯只用到了SCL(时钟线)和SDA(数据线)两条线,实现起来还是比较简单的,希望本文能帮助你理解IIC如何使用。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【GameFramework扩展应用】6-1、接入热更新框架HybridCLR
  • 服务器,云、边缘计算概念简单理解
  • 爬虫管理解决方案:让数据收集变得高效且合规
  • Redis基础教程(十五):Redis GEO地理信息查询与管理
  • 使用Apache Beam进行统一批处理与流处理
  • 【卡尔曼滤波器】DR_CAN :1_递归算法_做估计 学习笔记
  • 人脸检测+调整分辨率+调整帧率
  • 【HBZ分享】如何规避TCP的洪水攻击
  • LangChain 入门案例教程
  • github 下载提速的几种方法
  • 仕考网:公务员考试面试时间一般多长?
  • 利用Python进行数据分析PDF下载经典数据分享推荐
  • C 语言中如何实现图结构?
  • SpringBoot新手快速入门系列教程十:基于Docker Compose,部署一个简单的项目
  • 每天一个数据分析题(四百十六)- 线性回归模型
  • 《Java编程思想》读书笔记-对象导论
  • Bootstrap JS插件Alert源码分析
  • HTTP请求重发
  • Mithril.js 入门介绍
  • Python socket服务器端、客户端传送信息
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • SpringCloud集成分布式事务LCN (一)
  • XML已死 ?
  • 闭包--闭包之tab栏切换(四)
  • 分类模型——Logistics Regression
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • ######## golang各章节终篇索引 ########
  • #HarmonyOS:Web组件的使用
  • #includecmath
  • (13):Silverlight 2 数据与通信之WebRequest
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (第一天)包装对象、作用域、创建对象
  • (二)JAVA使用POI操作excel
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (离散数学)逻辑连接词
  • (六)激光线扫描-三维重建
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (十)T检验-第一部分
  • (数据大屏)(Hadoop)基于SSM框架的学院校友管理系统的设计与实现+文档
  • (贪心) LeetCode 45. 跳跃游戏 II
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)项目管理杂谈-我所期望的新人
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .Net OpenCVSharp生成灰度图和二值图
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .NET 读取 JSON格式的数据
  • .net 发送邮件
  • .Net接口调试与案例
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • /etc/sudoers (root权限管理)
  • @EnableAsync和@Async开始异步任务支持
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]
  • [AIGC] Redis基础命令集详细介绍
  • [Android Studio 权威教程]断点调试和高级调试