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

STM32——I2C通讯(软件模拟)

I2C概念

I2C:Inter-Integrated Circuit(内部集成电路)

Philps公司80年代初期开发的,引脚少,硬件实现简单,可扩展性广泛地使用在系统内多个集成电路(IC)间的低速通讯

简单的双向两线制总线协议标准,支持同步串行半双工通讯。

标准模式传输速率为100kbit/s,快速模式为400kbit/s,高速模式下可达3.4Mbit/s,目前大多I2C设备尚不支持高速模式。 

物理层

SCL:串行时钟总线,用于数据收发同步
SDA:串行数据总线,用高低电平表示数据
可连接多个IC通讯设备,支持一主多从也支持多主多从
每个设备都有唯一的地址,主机通过这个地址与从机通信
总线通过上拉电阻接到电源。设备空闲时,输出高阻态,当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平

协议层

位传输            作为串行通信,是按照位进行传输,一般是高位先行
起始信号        当SCL是高电平时,SDA线从高电平向低电平切换
停止信号        当SCL是高电平时,SDA线从低电平向高电平切换

//头文件定义
#define IIC_SCL(x)        do{ x ? \HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, GPIO_PIN_RESET); \}while(0)       /* SCL */#define IIC_SDA(x)        do{ x ? \HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, GPIO_PIN_RESET); \}while(0)       /* SDA */#define IIC_READ_SDA     HAL_GPIO_ReadPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) /* 读取SDA */

//起始信号
void iic_start(void)
{
/* SCL为高电平期间,SDA从高电平往低电平跳变*/
IIC_SDA(1);
IIC_SCL(1);
iic_delay();
IIC_SDA(0);
iic_delay();
IIC_SCL(0);
iic_delay();/*钳住总线,准备发送/接收数据
}//结束信号
void iic_stop (void)
/* SCL为高电平期间,SDA从低电平往高电平跳变*/
IIC_SDA(0);
iic_delay();
IIC_SCL(1);
iic_delay();
IIC_SDA(1);/*发送总线停止信号*/
iic_delay();
}

传输地址        主机通过SDA信号线发送设备地址(SLAVE_ADDRESS)来查找从机
                        PC协议规定设备地址可以是7位或10位,实际中7位的地址应用比较广泛。
                        紧跟设备地址的一个数据位用来表示数据传输方向,它是数据方向位(R/W),第                          8位或第11位
                        数据方向位为"1"时表示主机由从机读数据,该位为"0"时表示主机向从机写数据

 数据的有效性
SDA高或低电平状态只有在SCL时钟信号是低电平时才能改变
SDA线上的数据必须在时钟的高电平周期保持稳定

//发送一个字节
void iic_send_byte (uint8_t data)
{for(uint8_t t = 0; t < 8; t++){/*高位先发*\IIC_SDA((data &0x80)>> 7);iic_delay();IIC_SCL(1);iic_delay();IIC_SCL(0);data<<=1;/* 左移1位用于下一次发送}IIC_SDA(1);/*发送完成,主机释放SDA线*
}//读取一个字节数据
uint8_t iic_read_byte(uint8_t ack) /* 1:ack 0:nack*/
{uint8_t receive = 0;for(uint8_t t = 0; t < 8; t++){/*高位先输出,先收到的数据位要左移*receive <<= 1;IIC_SCL(1);iic_delay();if(IIC_READ_SDA) receive++;IIC_SCL(0);iic_delay();}if(!ack) iic_nack();else iic_ack() ;return receive;
}

响应

接收方接收到数据后,有两种响应

1.应答响应。给发送方一个低电平

2.非应答响应。给发送方一个高电平

//等待应答
uint8_t iic_wait_ack<(void))/* return 1:fail 0:succeed*/
{IIC_SDA(1);/*主机释放SDA线*iic_delay();IIC_SCL(1);/*从机返回ACK*/iic_delay();if(IIC_READ_SDA)/* SCL高电平读取SDA状态*/{iic_stop();/*SDA高电平表示从机nack*/return 1;}IIC_SCL(0);/*SCL低电平表示结束ACK检查*/iic_delay();return 0;
}//发送应答
void iic_ack(void)
{IIC_SCL(0)iic_delay();IIC_SDA(0);/*数据线为低电平,表示应答iic_delay();IIC_SCL(1);iic_delay();
}//发送非应答
void iic_ack(void)
{IIC_SCL(0)iic_delay();IIC_SDA(1);/*数据线为高电平,表示非应答iic_delay();IIC_SCL(1);iic_delay();
}


http://www.mrgr.cn/news/97826.html

相关文章:

  • 探秘 Svelte+Vite+TS+Melt - UI 框架搭建,开启高效开发
  • PostgreSQL-数据库的索引 pg_operator_oid_index 损坏
  • SpringBoot 整合 MCP
  • JS 箭头函数
  • 【设计模式】面向对象开发学习OOPC
  • Apache Nifi安装与尝试
  • 研究嵌入式软件架构时遇到的初始化堆栈溢出问题
  • 3 版本控制:GitLab、Jenkins 工作流及分支开发模式实践
  • LeetCode Hot100 刷题笔记(2)—— 子串、普通数组、矩阵
  • 【回眸】Linux 内核 (十六) 之 多线程编程 下
  • 中间件-消息队列
  • C# 设置Excel中文本的对齐方式、换行、和旋转
  • 【HTML】纯前端网页小游戏-戳破彩泡
  • IDEA :物联网ThingsBoard-gateway配置,运行Python版本,连接thingsboard,接入 MQTT 设备
  • 以普通用户身份启动pure-ftpd服务端
  • js chrome 插件,下载微博视频
  • 蓝桥杯备赛学习笔记:高频考点与真题预测(C++/Java/python版)
  • 开源的7B参数OCR视觉大模型:RolmOCR
  • 【论文精读】Multi-scale Neighbourhood Feature Interaction Network
  • windows使用cmake安装openvdb-12.0.0库