GPIO引脚 模拟 IIC(软件IIC)

2023-05-16

GPIO引脚 模拟 IIC(软件IIC)

IIC总线在传输数据的过程中一共有三种类型信号,分别为:开始信号、结束信号和应答信号。
IIC总线的时序图:
在这里插入图片描述

空闲状态
当IIC总线的数据线SDA和时钟线SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

起始信号与停止信号
起始信号:当时钟线SCL为高期间,数据线SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号;
停止信号:当时钟线SCL为高期间,数据线SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
在这里插入图片描述

应答信号
发送器每发送一个字节(8个bit),就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。

应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节;
应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

对于反馈有效应答位ACK的要求是:接收器在第9个时钟脉冲之前的低电平期间将数据线SDA拉低,并且确保在该时钟的高电平期间为稳定的低电平。 如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放数据线SDA,以便主控接收器发送一个停止信号P。

数据有效性
IIC总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定;只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

即:数据在时钟线SCL的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。
在这里插入图片描述

数据的传达
在IIC总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。

以下是具体的代码

static void sda_mode(uint8_t mode)   ///设置输入或者输出
{
	stc_gpio_cfg_t GPIO_Init;
	
	//使能gpio的时钟门
	Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
	
	//输入/输出
	GPIO_Init.enDir = mode;
	GPIO_Init.enOD = GpioOdEnable;                          ///< 开漏输出
	//上拉或者下拉
	GPIO_Init.enPu = GpioPuEnable;
	GPIO_Init.enPd = GpioPdDisable;
	
	Gpio_Init(GpioPortA,GpioPin12,&GPIO_Init);
	
}


void Iic_Start(void)
{
	sda_mode(GPIO_Mode_OUT);	//SDA设置为输出模式
	
	//空闲
	SCL=1;		//SCL脚拉高
	SDA_H;		//SDA脚拉低
	delay10us(1);
	
	SDA_L;		//SDA脚拉低
	delay10us(1);

	//钳住总线 
	SCL=0;		//SCL拉低
}

void Iic_Stop(void)
{
	sda_mode(GPIO_Mode_OUT);//SDA设置为输出模式
	SCL=0;
	SDA_L;
	
	delay10us(1);
	SCL=1;
	
	delay10us(1);
	
	SDA_H;  //总线空闲
}

//等待从机应答信号 1:无效应答 0:有效应答
uint8_t Iic_Wait_Ack(void)
{
	uint8_t ack = 0;
	sda_mode(GPIO_Mode_IN);		//SDA设置为输入模式
	
	SCL=0;
	delay10us(1);
	
	SCL=1;
	
	if(SDA_IN)
	{
		ack = 1;  //无效应答
	}
	else
	{
		ack = 0;  //有效应答
	}
	delay10us(1);
	SCL=0;

	return ack;
}

//编写代码主机发送一位数据 0 或 1
//发送应答信号 0有效应答  1无效应答
void Iic_Send_Ack(uint8_t ack)
{
	sda_mode(GPIO_Mode_OUT);
	
	SCL=0;
	
	if(ack == 1)
	{
		SDA_H;
	}
	if(ack == 0)
	{
		SDA_L;
	}
	
	delay10us(1);
	
	SCL=1;
	delay10us(1);
	SCL=0;
	

}

void Iic_Send_Byte(uint8_t txd)
{
	uint8_t i;
	sda_mode(GPIO_Mode_OUT);

	SCL=0;
	
	for(i=0; i<8; i++)
	{
		//从高往低取出每一位数据
		if(txd & (1<<(7-i)))
		{
			SDA_H;
		}
		else
		{
			SDA_L;
		}
	
		delay10us(1);
		SCL=1;
		delay10us(1);
		SCL=0;
	
	}
	
	
}

uint8_t Iic_Read_Byte()
{
	uint8_t i;
	uint8_t date=0;
	sda_mode(GPIO_Mode_IN);


	
	for(i=0; i<8; i++)
	{
		SCL=1;
		delay10us(1);
		
		
		if(SDA_IN==1)
		{
			date+=1;
		}
		if(i!=7)
			date=date << 1;
		

		
		SCL=0;
		delay10us(1);

	
	}
	return date;
	
	
}

void Write_Bytes(uint8_t addr, uint8_t data)
{
	uint8_t ack;
	//开始信号 
	Iic_Start();
	
	//发送写设备地址
	Iic_Send_Byte(I2C_WADDR);
	ack=Iic_Wait_Ack();
	if(ack == 1)
	{
		return ;
	}
	
	//发送写数据的地址
	Iic_Send_Byte(addr);
	ack=Iic_Wait_Ack();
	if(ack == 1)
	{
		return ;
	}	
	
	delay10us(1);
	Iic_Send_Byte(data);
	ack=Iic_Wait_Ack();
	if(ack == 1)
	{
		return ;
	}
	
	Iic_Stop();

}

void Read_Bytes(uint8_t addr, uint8_t *read_buff,uint8_t len)
{
	uint8_t ack;
	uint8_t i=0;
	
	//开始信号 
	Iic_Start();
	
	//发送写设备地址
	Iic_Send_Byte(I2C_WADDR);
	ack=Iic_Wait_Ack();
	if(ack == 1)
	{
		return ;
	}
	
	//发送读数据的地址
	Iic_Send_Byte(addr);
	ack=Iic_Wait_Ack();
	if(ack == 1)
	{
		return ;
	}

	//开始信号 
	Iic_Start();
	
	//发送读设备地址
	Iic_Send_Byte(I2C_RADDR);
	ack=Iic_Wait_Ack();
	if(ack == 1)
	{
		return ;
	}
	while(len--)
	{
		read_buff[i++]=Iic_Read_Byte();
		if(len==0)
		{
			Iic_Send_Ack(1);
		}
		else 
		{
			Iic_Send_Ack(0);
		}
	}

	Iic_Stop();
	
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GPIO引脚 模拟 IIC(软件IIC) 的相关文章

  • 【STM32】GPIO_InitTypeDef GPIO_InitStructure;语句的理解

    这句话声明一个结构体 xff0c 名字是GPIO InitStructure xff0c 结构体原型由GPIO InitTypeDef 确定 xff0c 在stm32中用来初始化GPIO 设置完GPIO InitStructure里面的内容
  • UART、IIC、SPI、CAN通信的区别与应用

    文章目录 1 通信的基本知识1 1 数据通信的种类1 1 1 串行通信1 1 2 并行通信1 1 3 总结 1 2 数据通信的传输方向1 2 1 单工1 2 2 半双工1 2 3 全双工1 2 4 总结 1 3 数据通信的方式1 3 1 同
  • GD32VF103之GPIO最小配置

    longan nano是Sipeed xff08 矽速科技 xff09 推出的开发板 xff0c 使用兆易创新的gd32vf103cbt6芯片 xff0c 该芯片是基于芯来科技的Nuclei Bumblebee处理器的32位通用微控制器 x
  • GPIO模式

    开漏输出 只能输出低电平 xff0c 不能输出高电
  • 树莓派GPIO

    命令行执行下行 xff0c 即可得树莓派管脚编码表 gpio readall 也可看下图 xff1a BOARD 编号参考 Raspberry Pi 主板上 P1 接线柱的针脚编号 使用该方式的优点是无需考虑主板的修订版本 xff0c 无需
  • void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)的一些理解

    GPIO TypeDef GPIOA BASE 表示将GPIOA BASE强制转换为指针类型的结构体 xff0c define GPIOA GPIO TypeDef GPIOA BASE 表示用 GPIO TypeDef GPIOA BAS
  • 【STM32学习】(二)CubeMX基于HAL库GPIO输出/输入

    本文主要记录下初学cubeMX进行HAL库配置 单片机 xff1a STM32F407ZGT6 一 新建工程 打开CubeMX xff0c Access To MCU SELETOR 二 配置CubeMX 1 设置Debug方式 因为我用的
  • STM32标准库通用软件模拟IIC

    STM32标准库通用软件模拟IIC 继上次通用可移植的矩阵键盘之后 xff0c 便继续寻找着下一个能够拿来只需改改引脚就可以使用的通用方案 恰好最近在研究PCA9685 xff0c 这是一片能够产生最多十六路PWM信号的芯片 xff0c 通
  • 12.RTT-IIC设备-AHT10温湿度传感器

    本系列博客更新结束啦 xff01 完结啦 xff01 xff01 xff01 撒花 xff01 xff01 xff01 关于RTT的设备和驱动专题更新完毕啦 xff0c 本期是最后一期 一段学习旅途的结束意味着下一段学习冒险的开始 虽然本系
  • I2C总线时序以及ACK和NACK(NAK),SCL被从机拉低?

    1 I2C协议详解及裸机程序分析 简书 通俗易懂 根据上图 我们首先设置IICCON 来设置时钟 时钟源是PCLK 是50MHZ 太快了我们需要设置这个分频系数 把时钟降低 降低到我们想要的SCL 然后我们要发出start信号 我们需要设置
  • Arduino通过继电器控制电机(5V小马达)ESP8266-12F同理(小白初学)

    用Arduino ESP8266 12F控制电机 一 实验环境 IDE Arduino 材料 Arduino UNO ESP82266 12F 4 5V电池盒子 继电器 6脚 5V电机一个 5V小马达 面包板 杜邦线若干 二 接法 参照37
  • 新唐NUC980使用记录(5.10.y内核):在用户应用中使用GPIO

    文章目录 目的 使用参考与演示 使用参考 存在的问题 问题定位 修改设备树 使用测试 总结 设备树文件内容 目的 GPIO是最基础的外设 使用频率也非常高 这篇文章将简单体验在NUC980 Liunx用户应用中使用GPIO功能 这篇文章中内
  • Linux的GPIO子系统解析 ( 一 ) 之 gpiolib.c

    文章目录 Linux的GPIO子系统解析 一 之 gpiolib c 绪论 关于GPIO子系统库文件的gpiolib c解析 drivers gpio gpiolib c gpio desc结构体 gpio chip结构体 gpio ens
  • GPIO模拟脉冲驱动步进电机

    引脚 PUL lt gt VCC 3 3v PUL lt gt PA6 DIR lt gt VCC 3 3v DIR lt gt PB12 ENA lt gt VCC 3 3v ENA lt gt PB15 按键 控制使能 PE6 控制方向
  • STM32 IIC通信干货!理论+实例

    I2C总线简介 I2C总线介绍 I2C Inter Integrated Circuit 总线 也称IIC或I2C 是由PHILIPS公司开发的两线式串行总线 用于连接微控制器及其外围设备 是微电子通信控制领域广泛采用的一种总线标准 它是同
  • I2C与SPI通信总线协议

    仅以寄存器地址为8Bit的器件为例 例如MPU6500 LSM6DS3 I2C通信协议 I2C 的要点是了解I2C通信帧的组成部分 START起始位 STOP停止位 ACK NACK信号 从机器件地址 从机寄存器地址 I2C读的时序比较繁琐
  • Raspberry Pi RuntimeError:已为此 GPIO 通道启用冲突边缘检测

    我正在遵循此处找到的教程 https www linkedin com pulse prepare your raspberry pi work aws iot kay lerch I have not even begun the int
  • linux GPIO C API

    我有一个 powerpc 板 上面运行着 3 2 内核 使用 sysfs 访问 GPIO 按预期工作 例如 gt echo 242 gt sys class gpio export gt cat sys class gpio gpio242
  • mmap 比 ioremap 慢

    我正在为运行 Linux 2 6 37 的 ARM 设备进行开发 我正在尝试尽快切换 IO 引脚 我制作了一个小内核模块和一个用户空间应用程序 我尝试了两件事 使用以下命令直接从内核空间操作 GPIO 控制寄存器ioremap mmap G
  • 按下按钮时 GPIO 事件检测不给出输出

    以下 python 脚本应该等待按钮按下 打印按钮按下消息 然后退出 但是 当我按下按钮时 什么也没有打印 然后 当我按回车键时 脚本会打印 检测到按钮按下 然后停止 我如何修复此代码 以便在按下按钮时打印 检测到按钮按下 我按照教程制作了

随机推荐