STM32的I2C补充说明

news2024/10/5 21:18:48

1.前言

前面不是开发了F407的i2c嘛,最近做项目有三四个i2c器件,项目要求用f103,于是看了一下f103,发现并没有多大区别,下面我会说一下异同。还有关于接收的过程也有要补充的。

2.F103 VS F407

两者之间几乎没有区别,唯一不同的是GPIO的区别,F103与F407在GPIO寄存器会有点区别,这里稍微改一下就能用了。其他部分基本不用动。

上次关于STM32作为主机接收过程讲的有点不足,这次我在发送的时候没发现什么问题,但是接收的时候出现了问题,下面我来展开讲讲,尤其是长数据接收。

3.数据错误

首先是接收错误的问题,上一篇文章里我说到接收数据的过程

程序没有问题,但是顺序错了,正确的顺序是先等待SR1的第六位到位,再读取数据,否则,读到的数据就会是地址,而非接收的数据。

4.多数据接收

上次因为只做了一个数据的接收,所以问题没有暴露出来,这次我在用传感器的时候要一次性接收6个数据,发现数据接收有问题。最后还是通过读手册来排故的。

首先我们再明确一下读数据的过程。

可以看到在读数据的时候,每读一位都需要一个ACK,直到最后一位数据,而这个ACK是由主机向从机发送的应答。

而在STM32中,控制这个应答的在CR1寄存器中,是第十位

通过给第十位置1来给从机应答

我们来测试一下,这里我通过i2c读取3个数据

i2c_ReadRegist(ADXL345ADDRESS,0x32,data,3);

 我们看一下波形

不对啊,而且停止位没了,传输停止后总线的电平也不对。

这里我们要再看一下手册

注意看一下最后一位的数据传输,比较特殊。手册上说的比较模糊,我个人的建议是在完成上一个数据接收后就立刻给停止位置1,给应答位置0。程序可以这样写

	while(wei<length)
	{
		if(length!=1){I2C1->CR1|=1<<10;}						//多重数据接收时由主机应答
		if(wei==length-1)
		{
			I2C1->CR1&=~(1<<10);					//最后一位无需应答
			I2C1->CR1|=1<<9;							//提前写入停止位
		}
		//等待数据接收完毕
		for(wait=0;(I2C1->SR1&(1<<6))==0;wait++){if(wait>WAITTIME){I2C1->CR1|=1<<9;return;}}
		i2cdata[wei]=I2C1->DR;				//EV8
		wei++;
	}

经过测试,只有这样数据才不会溢出 

我们再来测试一下 

可以看到,波形非常标准。

5.代码

void i2c_ReadRegist(unsigned char i2c_address,unsigned char regaddress,unsigned char* i2cdata,unsigned char length)
{
	
	unsigned int wait;
	unsigned int wei=0;
	
	//发送
	
	I2C1->CR1|=1<<8;							//发出起始信号
	//等待起始信号发送完毕
	for(wait=0;(I2C1->SR1&(1<<0))==0;wait++){if(wait>WAITTIME){I2C1->CR1|=1<<9;return;}}
	
	I2CEV(5);											//EV5
	
	#if ADDRESSBIT==7
	I2C1->DR=i2c_address<<1;			//写入地址
	#else
	I2C1->DR=i2c_address;				//写入地址
	#endif
	
	//等待地址发送完毕
	for(wait=0;(I2C1->SR1&(1<<1))==0;wait++){if(wait>WAITTIME){I2C1->CR1|=1<<9;return;}}
	
	I2CEV(6);	
	I2C1->DR=regaddress;								//EV8
	//等待数据发送完毕	
	for(wait=0;(I2C1->SR1&(1<<7))==0;wait++){if(wait>WAITTIME){I2C1->CR1|=1<<9;return;}}
	
	
	//接收
	I2C1->CR1|=1<<8;							//发出起始信号
	//等待起始信号发送完毕
	for(wait=0;(I2C1->SR1&(1<<0))==0;wait++){if(wait>WAITTIME){I2C1->CR1|=1<<9;return;}}
	
	I2CEV(5);
	
	#if ADDRESSBIT==7
	I2C1->DR=(i2c_address<<1)+1;	//写入地址
	#else
	I2C1->DR=i2c_address;				//写入地址
	#endif
	//等待地址发送完毕
	for(wait=0;(I2C1->SR1&(1<<1))==0;wait++){if(wait>WAITTIME){I2C1->CR1|=1<<9;return;}}
	
	I2CEV(6);

	while(wei<length)
	{
		if(length!=1){I2C1->CR1|=1<<10;}						//多重数据接收时由主机应答
		if(wei==length-1)
		{
			I2C1->CR1&=~(1<<10);					//最后一位无需应答
			I2C1->CR1|=1<<9;							//提前写入停止位
		}
		//等待数据接收完毕
		for(wait=0;(I2C1->SR1&(1<<6))==0;wait++){if(wait>WAITTIME){I2C1->CR1|=1<<9;return;}}
		i2cdata[wei]=I2C1->DR;				//EV8
		wei++;
	}
}

6.总结

前面写i2c程序还是大意了,这两天测试的时候才发现问题,不过写好的i2c用起来还是很舒服的,几乎没有卡顿(中间的空白是在跑FFT算法,不是i2c的问题)

我这接收大量数据并且直接裸机跑在死循环里也没有出错,真不错。

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

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

相关文章

Maven 项目之快速选择环境配置文件

Maven项目中&#xff0c;多环境之间如何进行配置文件的切换。在我们开发的过程中&#xff0c;经常会出现开发环境、测试环境、生产环境等之间的切换&#xff0c;如果我们每次都去替换配置文件&#xff0c;就会跟繁琐&#xff0c;这个时候就可以创建多个环境&#xff0c;同时在对…

下载页面上的视频

引言&#xff1a;有些页面上的视频可以直接右键另存为或者F12检索元素找到视频地址打开后保存&#xff0c;但有些视频页面是转码后的视频&#xff0c;不能直接另存为视频格式&#xff0c;可以参考下本方法 以该页面视频为例&#xff1a;加载中...点击查看详情https://wx.vzan.c…

zookeeper监听集群节点的实现zkclient组件实现方案(Java版)

ZooKeeper Watcher 机制 client 向zookeeper 注册监听client注册的同时会存储一个WatchManager对象向zookeeper发生改变则notification client 并发送一个WatchManager对象,然后client再更新该对象 package com.jacky.zk.demo;import org.I0Itec.zkclient.IZkChildListener;…

LeetCode575——分糖果

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 这道题比较简单&#xff0c;但我还是花费了将近四个小时的时间去解答&#xff0c;AC的那一刻&#xff0c;终于全身舒畅&#xff0c;这道题的思路就是先求出糖果的种数&#xff0c;然后我们从题中可以得出&#x…

如何配置vite的proxy

1.前言 vite项目&#xff0c;本地开发环境可以通过配置proxy代理实现跨域请求。但是生产环境&#xff0c;该配置不生效&#xff0c;一般使用 nginx 转发&#xff0c;或者后端配置cors 2.解释 server: {port: 9000,proxy: { // 本地开发环境通过代理实现跨域&#xff0c;生产…

如何处理Flutter应用在iOS平台上的兼容性问题

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天我想和大家聊聊一个常见但令人头疼的问题——Flutter应用在iOS平台上的兼容性问题。在开发跨平台应用时&#xff0c;尤其是在Android和iOS两大平台上&#xff0c;兼容性问题总是难以避免。而Flutter&#xff0c;作为一个旨在解决…

使用OMP复原一维信号(MATLAB)

参考文献 https://github.com/aresmiki/CS-Recovery-Algorithms/tree/master MATLAB代码 %% 含有噪声 % minimize ||x||_1 % subject to: (||Ax-y||_2)^2<eps; % minimize : (||Ax-y||_2)^2lambda*||x||_1 % y传输中可能含噪 yyw % %% clc;clearvars; close all; %% 1.构…

IE浏览器兼容性问题——el-button点击失效

el-table 中经常有这种场景&#xff1a;最后一列是操作&#xff0c;只有一个图标 之前的实现是直接讲点击事件绑定到了 icon 图标上&#xff0c;这样在谷歌、edge、火狐等是没问题的&#xff0c;但是在ie浏览器下&#xff0c;就会出现点击事件无效的情况&#xff0c;点击后不会…

使用minikube安装使用单机版K8S(docker)

前置&#xff1a;作为一个开发&#xff0c;工作之余想玩一下k8s&#xff0c;但是搭建成本太高&#xff0c;所以就找到了minikube这个工具&#xff0c;快速搭建单机版k8s&#xff0c;下面是个人搭建流程&#xff0c;基于centos7&#xff0c;仅供参考。 1.下载kubectl&#xff0…

Idea2023创建Servlet项目

① Java EE 只是一个抽象的规范&#xff0c;具体实现称为应用服务器。 ② Java EE 只需要两个包 jsp-api.jar 和 servlet-api.jar&#xff0c;而这两个包是没有官方版本的。也就是说&#xff0c;Java 没有提供这两个包&#xff0c;只提供了一个规范。那么这两个包是谁提供的…

【Linux多线程】信号量以及线程池

【Linux多线程】信号量以及线程池 目录 【Linux多线程】信号量以及线程池POSIX信号量基于环形队列的生产者消费者模型 线程池 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2024.4.2 前言&#xff1a;本篇博客将会介绍Linux线程中的信号量以及线程池&#xff0c;完善生产者…

elementui 实现一个固定位置的Pagination(分页)组件

系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 二、elementui 左侧导航菜单栏与main区域联动 三、elementui 中设置图片的高度并支持PC和手机自适应 四、 elementui 实现一个固定位置的Pagination&#xff08;分页&#xff09;组件 文章目录 系列文章目录…

Python基于深度学习的人脸识别项目源码+演示视频,利用OpenCV进行人脸检测与识别 preview

​ 一、原理介绍 该人脸识别实例是一个基于深度学习和计算机视觉技术的应用&#xff0c;主要利用OpenCV和Python作为开发工具。系统采用了一系列算法和技术&#xff0c;其中包括以下几个关键步骤&#xff1a; 图像预处理&#xff1a;首先&#xff0c;对输入图像进行预处理&am…

深入剖析主机安全中的零信任机制及其实施原理

引言 在数字化转型加速与云端服务普及的大背景下&#xff0c;传统依赖边界的网络安全模式逐渐显露出其局限性。面对愈发复杂多变的威胁环境&#xff0c;零信任安全架构作为新一代的安全范式应运而生&#xff0c;尤其是在主机层面的安全实践中&#xff0c;零信任机制正扮演着至…

RabbitMQ3.x之七_RabbitMQ消息队列模型

RabbitMQ3.x之七_RabbitMQ消息队列模型 文章目录 RabbitMQ3.x之七_RabbitMQ消息队列模型1. RabbitMQ消息队列模型1. 简单队列2. Work Queues(工作队列)3. Publish/Subscribe(发布/订阅)4. Routing(路由)5. Topics(主题)6. RPC(远程过程调用)7. Publisher Confirms(发布者确认) …

防止推特Twitter账号被冻结,应该选什么代理类型IP?

在处理多个 Twitter 帐号时&#xff0c;选择合适的代理IP对于避免大规模帐户暂停至关重要。现在&#xff0c;问题出现了&#xff1a;哪种类型的代理是满足您需求的最佳选择&#xff1f;下面文章将为你具体讲解推特账号冻结原因以及重点介绍如何选择代理IP。 一、推特账号被冻结…

C# WPF编程-命令

C# WPF编程-命令 概述WPF命令模型ICommand接口RoutedCommand类RoutedUICommand类命令库 概述 使用路由事件可以响应广泛的鼠标和键盘事件&#xff0c;这些事件是低级的元素。在实际应用程序中&#xff0c;功能被划分成一些高级的任务。这些任务可通过各种不同的动作和用户界面…

如何借助API实现自动化商品采集商品,自营商城选品上货搜索无货源模式

借助API实现自动化商品采集、自营商城选品上货以及搜索无货源模式&#xff0c;通常需要以下步骤&#xff1a; 请求示例&#xff0c;API接口接入Anzexi58 确定数据源&#xff1a; 首先&#xff0c;你需要确定你的商品数据来源。这可能是其他电商平台、供应商网站、数据提供商等…

Spark 的结构化 APIs——RDD,DataFrame, Dataset, SparkSQL 使用和原理总结

文章目录 前言RDD的底层是什么?结构化 Spark主要优点和好处 DataFrame APISpark的基本数据类型Spark的结构化和复杂数据类型Schemas 和创建 DataFramesColumns 和 ExpressionsRows通用的 DataFrame 算子 The Dataset API有类型 Objects、无类型 Objects 和通用 Rows创建 Datas…

Express框架搭建项目 node.js

文章目录 引言Express框架介绍express安装环境准备写一个简单的项目展示 文章总结 引言 Express是一个基于Node.js平台的轻量级Web应用框架&#xff0c;它提供了简洁的API和丰富的功能&#xff0c;使得开发者能够快速地构建Web服务器和API。本文将带领大家从零开始&#xff0c…