STM32完成软件I2C通讯

news2024/11/24 2:33:41

今天的重点是利用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_11


void 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接收应答位赋值给Ack
	MyI2C_Stop();        //我的I2C停止时序
	
	OLED_ShowNum(1, 1, Ack, 3);  //OLED显示应答结果
	
	while(1)
	{

	}
}

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

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

相关文章

goproxy 简单介绍 及一键安装脚本

goproxy 官网 https://goproxy.cn/ GoProxy 是一项用于 Go 模块的高性能代理服务&#xff0c;旨在为 Go 开发人员提供更快速、更可靠的模块下载体验。它提供以下主要功能&#xff1a; 全球分布式代理服务器: GoProxy 在全球多个地区部署了代理服务器&#xff0c;例如拉斯维加…

驱动开发:探索DRIVER_OBJECT驱动对象

本章将探索驱动程序开发的基础部分&#xff0c;了解驱动对象DRIVER_OBJECT结构体的定义&#xff0c;一般来说驱动程序DriverEntry入口处都会存在这样一个驱动对象&#xff0c;该对象内所包含的就是当前所加载驱动自身的一些详细参数&#xff0c;例如驱动大小&#xff0c;驱动标…

B站基于Apache Ranger的大数据权限服务的技术演进

01 背景 随着云计算、大数据技术的日趋成熟&#xff0c;复杂多元、规模庞大的数据所蕴含的经济价值和社会价值逐步凸显&#xff0c;数据安全也是企业面临的巨大挑战&#xff0c;B站一直致力于对用户隐私数据的保护。 02 Ranger概述 2.1 用户认证 提到安全&#xff0c;就不得不…

uni-app web端使用getUserMedia,摄像头拍照

<template><view><video id"video"></video></view> </template> 摄像头显示在video标签上 var opts {audio: false,video: true }navigator.mediaDevices.getUserMedia(opts).then((stream)> {video document.querySelec…

emmet语法--快速生成html标签

emmet语法介绍 可以直接把它理解为快捷键。 通过一定简略的缩写配合快捷键&#xff0c;直接生成我们想要的html代码。 vscode中已经内置了emmet语法&#xff0c;可以直接使用。 emmet的核心就是tab键&#xff0c;我们输入关键词然后按下tap就可以直接生成我们要的代码。 标…

高云FPGA的管脚约束文件的复制

问&#xff1a;Gowin里面能不能直接拷贝一个管脚约束文件进去用&#xff1f; 答&#xff1a; 可以直接拷贝&#xff0c;但是拷贝前后两个工程对应的芯片必须要是同一个芯片 拷贝方法: 第一步&#xff1a;按照被拷贝约束文件对应的芯片新建一个工程&#xff0c;然后将原工程文…

产品推荐 | 基于Lattice的Crosslink系列LIF-MD6000 FPGA开发板

1、产品概述 LATTICE是一家老牌的FPGA厂家。在CPLD和FPGA低成本&#xff0c;小封装独树一帜。特别在消费电子&#xff0c;小型化设备&#xff0c;控制领域用的比较多。 Crosslink开发板采用Lattice的Crosslink家族系列芯片&#xff0c;LIF-MD6000-6JM80。Crosslink芯片具有低…

取出/var/log/secure中一小时内登录失败超过三次的IP

取出/var/log/secure中一小时内登录失败超过三次的IP 前两个字段是日期&#xff0c;第三个字段是小时&#xff0c;第四个字段是IP cat /var/log/secure | sort -i | awk -F [ :] /Failed/{a[$1" "$2" "$3" "$4" "$(NF-3)]}END{for(i …

二百三十一、ClickHouse——DBeaver连接ClickHouse中时间戳字段的时区差了8小时

一、目的 在用kettle把MySQL中的数据同步到ClickHouse中&#xff0c;发现kettle里的数据显示正常、DataGrip查询ClickHouse中的数据显示正常&#xff0c;但是DBeaver中显示的ClickHosue中的时间字段晚8个小时 二、错误原因 DBeaver的数据库时区设置有问题 三、解决办法 右…

DP10RF001一款工作于200MHz~960MHz低功耗、高性能、单片集成的(G)FSK/OOK无线收发芯片

产品概述. DP10RF001是一款工作于200MHz~960MHz范围内的低功耗、高性能、单片集成的(G)FSK/OOK无线收发机芯片。内部集成完整的射频接收机、射频发射机、频率综合器、调制解调器&#xff0c;只需配备简单、低成本的外围器件就可以获得良好的收发性能。芯片支持灵活可设的数据包…

[大模型]Langchain-Chatchat安装和使用

项目地址&#xff1a; https://github.com/chatchat-space/Langchain-Chatchat 快速上手 1. 环境配置 首先&#xff0c;确保你的机器安装了 Python 3.8 - 3.11 (我们强烈推荐使用 Python3.11)。 $ python --version Python 3.11.7接着&#xff0c;创建一个虚拟环境&#xff…

Day98:云上攻防-云原生篇K8s安全Config泄漏Etcd存储Dashboard鉴权Proxy暴露

目录 云原生-K8s安全-etcd(Master-数据库)未授权访问 etcdV2版本利用 etcdV3版本利用 云原生-K8s安全-Dashboard(Master-web面板)未授权访问 云原生-K8s安全-Configfile鉴权文件泄漏 云原生-K8s安全-Kubectl Proxy不安全配置 知识点&#xff1a; 1、云原生-K8s安全-etcd未…

Failure Unable to retrieve image details-解决Portainer与Docker v26不兼容问题

文章目录 前言解决过程解决方法一解决方法二 前言 今天登上服务器习惯性的升级了yum软件包&#xff0c;结果这一更新后导致Portainer不能正常使用&#xff0c;后续进行成功解决&#xff0c;简单记录一下 解决过程 事故过程模拟 当时顺手升级下docker版本(V26.0.1) 结果Porta…

OpenHarmony南向之编译构建框架

title: OpenHarmony南向之编译构建框架 categories:- OpenHarmony tags:- Ninja- GN author: shell cover: /img/oh/build_framework_ZN.png date: 2024-01-03 21:05:38概述 OpenHarmony编译子系统是以GN和Ninja构建为基座&#xff0c;对构建和配置粒度进行部件化抽象、对内建…

智能售货机:引领便捷生活

智能售货机&#xff1a;引领便捷生活 在这个科技迅速进步的时代&#xff0c;便捷已成为生活的必需。智能售货机作为技术与便利完美结合的产物&#xff0c;正逐渐改变我们的购物方式&#xff0c;为都市生活增添新的活力。 智能售货机的主要优势是它的极致便利性。不论是在地铁…

局域网管理软件哪个好?局域网电脑管理系统实践案例

之前有一个公司案例&#xff0c;是这样的&#xff1a; 公司名称&#xff1a;智慧科技有限公司 背景&#xff1a; 智慧科技有限公司是一家拥有数百名员工的中型企业&#xff0c;随着业务的快速发展&#xff0c;公司面临着网络管理上的挑战。 员工在日常工作中需要频繁地访问…

ChatGPT加持,需求分析再无难题

简介 在实际工作过程中&#xff0c;常常需要拿到产品的PRD文档或者原型图进行需求分析&#xff0c;为产品的功能设计和优化提供建议。 而使用ChatGPT可以很好的帮助分析和整理用户需求。 实践演练 接下来&#xff0c;需要使用ChatGPT 辅助我们完成需求分析的任务 注意&…

车载平板丨车载终端丨车载平板电脑前景如何?

随着人们对车辆安全性和稳定性的关注日益增加&#xff0c;车载加固终端市场前景非常广阔。根据市场研究机构的数据显示&#xff0c;全球车载加固终端市场规模将在未来几年内快速增长。预计到2025年&#xff0c;全球车载加固终端市场规模将达到约55亿美元&#xff0c;年复合增长…

数字IC/FPGA——锁存器/触发器/寄存器

本文主要介绍以下几点&#xff1a; 什么是触发器和锁存器门电路和触发器的区别什么是电平钟控触发器电平钟控触发器触发器和锁存器的区别触发器的分类方式&#xff1a;逻辑功能、触发方式、电路结构、存储数据原理、构成触发器的基本器件寄存器利用移位寄存器实现串并转换或并…

npm问题合集以及npm常规操作整理

问题一&#xff1a;npm install 卡在“sill idealTree buildDeps“ 可以尝试将网络切换为其他网络&#xff0c;我的是这么解决的。可以尝试重新设置镜像。 问题二&#xff1a;npm install 项目依赖报WARN deprecated 原因 依赖版本问题&#xff0c;下载最新版本。 解决方案 …