首页 > 其他分享 >IIC工作模式时序分析

IIC工作模式时序分析

时间:2024-09-10 19:47:57浏览次数:1  
标签:SCL SET void 模式 时序 SDA IIC GPIO

IIC工作模式时序分析

此处利用IO口模拟IIC通信过程中的时序。
image

通信过程

在IIC通信过程SDA存在两种模式(接收模式和发送模式),发送或接受一个字节(器件的7个bit+1个bit方向(1 - 读方向,0 - 写方向))

模式配置

  1. 当SDA为接入模式接收了1字节数据后在第九个时钟脉冲期间就要变成输出模式发送ask
  2. 当SDA为输出模式发送了1字节数据后在第九个时钟脉冲期间就要变成输入模式检测是否收到ask
  3. 因此SDA需配置两个模式而SCL模拟时序只需配置输出模式
#define  SDA_SET(n)  (n) ? GPIO_SetBits(GPIO?,GPIO_Pin_?) : GPIO_ResetBits(GPIO?,GPIO_Pin_?) 
#define  SCL_SET(n)  (n) ? GPIO_SetBits(GPIO?,GPIO_Pin_?) : GPIO_ResetBits(GPIO?,GPIO_Pin_?) 
#define  SDA_READ    GPIO_ReadInputDataBit(GPIO?,GPIO_Pin_?)

IIC的SCL配置

/**
  * @name:	IIC_SCLConfig
  * @brief  	IIC的SCL配置
  * @param  	void
  * @retval 	void
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
void IIC_SCLConfig()
{
    GPIO_InitTypeDef GPIO_InitStructure;

	//打开GPIO端口的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO?,ENABLE);

	//SCL
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_OUT;					//输出模式
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType 	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  	= GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_?;
	GPIO_Init(GPIO?, &GPIO_InitStructure);
}

IIC的SDA配置

/**
  * @name:	IIC_SDAConfig
  * @brief  	IIC的SCL配置
  * @param  	
		@GPIO_Mode
  * @retval 	void
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
void IIC_SDAConfig(GPIOMode_TypeDef GPIO_Mode)
{
    GPIO_InitTypeDef GPIO_InitStructure;

	//打开GPIO端口的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO?,ENABLE);

	//SCL
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode;					//输出模式
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType 	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  	= GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_?;
	GPIO_Init(GPIO?, &GPIO_InitStructure);
}

IIC的空闲状态

image

/**
  * @name:	IIC_Config
  * @brief  	IIC的初始化
  * @param  	
		@GPIO_Mode
  * @retval 	void
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
void IIC_Config(void)
{
    //1.设置SDA和SCL为输出模式
    IIC_SCLConfig();
    IIC_SDAConfig(GPIO_Mode_OUT);

    //2.确保SDA和SCL处于空闲状态
    SDA_SET(1);
    SCL_SET(1);
    delay_us(5);
}

IIC的开始信号

image

/**
  * @name:	IIC_Start
  * @brief  	IIC的开始信号
  * @param  	void
  * @retval 	void
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
void IIC_Start(void)
{
    //1.设置SDA为输出模式
    IIC_SDAConfig(GPIO_Mode_OUT);

    //2.确保SDA和SCL处于空闲状态
    SDA_SET(1);
    SCL_SET(1);
    delay_us(5);

    //3.设置SDA为低电平
    SDA_SET(0);
    delay_us(5);
}

IIC的发送字节

image

/**
  * @name:	IIC_SendByte
  * @brief  	IIC的发送字节
  * @param  	
		@Byte
  * @retval 	void
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
void IIC_SendByte(uint8_t Byte)   //1011 0110
{
     //1.设置SDA为输出模式
    IIC_SDAConfig(GPIO_Mode_OUT);

    //2.设置SDA为低电平,SCL为低电平
    SDA_SET(0);
    delay_us(5);
    SCL_SET(0);
    delay_us(5);

    //2.循环发送8次,每次发送一个bit  遵循MSB 高位先出
    for(int i=0;i<8;i++)
    {
        SDA_SET(1);
        delay_us(5);
        //3.判断待发送的字节的最高位  ???? ???? & 1000 0000
        if( Byte & 0x80 )
        {
            SDA_SET(1);
        }
        else
            SDA_SET(0);

        Byte <<= 1;
        delay_us(5);

        SDA_SET(0);
        delay_us(5);
    }
}

IIC的接收字节

image

/**
  * @name:	IIC_RecvByte
  * @brief  	IIC的接受字节
  * @param  	void
  * @retval 	uint8_t 
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
uint8_t IIC_RecvByte(void)
{
	uint8_t i=0;
	uint8_t data =0;

	//保证SDA引脚为输入模式
	IIC_SDAConfig(GPIO_Mode_IN);

	SCL_SET(0);
	delay_us(5);


	for(i=0;i<8;i++)
	{
		//时钟线拉高,数据有效
		SCL_SET(1);
		delay_us(5);

		data <<=1;
		data |= SDA_READ;
		delay_us(5);


		//时钟线拉低,保持占用总线,总线是忙状态
		SCL_SET(0);
		delay_us(5);

	}
}

IIC的判断从机是否应答

image

/**
  * @name:	IIC_IsSlaveACK
  * @brief  	IIC的判断从机是否应答
  * @param  	void
  * @retval 	bool
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
bool  IIC_IsSlaveACK(void)
{
	bool ack;

	//1.设置SDA引脚为输入模式
	IIC_SDAConfig(GPIO_Mode_IN);

	//3.把SCL引脚电平拉高,此时为第9个脉冲的高电平,主机读取状态
	SCL_SET(1);
	delay_us(5);

	//4.主机读取状态  1 表示未应答  0  表示已应答
	if(SDA_READ)
		ack = false;
	else
		ack = true;

	//5.把SCL引脚电平拉低
	SCL_SET(0);
	delay_us(5);

	return ack;
}

IIC的收到从机数据发送应答

image

/**
  * @name:	IIC_MasterACK
  * @brief  	IIC的收到从机数据发送应答
  * @param  	void
  * @retval 	void
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
void IIC_MasterACK(void) 
{
   	 // 1.设置SDA引脚为输出模式
    	IIC_SDAConfig(GPIO_Mode_OUT);

 	// 2.把SCL引脚电平拉低,此时主机准备
  	SCL_SET(0);
  	delay_us(5);

	// 3.设置SDA为高电平,表示应答
       	SDA_SET(1);
       	delay_us(5);

    	// 4.把SCL电平拉高,此时从机读取bit
    	SCL_SET(1);
    	delay_us(5);
}

IIC的停止信号

image

/**
  * @name:	IIC_Stop
  * @brief  	IIC的停止信号
  * @param  	void
  * @retval 	void
  * @date 	2024/09/10
  * @note   	补充 注意 说明
  */
void IIC_Stop(void)
{
	//1.设置SDA引脚为输出模式
	IIC_SDAConfig(GPIO_Mode_OUT);

	//2.设置SDA和SCL均为低电平
	SDA_SET(0);
	SCL_SET(0);
	delay_us(5);

	//3.把SCL电平拉高
	SCL_SET(1);
	delay_us(5);

	//4.把SDA电平拉高
	SDA_SET(1);
	delay_us(5);

}

标签:SCL,SET,void,模式,时序,SDA,IIC,GPIO
From: https://www.cnblogs.com/lu-ciana/p/18407041

相关文章

  • Java 设计模式-状态模式
    目录一.概述二.主要角色三.代码示例四.优缺点优点:缺点:五.常见应用场景一.概述        状态模式是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。对象看起来好像修改了它的类。状态模式把所有的与一个特定的状态相关的行为放到一个类......
  • Java 设计模式-代理模式
    目录概述一.什么是代理模式1.举例说明二.代理模式作用1.保护代理2.增强功能3.代理交互4.远程代理:三.代理模式3个角色四.静态代理1.代码示例:五.JDK动态代理1.代码示例:六.CGLIB动态代理1.代码示例 七.JDK动态代理和CGLIB动态代理区别八.两种在......
  • [设计模式] Cola-StateMachine : 一个轻量实用的Java状态机框架
    1概述:状态机1.0状态机vs工作流在介绍状态机之前,先介绍一个工作流(WorkFlow),初学者通常容易将两个概念混淆。工作流(WorkFlow),大体是指业务过程(整体或者部分)在计算机应用环境下的自动化,是对工作流程及其各操作步骤之间业务规则的描述。在计算机系统中,工作流属于计算机支持的......
  • Activity启动模式
    Activity启动模式1.Activity启动模式介绍1.1任务栈在Android开发中,任务栈(TaskStack)是一个非常重要的概念,主要用于管理应用程序中的Activity及其启动模式。它帮助开发者了解当用户在不同应用之间切换,或者应用内部不同Activity之间跳转时,系统如何管理这些Activity的生命周期与......
  • NS4263 3.0Wx2 双声道 AB/D 类双模音频功率放大器附加耳机模式
    1特性●工作电压范围:3.0V-5.25V●AB类和D类工作模式切换●一线脉冲控制工作模式与关断模式●内置立体声耳机输出功能●输出功率3W@ClassD/Load=4ohm●THD+N=0.1%@VDD=5V/Po=1W●优异的全带宽EMI抑制能力●优异的“上电和掉电”噪声抑制●内置过流保护......
  • laravel 策略模式、工厂模式使用案例
    laravel策略模式、工厂模式使用案例在Laravel中使用设计模式来对接多个物流服务商(如菜鸟、顺丰、极兔),可以使用策略模式或工厂模式来实现动态调用不同物流接口的功能。下面的示例展示了如何使用策略模式来实现这个需求,通过一个父类,多个子类来处理不同的物流服务商,并根据单......
  • 单例模式解析
    1.什么是单例模式一种常用的软件设计模式,它确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。2.单例模式存在原因(1)确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。(2)用于控制资源访问、管理共享资源(如配置文件、数据库连接等)或实现一个全局服务......
  • python装饰器模式实现切面功能
    引言在软件开发中,我们经常会遇到一些横切关注点(cross-cuttingconcerns),如日志记录、事务管理、安全性检查等,这些关注点通常会跨越多个模块。传统的编程方式会导致代码的重复和分散,难以维护。面向切面编程(AOP)是一种编程范式,它通过提供一种新的方式来模块化横切关注点,从而提高代码......
  • RapidJSON 的坑--允许Object对象存在相同的key,且key为数字时序列化报异常
    RapidJSON的坑--允许Object对象存在相同的key,且key为数字时序列化报异常测试代码如下:1voidshow(rapidjson::Document&doc)2{3printf("-----------------foriterator\nMemberCount:%d\n",doc.MemberCount());4for(autoit=doc.MemberBegin();it!=doc......
  • TimesNet - 时序升维卷积任务通用模型 论文笔记 ICLR2023
    论文信息标题:Timesnet:Temporal2d-variationmodelingforgeneraltimeseriesanalysis作者:HaixuWu,TenggeHu,YongLiu,HangZhou,JianminWang,MingshengLong代码:https://github.com/thuml/TimesNet[原仓库,代码已迁移到TSLib]https://github.com/thuml/Time-Ser......