EFM32 硬件I2C通讯案例

2023-10-28

前言

        最近项目上用到了EFM32HG222F64G芯片中的硬件通讯,i2c通讯不稳定问题,导致花了很长时间去解决,走了不少弯路,最终还是解决了。在此写一下,做个记录,也方便给后面做产品的攻城狮,少走一些弯路吧!好了 ^_^! 进入正题。

来个直接点,直接上代码:

需要创建两个文件,I2C.c与I2C.h

I2C.h

#ifndef I2C_H
#define	I2C_H

#include "em_i2c.h"


void initI2c(void);
I2C_TransferReturn_TypeDef i2c_writeData(uint8_t wrStAddr, uint8_t* txData, uint8_t writeLen);
I2C_TransferReturn_TypeDef i2c_readData(uint8_t srAddr, uint8_t *rxData, uint8_t readLen);


#endif

I2C.c

#include "em_i2c.h"
#include "em_emu.h"
#include "i2c.h"
#include "em_cmu.h"
#include "lee_log.h"

#define I2C_ADDRESS                     0xD0
#define TIME_OUTT 100


I2C_TransferReturn_TypeDef I2C_Status;
/*----------------------------------------------------------------------------*/
//@Breif Description:Initialize the i2c module
/*----------------------------------------------------------------------------*/
void initI2c(void)
{
	I2C_Init_TypeDef init_I2C = 
	{
		.enable = true,
		.clhr = i2cClockHLRStandard,
		.freq = I2C_FREQ_STANDARD_MAX,
		.master = true,
		.refFreq = 0
	};
	
	/* Enabling clock to the I2C, GPIO*/
	CMU_ClockEnable(cmuClock_HFPER, true);
	CMU_ClockEnable(cmuClock_I2C0, true);
	CMU_ClockEnable(cmuClock_GPIO, true);
	
	/* Starting LFXO and waiting until it is stable */
	CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
	/* Routing the LFXO clock to the RTC */
	CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
	
	//GPIO_DriveModeSet(gpioPortA, gpioDriveModeHigh);
	
	/* Using PA0 (SDA) and PA1 (SCL) */
	GPIO_PinModeSet(gpioPortA, 1, gpioModeWiredAndPullUpFilter, 1);
	GPIO_PinModeSet(gpioPortA, 0, gpioModeWiredAndPullUpFilter, 1);
	/* Configure interrupt pin*/
	GPIO_PinModeSet(gpioPortC, 4, gpioModeInput, 0);

	
	//I2C0->ROUTE |= I2C_ROUTE_LOCATION_LOC2 + I2C_ROUTE_SCLPEN + I2C_ROUTE_SDAPEN;
	I2C0->ROUTE = I2C_ROUTE_SDAPEN
	| I2C_ROUTE_SCLPEN
	| (0 << _I2C_ROUTE_LOCATION_SHIFT);
	I2C_Init(I2C0, &init_I2C);
	I2C0->CTRL |= I2C_CTRL_AUTOSN;						    //一个字节的读取,这里需要更改
	//I2C0->CTRL |= I2C_CTRL_AUTOACK | I2C_CTRL_AUTOSN;		//两个字节的读取,这里需要更改
	//NVIC_EnableIRQ(I2C0_IRQn);
}
/*----------------------------------------------------------------------------*/
//@Breif Description:	write data to BMI160
/*----------------------------------------------------------------------------*/
I2C_TransferReturn_TypeDef i2c_writeData(uint8_t wrStAddr, uint8_t* txData, uint8_t writeLen)
{
	uint32_t loop = TIME_OUTT;
	I2C_TransferSeq_TypeDef tx_Init = 
	{
		.addr = I2C_ADDRESS,
		.buf[0].data = &wrStAddr,
		.buf[0].len = 1,
		.buf[1].data = txData,
		.buf[1].len = writeLen,
		.flags = I2C_FLAG_WRITE_WRITE,
	};
	
	I2C_Status = I2C_TransferInit(I2C0, &tx_Init);
	while ((I2C_Status == i2cTransferInProgress) && loop--)
	{
		I2C_Status = I2C_Transfer(I2C0);
		//EMU_EnterEM1();
	}	
	if (loop == TIME_OUTT) {
		LEE_LOG(LOG_INFO,"i2c_write loop fail.\n");
	}
	return(I2C_Status);
}

/*----------------------------------------------------------------------------*/
//@Breif Description:read data from BMI160
/*----------------------------------------------------------------------------*/
I2C_TransferReturn_TypeDef i2c_readData(uint8_t srAddr, uint8_t *rxData, uint8_t readLen)
{
	uint32_t loop = TIME_OUTT;
	I2C_TransferSeq_TypeDef rx_Init = 
	{
		.addr = I2C_ADDRESS,
		.buf[0].data = &srAddr,
		.buf[0].len = 1,
		.buf[1].data = rxData,
		.buf[1].len = readLen,
		.flags = I2C_FLAG_WRITE_READ,
	};
	/* Do a polled transfer */
	I2C_Status = I2C_TransferInit(I2C0, &rx_Init);
	while ((I2C_Status == i2cTransferInProgress) && (loop--))
	{
		/* Enter EM1 while waiting for I2C interrupt */
		I2C_Status = I2C_Transfer(I2C0);
		//EMU_EnterEM1();
		/* Could do a timeout function here. */
	}
	if (loop == TIME_OUTT) {
		LEE_LOG(LOG_INFO,"i2c_read loop fail.\n");
	}
	return(I2C_Status);
}

/*----------------------------------------------------------------------------*/
//@Breif Description:the interrupt service function
/*----------------------------------------------------------------------------*/
//void I2C0_IRQHandler(void)
//{
//	I2C_Status = I2C_Transfer(I2C0);
//}


在这说明一下,我出现过的问题,在I2C初始化的时候,按照实例代码配置

I2C0->CTRL |= I2C_CTRL_AUTOACK | I2C_CTRL_AUTOSN;       

我明明写的读取按照单字节来读取的,但是使用逻辑分析仪抓到的波形而双字节的波形(现在项目上是使用BMI160出现这种情况,不知道跟其他产品是否有类似的问题)

逻辑分析仪抓的波形如下:

write:

read:

使用下面的配置的话,是可以读取单字节的数据(项目上是使用BMI160与EFM32通讯)

I2C0->CTRL |= I2C_CTRL_AUTOSN;                            //一个字节的读取,这里需要更改

write:

read:

在main(),使用

int main(void)
{
   uint8_t data_wr[]={0};
   uint8_t reg_data = 0;
   
   initI2c();
   bmi160_init(0xd0);  

   while (1) {     
        data_wr[0] = 0x15;
        i2c_writeData(0x40,data_wr,1);
        LED_Delay_ms(1000);
        i2c_readData(0x40, &reg_data,1);       
        LEE_LOG(LOG_INFO," acc_data40 = %X \r\n", reg_data);
        LEE_LOG(LOG_INFO,"**************************** \r\n");
   }

 

只需要调用读、写方法即可

i2c_writeData(0x40,data_wr,1);

i2c_readData(0x40, &reg_data,1);       

以上的代码已经在项目上使用,测试过没什么问题。谢谢各位看官。

还有一个问题就是在初始化时。下面这两个要配合使用,不能单独配置一个,不然,不起作用。

.freq = I2C_FREQ_FASTPLUS_MAX;

CMU_ClockEnable(cmuClock_HFPER, true);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EFM32 硬件I2C通讯案例 的相关文章

  • MySQL四十五讲(基础篇)知识汇总(全)

    MySQL四十五讲 基础篇 知识汇总 全 一 MySQL 基本架构 二 日志 Redo log 和 Binlog 2 1 重要的日志模块 gt Redo log 2 2 重要的日志模块 Binlog 2 3 Redo log 与 Binlo
  • 多态&单例类

    1 多态 多态 一种事物的多种体现形式 举例 动物有很多种 应用 定义时并不确定是什么类型 要调用的是哪个方法 只有运行的时候才能确定调用的是哪个 注意 继承是多态的前提 1 多态 1 1 回顾isinstance class Dog ob
  • 使用jquery做的伸缩菜单

  • 基于wordpress和Sakura主题插件搭建博客网站

    基于wordpress和Sakura主题插件搭建博客网站 1 引言 2 认清现实 3 使用的本地化方法 4 分享自己走的一些弯路 5 硬刚404的余波 6 额外的收获 1 引言 最近 本着试试的想法 想着找一个前端方面的工作 遇到一些招聘软
  • fiddler扩展模拟弱网络环境设置

    今天在qq群中有人问到怎么模拟app弱网络环境 我查了下资料 记得之前做测试的时候是设置fiddler断点 app请求后止于fiddler断点 app一直拿不到响应结果就应该要给出网络请求失败的提示 这种方式太麻烦 对每个接口每次请求都要独
  • 图形学实验六真实感图形算法

    目录 实验六 真实感图形算法 一 实验目的 二 实验内容 三 实验原理 四 实验示范代码 略 五 实验步骤 六 实验结果处理 七 实验注意事项 八 预习与思考题 九 实验报告要求 实验六 真实感图形算法 实验类型 设计型 实验学时 2实验要
  • 解决无法成功完成操作,因为文件包含病毒或潜在的垃圾软件

    解决无法成功完成操作 因为文件包含病毒或潜在的垃圾软件 近日在运行电脑上某一个软件的时候 提示 无法成功完成操作 因为文件包含病毒或潜在的垃圾软件 在网上搜索了半天 百度结果翻了几页 都是说把Windows安全中心的 实时保护 关了 然后把
  • MFC 基础知识:主对话框与子对话框(二)

    仅供使用VS MFC初学者学习 高手莫见笑 接 MFC 基础知识 主对话框与子对话框 一 的内容 在 MFC 基础知识 主对话框与子对话框 一 中Edit Control 编辑框 控件中输出内容 主要是想讲讲在创建的子对话框中如何实现一些操
  • BFS算法解题套路框架(附习题)

    BFS算法解题套路框架 BFS 的核心思想 就是把一些问题抽象成图 从一个点开始 向四周开始扩散 一般来说 我们写 BFS 算法都是用 队列 这种数据结构 每次将一个节点周围的所有节点加入队列 BFS 相对 DFS 的最主要的区别是 BFS
  • 20190711_New_Citation

    Cross Talk Among Reactive Oxygen Nitrogen and Sulfur During Abiotic Stress in Plants https onlinelibrary wiley com doi p
  • Awesome Fine-Grained Image Analysis – Papers, Codes and Datasets

    Awesome Fine Grained Image Analysis Papers Codes and Datasets Table of contents Introduction Tutorials Survey papers Ben
  • LDA(Latent Dirichlet Allocation)主题模型

    LDA于2003年由 David Blei Andrew Ng和 Michael I Jordan提出 因为模型的简单和有效 掀起了主题模型研究的波浪 虽然说LDA模型简单 但是它的数学推导却不是那么平易近人 一般初学者会深陷数学细节推导中
  • Java中对象的引用(Java对象的引用 )

    Java对象的引用 一 概念 什么是Java对象的引用 每种编程语言都有自己的数据处理方式 有些时候 程序员必须注意将要处理的数据是什么类型 你是直接操纵元素 还是用某种基于特殊语法的间接表示 例如C C 里的指针 来操作对象 所有这些在
  • git 001--建本地仓库和远程仓库和拉代码

    要使用Git对我们的代码进行管理 首先需要获得Git仓库 获取Git仓库通常有两种方式 在本地初始化Git仓库 不常用 从远程仓库克隆 常用 一 建本地仓库 方法一 在自己电脑的任意目录下创建一个空目录 例如桌面的aaa 作为我们的本地Gi
  • 新手入门必看MyBatis-Plus&Druid数据源

    MyBatis Plus Druid数据源 我们就一起来了解下Mybatis Plus吧 什么是MyBatis Plus MyBatis Plus的优势 MyBatis Plus简单来说就是在原本的MyBatis的基础上加了Buff或者说是
  • [系统安全] 四十四.恶意代码同源分析及BinDiff软件基础用法

    您可能之前看到过我写的类似文章 为什么还要重复撰写呢 只是想更好地帮助初学者了解病毒逆向分析和系统安全 更加成体系且不破坏之前的系列 因此 我重新开设了这个专栏 准备系统整理和深入学习系统安全 逆向分析和恶意代码检测 系统安全 系列文章会更

随机推荐

  • 外盘期货的几个级别 你到达几级了?

    01 小白 如果开始赔了钱 就收手不做或者学会敬畏市场还好 但如果开始的福利期太顺或者太容易 就及其容易造成信心爆棚 对行情存在 赌 的思想 反而不利于以后的成长 这种情况基本出现在刚刚入市 实盘交易时间短的小白身上 02 筑基期 处在这一
  • 二叉树的扩展——主要方法和基本算法等

    1 求树的高度 思路 二叉树的高度等于左右子树里面的最大高度 int high BtNode ptr if ptr NULL return 0 int L high ptr gt lchild int R high ptr gt rchil
  • java.lang.IllegalStateException

    Caused by java lang IllegalStateException The specified child already has a parent You must call removeView on the child
  • 【SQL】保姆级教程:MySQL配置全过程 & 编辑器DBeaver的安装配置

    MySQL 是最流行的关系型数据库管理系统 在 WEB 应用方面 MySQL 是最好的 RDBMS Relational Database Management System 关系数据库管理系统 应用软件之一 文章目录 一 什么是数据库 二
  • 数字水印技术的原理、实现及其应用

    概述 数字水印 是指将特定的信息嵌入数字信号中 数字信号可能是音频 图片或是视频等 数字水印可分为浮现式和隐藏式两种 明水印 visible watermarking 其所包含的信息可在观看图片或视频时同时被看见 盲水印 blind wat
  • 计蒜客T1461——校验信用卡号码

    如题 本题需要解决的本质就是多个字符串转换为整型数据的过程 主要的考点在于如下3个 1 循环输入多个字符串并不间断 2 将字符串处理为整型数据 3 完成对整形数据的检验 上述三个要求通过STL可以很轻松地解决 具体做法写在了代码注释之中 i
  • Unity3D 4.0新功能:Mecanim动画系统基础教程

    作为Unity4 0的主要更新功能 Mecanim动画被寄予了很多的期望 系统有先进的地方 也有不足的地方 这些我们留到最后再来总结 阿赵粗略的学习了一下 写下以下的教程 这篇教程简单的说明了Mecanim系统的用法和控制方式 里面用到的资
  • electron-vue中报错 Cannot use import statement outside a module解决方案(亲测有效!!!)

    错误 Cannot use import statement outside a module 不能在模块之外使用导入语句 原因 安装的某个依赖包里使用了import语法 因为我们打包输出的是commonjs规范 所以不识别import语法
  • 学习笔记 React(一)Hello React例子及创建虚拟DOM的两种方式

    React官网地址 React库 最基础的例子 官网 1 英文官网 https reactjs org 2 中文官网 https react docschina org React库 babel min js ES6 gt ES5 JSX
  • C++中函数原型和函数定义

    C 中函数原型和函数定义 C 函数原型指的是函数声明的语法形式 它告诉编译器函数的名称 返回类型和参数列表 函数原型的语法形式如下 return type function name parameter list 其中 return typ
  • 什么是强制缓存?什么是协商缓存?cache

    强制缓存和协商缓存是用于在Web浏览器和服务器之间进行缓存控制的两种机制 强制缓存 强缓存 强制缓存 强制缓存是通过设置HTTP响应头来实现的 它告诉浏览器在一定时间内直接使用缓存的副本 而不需要再向服务器发起请求 常见的强制缓存相关的响应
  • PHP Filter伪协议Trick总结

    PHP Filter伪协议Trick总结 前言 最近在学习的过程中碰到了很多的filter协议的小trick 在此做一个总结以及对filter协议的一些探索 PHP Filter协议介绍 php filter是php中独有的一种协议 它是一
  • 题目0010-数据分类

    数据分类 题目描述 对一个数据a进行分类 分类方法是 此数据a 4个字节大小 的4个字节相加对一个给定值b取模 如果得到的结果小于一个给定的值c则数据a为有效类型 其类型为取模的值 如果得到的结果大于或者等于c则数据a为无效类型 比如一个数
  • SpringBoot配置文件

    1 springboot提供两种配置文件类型 properties和yml yaml 2 默认配置文件名称 properties 3 在同一级目录下优先级为 peoperties gt yml gt yaml YAML定义 三种配置文件写法
  • java基于HuTool工具类ExcelWriter合并单元格

    HuTool工具类ExcelWriter合并单元格 基于HuTool工具类ExcelWriter合并单元格并且使用 jdk1 8 lambda表达式 效果如下 创建注解 import java lang annotation Element
  • 内核篇加载内核模块(Android10)

    一 开发前期准备 本文中使用的是linageOs源码中下载的oneplus3 安卓10内核源码进行研究测试 交叉编译链使用的是linageOs源码中的交叉编译链 lineageOs源码中oneplus3内核源码位置路径 home qiang
  • WebGIS开发入门

    目录 一 WebGIS 二 GIS背景 三 如何入门webgis开发 1 gis数据处理 2 gis数据服务发布 3 gis数据服务调用 4 gis数据渲染 四 WebGIS核心价值 五 webgis发展方向 六 gis开发就业方向 1 数
  • Javascript设计模式-06-代理模式

    Javascript设计模式 06 代理模式 简介 代理模式就是为其他对象提供一种代理 代用品或者占位符 以控制对这个对象的访问 代理对象角色内部含有对真实对象的引用 从而可以操作真实对象 同时代理对象提供与真实对象相同的接口 以便在任何时
  • 离散型制造企业如何选择MES系统?

    随着MES系统越来越被企业重视 并被运用到很多制造业中 MES对于制造企业来说 其所需要的要求是各不相同的 比如离散型制造企业 该如何选择MES系统呢 什么是离散型制造企业 离散型制造企业的产品往往由多个零件经过一系列并不连续的工序的加工最
  • EFM32 硬件I2C通讯案例

    前言 最近项目上用到了EFM32HG222F64G芯片中的硬件通讯 i2c通讯不稳定问题 导致花了很长时间去解决 走了不少弯路 最终还是解决了 在此写一下 做个记录 也方便给后面做产品的攻城狮 少走一些弯路吧 好了 进入正题 来个直接点 直