14 STM32 - IIC (时序图+软件源码)

14.1 IIC简介

IIC(Inter-Integrated Circuit),中文集成电路总线,是一种串行通信总线,使用多主从架构。I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。主设备通过两个IO口便可以访问许多设备,因此可以节约IO口。IIC主从之间只有一根数据线,可以收数据,也可以发数据,但是不能同时收发,因此IIC属于半双工的通信模式。IIC硬件电路通常两根线接4.7K-10K电阻上拉到3.3V。结构如下图所示。
在这里插入图片描述

14.2 IIC时序

IIC两根线传输数据的信号分为开始信号,传输信号,应答信号,结束信号。
开始信号:SCL为高电平时,SDA由高向低跳变。
传输信号:SCL为高电平时,SDA的电平信号(整个SCL为高时,要确保SDA信号保持不变,只有SCL低电平时,SDA电平才能改变)。
应答信号:传输信号完成后,SDA在SCL低电平时输出高电平,然后修改为输入模式,待SCL为高时读取SDA电平,为高是否定应答信号,为低是肯定应答信号。
结束信号:SCL为高电平时,SDA由低向高跳变。
如下图,即完成一次8字节数据传输,发送的数据为:0xB2,(二进制: 10110110)
在这里插入图片描述

1: 开始信号;
2:数据改变,只有SCL为低时才能修改;
3-10:数据传输,数据为0xB2,(二进制: 10110110)
11:应答信号:高为从机确定收到数据,低为从机不确定收到数据
12: 结束信号

14.3 软件模拟源码:

#include "soft_iic.h"
#include "delay.h"//IO操作函数     
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA     
#define READ_SDA   PBin(7)  //输入SDA //IO方向设置
#define SDA_IN()  { GPIOB->MODER&=~(3<<(7*2));GPIOB->MODER|=0<<7*2; }  //PB7输入模式
#define SDA_OUT() { GPIOB->MODER&=~(3<<(7*2));GPIOB->MODER|=1<<7*2; }  //PB7输出模式//初始化IIC
void IICInit(void)
{GPIO_InitTypeDef  GPIO_InitStructure;//GPIOB8,B9初始化设置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   //普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;    //上拉GPIO_Init(GPIOB, &GPIO_InitStructure);          //初始化IIC_SCL=1;IIC_SDA=1;
}//产生IIC起始信号
static void IIC_Start(void)
{SDA_OUT();     //sda线输出IIC_SDA=1;IIC_SCL=1;DelayUs(4);IIC_SDA=0;    //START:when CLK is high,DATA change form high to low DelayUs(4);IIC_SCL=0;    //钳住I2C总线,准备发送或接收数据 
}//产生IIC停止信号
static void IIC_Stop(void)
{SDA_OUT();  //sda线输出IIC_SCL=0;IIC_SDA=0;  //STOP:when CLK is high DATA change form low to highDelayUs(4);IIC_SCL=1; IIC_SDA=1;  //发送I2C总线结束信号DelayUs(4);                                   
}//等待应答信号到来
//返回值:1,接收应答失败    0,接收应答成功
static u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN();      //SDA设置为输入  IIC_SDA=1;DelayUs(1);       IIC_SCL=1;DelayUs(1);     while(READ_SDA){ucErrTime++;if(ucErrTime>250) // 超时错误{IIC_Stop();return 1;}}IIC_SCL=0; //时钟输出0        return 0; // 有应答返回0
}//产生ACK应答
static void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;DelayUs(2);IIC_SCL=1;DelayUs(2);IIC_SCL=0;
}//不产生ACK应答            
static void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;DelayUs(2);IIC_SCL=1;DelayUs(2);IIC_SCL=0;
}static 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;DelayUs(2);   //对TEA5767这三个延时都是必须的IIC_SCL=1;DelayUs(2);IIC_SCL=0;DelayUs(2);}
}static u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; DelayUs(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++;DelayUs(1); }if (ack)IIC_Ack(); //发送ACK   elseIIC_NAck(); //发送nACKreturn receive;
}

直接调用以上API函数,可以读写24C02(EEPROM)。

// 读1字节内容
u8 W24C_ReadOneByte(u16 addr, u8* data)
{IIC_Start();IIC_Send_Byte(0xA0);if(1 == IIC_Wait_Ack()){return 1; // err}IIC_Send_Byte(addr>>8);if(1 == IIC_Wait_Ack()){return 2; // err}IIC_Send_Byte(addr&0x0FF);if(1 == IIC_Wait_Ack()){return 3; // err}IIC_Start();IIC_Send_Byte(0xA1);if(1 == IIC_Wait_Ack()){return 4; // err}data[0] = IIC_Read_Byte(0);IIC_Stop();return 0;
}// 读n字节内容
u8 W24C_ReadByte(u16 addr, u8* buf, u16 len)
{u16 i;IIC_Start();IIC_Send_Byte(0xA0);if(1 == IIC_Wait_Ack()){return 1; // err}IIC_Send_Byte(addr>>8);if(1 == IIC_Wait_Ack()){return 2; // err}IIC_Send_Byte(addr&0x0FF);if(1 == IIC_Wait_Ack()){return 3; // err}IIC_Start();IIC_Send_Byte(0xA1);if(1 == IIC_Wait_Ack()){return 4; // err}for(i=0; i<len; i++){buf[i] = IIC_Read_Byte(1);}IIC_Stop();return 0;
}u8 W24C_WriteOneByte(u16 addr, u8 data)
{IIC_Start();IIC_Send_Byte(0xA0);if(1 == IIC_Wait_Ack()){return 1; // err}IIC_Send_Byte(addr>>8);if(1 == IIC_Wait_Ack()){return 2; // err}IIC_Send_Byte(addr&0x0FF);if(1 == IIC_Wait_Ack()){return 3; // err}IIC_Send_Byte(data);if(1 == IIC_Wait_Ack()){return 4; // err}IIC_Stop();DelayMs(5);return 0;
}u8 W24C_WriteByteHighSpeed(u16 addr, u8* data, u8 len)
{u8 i;IIC_Start();IIC_Send_Byte(0xA0);if(1 == IIC_Wait_Ack()){return 1; // err}IIC_Send_Byte(addr>>8);if(1 == IIC_Wait_Ack()){return 2; // err}IIC_Send_Byte(addr&0x0FF);if(1 == IIC_Wait_Ack()){return 3; // err}for(i=0; i<len; i++){IIC_Send_Byte(data[i]);IIC_Wait_Ack();}IIC_Stop();DelayMs(5);return 0;            
}u8 W24C_WriteBytes(u16 addr, u8* data, u8 len)
{while(len--){W24C_WriteOneByte(addr,*data);addr++;data++;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/639404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【蓝桥杯备赛Java组】语言基础|竞赛常用库函数|输入输出|String的使用|常见的数学方法|大小写转换

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;蓝桥杯&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 一、编程基础 1.1 Java类的创建 1.2 Java方法 1.3 输入输出 1.4 String的使用 二、竞赛常用库函数 1.常见的数学方法 2.大小写转…

邦芒支招:避免薪资谈崩的六个措施

对于求职者而言&#xff0c;我喜欢把回答薪资问题比喻成玩扑克牌&#xff0c;它的目标就是让招聘方先亮出底牌。其原因在于&#xff0c;正如詹姆斯察觉到的&#xff0c;一旦你暴露了具体的薪资数目&#xff0c;你就会陷入要价太高(或者太低)的境地。 以下这些小技巧也许能为…

函数传参之按值传递

定义&#xff1a;所有函数的参数都是按值传递的&#xff0c;这意味着函数外的值被会被赋值到函数内部的参数中&#xff0c;就像从一个变量赋值到另外一个变量一样 **原始值&#xff1a;那么久跟原始值变量的复制一样** **引用值&#xff1a;那么久跟引用值复制一样**变量有按值…

php基础学习之代码框架

一&#xff0c;标记 脚本标记&#xff08;已弃用&#xff09;&#xff1a;<script language"php"> php代码 </script> 标准标记&#xff1a;<?php php代码 ?> 二&#xff0c;基础输出语句 不是函数&#xff0c;…

国内比较好的sap实施商有哪些?

在当今数字化浪潮的推动下&#xff0c;企业的数字化转型已成为企业竞争力的关键因素。而在众多企业应用软件中&#xff0c;SAP&#xff08;系统应用和产品&#xff09;作为全球的企业资源规划&#xff08;ERP&#xff09;解决方案供应商&#xff0c;扮演着至关重要的角色。然而…

javascript设计模式-应用示例

事件工具类 /* addEvent: simplified event attachment */ function addEvent( obj, type, fn ) {if (obj.addEventListener) {obj.addEventListener( type, fn, false );EventCache.add(obj, type, fn);}else if (obj.attachEvent) {obj["e"typefn] fn;obj[typefn…

【WSL】[出现错误 2147944320 (0x80070780) (启动“ubuntu.exe”时)]

问题描述 在尝试启动 Windows Subsystem for Linux (WSL) 的 “ubuntu.exe” 时&#xff0c;可能会遇到以下错误&#xff1a; [出现错误 2147944320 (0x80070780) (启动“ubuntu.exe”时)]错误的截图如下&#xff1a; 原因分析 系统找不到指定的文件。在这种情况下&#xff…

Git提交 ssh: connect to host github.com port 22: Connection timed out解决方案

你们好&#xff0c;我是金金金。 场景 之前都是好好的&#xff0c;不知道今天为什么提交代码就这样了 排查 根据英文可以看出&#xff0c;ssh端口号被拒绝了&#xff0c;22号端口不行&#xff0c;那就换一个端口 造成error的原因 ssh端口被拒绝 解决 找到.ssh文件&#xff…

CLion调试Nodejs源码

【环境】 macOS node-v20.11.0源码 CLion 2023.3.2 【1】下载源码 https://nodejs.org/en/download/ 【2】编译源码 解压后的目录如下 进入解压后的目录进行编译 ./configure --debug make -C out BUILDTYPEDebug -j 4需要好久… 编译成功之后在node-v20.11.0目录下会有一个…

【Web实操11】定位实操_照片墙(无序摆放)

设置一个板块&#xff0c;将照片随意无序摆放在墙上&#xff0c;从而形成照片墙。本来效果应该是很唯美好看的&#xff0c;就像这种&#xff0c;但是奈何本人手太笨&#xff0c;只好设置能达到照片墙的效果就可。 代码如下&#xff1a; <!DOCTYPE html> <html lang&…

SpringBoot整理-Spring Boot配置

Spring Boot 的配置系统是其核心功能之一,旨在简化 Spring 应用的配置过程。Spring Boot 提供了一种灵活的方式来配置你的应用,无论是通过外部配置文件,环境变量,命令行参数还是在代码中直接配置。以下是关于 Spring Boot 配置的几个重要方面: 配置文件 application.prope…

JavaEE的MVC(Model-View-Controller)设计模式

JavaEE的MVC&#xff08;Model-View-Controller&#xff09;设计模式是一种用于组织和管理Web应用程序的架构模式。MVC模式将应用程序分为三个主要组件&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#x…

binary_search_tree的介绍与实现(二叉搜索树精美图示详解哦)

二叉搜搜索树 引言二叉搜索树的介绍二叉搜索树的实现框架默认成员函数构造析构赋值重载 InsertR&#xff08;插入&#xff09;EraseR&#xff08;删除&#xff09;SearchR&#xff08;查找&#xff09; 源码概览总结 引言 在C语言部分&#xff0c;我们已经认识了树与二叉树的结…

【嵌入式经验积累】C语言实现傅里叶变换

文章目录 C 语言实现离散傅利叶变换&#xff08;DFT&#xff09;代码如下&#xff1a;C 语言实现快速傅利叶变换&#xff08;FFT&#xff09;&#xff0c;代码如下&#xff1a;分裂基快速傅利叶变换代码如下。实序列快速傅利叶变换&#xff08;一&#xff09;&#xff0c;代码如…

Nginx 实战指南

Nginx 是一款高性能的开源反向代理服务器,也可用作负载均衡器、Web服务器和缓存服务器。本实战指南将带你深入了解 Nginx 的安装、基础配置、高级配置、最佳实践以及性能调优。 步骤 1: 安装 Nginx Ubuntu sudo apt update sudo apt install nginx CentOS sudo yum insta…

python使用分治算法找出出现次数最多的数字

对于给定的一个长度为n的数组nums&#xff0c;需要找出起重工出现次数大于n/2向下取整的元素&#xff0c;假设给定的数组中一定存在符合给定要求的数&#xff0c;例如给定如下的例子&#xff1a; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 添加图片注…

docker使用http_proxy配置代理

钢铁知识库&#xff0c;一个学习python爬虫、数据分析的知识库。人生苦短&#xff0c;快用python。 在内网服务器中&#xff0c;docker经常需要下载拉取镜像&#xff0c;但由于没有网络要么只能手动导入镜像包&#xff0c;又或者通过http_proxy代理到其它服务器下载。 解决方法…

看书标记【R语言数据分析项目精解:理论、方法、实战 9】

看书标记——R语言 Chapter 9 文本挖掘——点评数据展示策略9.1项目背景、目标和方案9.1.1项目背景9.1.2项目目标9.1.3项目方案1.建立评论文本质量量化指标2.建立用户相似度模型3.对用户评论进行情感性分析 9.2项目技术理论简介9.2.1评论文本质量量化指标模型1.主题覆盖量2.评论…

FA-分配行重分配报错【APP-OFA-48313】

FA-重分配行报错 已存在行只能分多次转移调整 Ref1&#xff1a; APP-OFA-48313 You Cannot Create Identical Distribution Lines with Transfer (Doc ID 336894.1) APPLIES TO: Oracle Assets - Version 11.5.10.0 and later Information in this document applies to any…

Ubuntu20 服务器版磁盘扩容

Ubuntu20 服务器版磁盘扩容 Ubuntu20 服务器版磁盘不够用进可以使用fdisk命令对磁盘进行扩容 本案例中是基于vmware虚拟化环境下&#xff0c;ubuntu服务器按默认磁盘大小16G进行安装后&#xff0c;运行一段时间后发面/分区磁盘空间全部用完&#xff0c;导致服务无法正常运行。基…