STM32完成软件I2C通讯

今天的重点是利用STM32的软件方案和MPU60506轴姿态传感器建立通讯,今天只完成了简单的发送地址和接收应答的部分,特此记录一下过程,以后忘记可以随时翻出来看看。

先介绍最基本的I2C通讯的最基本的6个时序:

一:起始条件:SCL高电平期间,SDA从高电平切换到低电平

时序图从左到右的顺序为1、2、3、4.

二:终止条件:SCL高电平期间,SDA从低电平切换到高电平

三:发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位先行),然后释放SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节

四:接收一个字节:SCL低电平期间,从机将数据位依次放到SDA线上(高位先行),然后释放SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)

五:发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答

六:接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)

好了到此结束,整个I2C通讯的所有最基本的时序都理清了,和固定的芯片通讯都要建立在这6个基本时序的上层了。下面就是我写的六个时序的代码部分,可以结合着我画的图来理解,能很快的应用起来,刚开始的小伙伴估计不太会看这个时序图,我也是刚刚才有所感觉的,画的不好,理解的不够透彻,还望多多指正啊!

下面是MyIC.c文件

#include "stm32f10x.h"                  // Device header
#include "MyI2C.h"
#include "Delay.h"void MyI2C_W_SCL(uint8_t BitValue)
{GPIO_WriteBit(GPIO_POART, MyI2C_SCL, (BitAction)BitValue);Delay_us(10);
}void MyI2C_W_SDA(uint8_t BitValue)
{GPIO_WriteBit(GPIO_POART, MyI2C_SDA, (BitAction)BitValue);Delay_us(10);
}uint8_t MyI2C_R_SDA(void)
{uint8_t BitValue;BitValue = GPIO_ReadInputDataBit(GPIO_POART, MyI2C_SDA);Delay_us(10);return BitValue;
}void MyI2C_Init(void)
{RCC_APB2PeriphClockCmd(GPIO_CLOCK, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStruct.GPIO_Pin = MyI2C_SCL | MyI2C_SDA;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIO_POART, &GPIO_InitStruct);//	MyI2C_W_SCL(1);
//	MyI2C_W_SDA(1);GPIO_SetBits(GPIO_POART, MyI2C_SCL | MyI2C_SDA);
}void MyI2C_Start(void)
{MyI2C_W_SDA(1);MyI2C_W_SCL(1);MyI2C_W_SDA(0);MyI2C_W_SCL(0);
}void MyI2C_Stop(void)
{MyI2C_W_SDA(0);MyI2C_W_SCL(1);MyI2C_W_SDA(1);
}void MyI2C_Send_Byte(uint8_t Byte)
{uint8_t i;for( i = 0; i < 8; i ++){MyI2C_W_SDA(Byte & (0x80 >> i));MyI2C_W_SCL(1);MyI2C_W_SCL(0);}
}uint8_t MyI2C_Receive_Byte(void)
{uint8_t i, Byte = 0x00;MyI2C_W_SDA(1);for( i = 0; i < 8; i ++){MyI2C_W_SCL(1);if(MyI2C_R_SDA() == 1) { Byte |= (0x80 >> i);}MyI2C_W_SCL(0);}return Byte;
}void MyI2C_Send_Ack(uint8_t BitAck)
{MyI2C_W_SDA(BitAck);MyI2C_W_SCL(1);MyI2C_W_SCL(0);
}uint8_t MyI2C_Receive_Ack(void)
{uint8_t BitAck;MyI2C_W_SDA(1);MyI2C_W_SCL(1);BitAck = MyI2C_R_SDA();MyI2C_W_SCL(0);return BitAck;
}

下面是MyIC.h文件

#ifndef __MYI2C_H
#define __MYI2C_H
// 需要更改端口的话只需要在这4个宏定义中更改就行了,其他的地方不用改
#define GPIO_CLOCK                                       RCC_APB2Periph_GPIOB
#define GPIO_POART                                       GPIOB
#define MyI2C_SCL                                        GPIO_Pin_10
#define MyI2C_SDA                                        GPIO_Pin_11void MyI2C_Init(void);     //我的I2C初始化void MyI2C_Start(void);  //我的I2C开始时序void MyI2C_Stop(void);  //我的I2C结束时序void MyI2C_Send_Byte(uint8_t Byte);   //我的I2C发送一个字节uint8_t MyI2C_Receive_Byte(void);   //我的I2C接收一个字节void MyI2C_Send_Ack(uint8_t BitAck);   // 我的I2C发送应答位uint8_t MyI2C_Receive_Ack(void);          //我的I2C接收应答位#endif

下面是main.c文件,测试基础的I2C代码的时序都有没有问题

回复显示0代表有这个地址,回复显示1代表没有这个地址

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "MyI2C.h"int main(void)
{OLED_Init();       //oled  屏幕初始化MyI2C_Init();    //我的I2C初始化MyI2C_Start();   //我的I2C开始时序MyI2C_Send_Byte(0xD0);   //我的I2C发送地址           这里要是有个遍历就可以把所有的地址都发送一遍测试都有哪个地址uint8_t Ack = MyI2C_Receive_Ack();  //我的I2C接收应答位赋值给AckMyI2C_Stop();        //我的I2C停止时序OLED_ShowNum(1, 1, Ack, 3);  //OLED显示应答结果while(1){}
}

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

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

相关文章

TCP/IP协议—UDP

TCP/IP协议—UDP UDP协议UDP通信特点 UDP头部报文UDP检验 UDP协议 用户数据传输协议 (UDP&#xff0c;User Datagram Protocol) 是一种无连接的协议&#xff0c;提供了简单的数据传输服务&#xff0c;不保证数据的顺序以及完整性。应用层很多通信协议都基于UDP进行传输&#x…

算法-二分

算法-二分 时间复杂度&#xff08;logn&#xff09; 当问题的答案具有单调性时&#xff0c;就可以通过二分把求解转换为判定。 1.整数二分 bool check(int x){...} //检查x是否满足某种性质int bsearch_1(int l,int r) {int mid(lr)>>1;int ansr;if(check(mid)) an…

蓝桥杯JAVA组备赛模板2:质素线性筛

线性筛&#xff1a; //质数线性筛int N1000010;int cnt 0;int[] minv new int[N];int[] prime new int[N];minv[1] 1;for(int i 2;i < N;i){if(minv[i] 0)prime[cnt] i;for(int j 1;j < cnt && i * prime[j] < N;j){minv[i * prime[j]] prime[j];if…

关系型数据库设计的核心原则和规范

关系型数据库设计规范旨在减少数据冗余、提高数据一致性&#xff0c;并优化数据访问性能。以下是关系型数据库设计的核心原则和规范&#xff1a; 实体-关系模型 (ER Model) 在设计阶段&#xff0c;首先创建实体-关系图&#xff08;ER Diagram&#xff09;&#xff0c;用于描述业…

centos7的防火墙

一、防火墙的开启、关闭、禁用命令 &#xff08;1&#xff09;设置开机启用防火墙&#xff1a;systemctl enable firewalld.service &#xff08;2&#xff09;设置开机禁用防火墙&#xff1a;systemctl disable firewalld.service &#xff08;3&#xff09;启动防火墙&#x…

未佩戴厨师帽识别检测 厨房管理系统 自动监测未佩戴厨师帽行为 实时报警

在厨房环境中&#xff0c;佩戴厨师帽对于食品安全和卫生至关重要。厨师帽能够有效地防止头发、皮屑等杂质掉入食物中&#xff0c;减少了食品受到污染的可能性&#xff0c;从而保障了食品安全。特别是在学校、餐厅等场景中&#xff0c;对于未佩戴厨师帽的检测更是必不可少。相关…

c++ override关键字

在C11及之后的标准中&#xff0c;override是一个关键字&#xff0c;用于表示派生类中的成员函数覆盖了基类中的虚函数。 使用override关键字的好处在于它提供了一种明确的方式来指示编译器&#xff1a;该函数打算覆盖基类中的虚函数。如果使用了override关键字&#xff0c;但该…

深入理解Linux系统中的前后台任务与守护进程

⭐小白苦学IT的博客主页 ⭐初学者必看&#xff1a;Linux操作系统入门 ⭐代码仓库&#xff1a;Linux代码仓库 ❤关注我一起讨论和学习Linux系统 1.前言 在Linux系统中&#xff0c;进程管理是至关重要的一个环节。其中&#xff0c;前后台任务和守护进程是进程管理中不可忽视的两…

neo4j-02

1.项目实战参考vue 使用 Apache ECharts 可视化 Neo4j 图数据_neo4j echarts-CSDN博客 2.后台集成参考https://www.yuduan.top/archives/1702217828037

Vue结合el-table实现合并单元格(以及高亮单元表头和指定行)

实现效果如下&#xff1a; 思路&#xff1a; 1.首先使用动态表头表格。 2.其次实现动态计算合并单元格。&#xff08;计算规则 传递需要合并的字段&#xff09; 3.然后封装公共的计算单元格方法 export导出供多个页面使用。 4.同时需要封装成公共的组件供多个页面使用。 5…

资治通鉴读后感之【听不同的声音、CEO风险管理、现金储备、重视领导周边的人】

听不同的声音&#xff1a; 1、能听到不同意见 2、建立保障”说不同意见“的制度 你觉得别人过得特别好&#xff0c;肯定是你跟他不熟。 欲戴皇冠&#xff0c;必承其重。 CEO风险管理&#xff1a; 1、不碰、不参与极限运动&#xff1b; 2、尊守法律&#xff1b; …

电动车新国标迎来修订机会,用户的真实需求能被满足吗?

文&#xff5c;新熔财经 作者&#xff5c;宏一 自2019年4月《电动自行车安全技术规范》发布至今&#xff0c;电动车的新国标标准已经实施5年&#xff0c;市场上的争议也此起彼伏地持续了5年。 因为新国标对电动车的各项技术标准提出的明确要求&#xff0c;其中&#xff0c;最…

【御控物联】物联网平台简述

物联网平台是一种实现设备接入、设备监控、设备管理、数据存储、消息多源转发和数据分析等能力的一体化平台。物联网平台主要具备以下四种能力。 连接管理&#xff1a; 为大批量设备提供联网通信能力&#xff0c;助力设备数据快速上云&#xff0c;解决设备孤岛、数据不能共享问…

Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066

很奇怪的问题,在使用nifi的时候碰到的,这里是用NIFI,把数据从postgresql中同步到mysql中, 首先postgresql中的源表,中是没有create_time这个字段的,但是同步的过程中报错了. 报错的内容是说,目标表中有个create_time字段,这个字段是必填的,但是传过来的flowfile文件中,的数据没…

奇怪的捐赠 蓝桥杯 java

奇怪的捐赠 地产大亨Q先生临终的遗愿是&#xff1a;拿出100万元给X社区的居民抽奖&#xff0c;以稍慰藉心中愧疚。 麻烦的是&#xff0c;他有个很奇怪的要求&#xff1a; 100万元必须被正好分成若干份&#xff08;不能剩余&#xff09;。 每份必须是7的若干次方元。 比如&…

[RK3399 Linux] 使用ubuntu 20.04.5制作rootfs

一、ubuntu base ubuntu base是用于为特定需求创建自定义映像的最小rootfs,是ubuntu可以运行的最小环境。 1.1 下载源码 下载ubuntu-base的方式有很多,可以从官方的地址:ttp://cdimage.ubuntu.com/ubuntu-base/releases。 也可以其它镜像地址下载,如清华源:https://mi…

使用shell管理和配置网络服务_1

1、请使用nmcli命令配置仅主机模式网络环境&#xff0c;要求如下: 1) 创建一个新的网卡连接eth1&#xff0c;该连接映射到ens32网卡上; 首先&#xff0c;确保 ens32 网卡没有被其他网络配置文件使用。然后&#xff0c;使用 nmcli 创建一个新的连接&#xff0c;并将其绑定到 e…

在Linux中使用dpkg -i离线安装下载的deb软件包

“dpkg -i” 是 Debian 系统中用于安装 .deb 格式软件包的命令。它是 Debian Package Management System&#xff08;DPMS&#xff09;的一部分&#xff0c;允许用户通过命令行界面来管理软件包。 使用该命令时&#xff0c;需要提供要安装的软件包的路径作为参数。例如&#…

实战纪实 | 编辑器漏洞之Ueditor-任意文件上传漏洞 (老洞新谈)

UEditor 任意文件上传漏洞 前言 前段时间在做某政府单位的项目的时候发现存在该漏洞&#xff0c;虽然是一个老洞&#xff0c;但这也是容易被忽视&#xff0c;且能快速拿到shell的漏洞&#xff0c;在利用方式上有一些不一样的心得&#xff0c;希望能帮助到一些还不太了解的小伙…

一行代码实现Android反向shell(Reverse shell)

网上关于android得反向shell 多是需要安装apk的&#xff0c;操作麻烦。 本文通过一行代码即可实现Android反向shell&#xff08;Reverse shell&#xff09;。 ------------------------------ 在 PC 上执行以下操作 &#xff08;控制端&#xff09; nc -lvp 4444 ---------…