概述

最近搞项目使用了EFM32这款单片机,感觉硬件I2C还是不够灵活,这次改成了模拟I2C方式通讯。

需要创建两个文件:i2c.h和i2c.c

以下是i2c.h文件实例代码:

#ifndef __IIC_H
#define __IIC_H
#include <stdint.h>void i2c_read(uint8_t addr, uint8_t reg, uint8_t* buf, uint32_t len);
void i2c_write(uint8_t addr, uint8_t reg, uint8_t* buf, uint32_t len);

以下是i2c.c文件实例代码:

#include "i2c.h"
#include <stdint.h>
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"#define SCK_TIME    2#define ACK_TIME    3#define START_TIME  5/* Using PA0 (SDA) and PA1 (SCL) */#define gpio_direction_input(a) \if(#a=="SDA")  \{              \GPIO_PinModeSet(gpioPortA, 0, gpioModeInput, 1); \}                #define gpio_direction_output(a,b) \if(#a=="SDA")   \{              \GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, b); \}             \else if(#a=="SCL")         \{              \GPIO_PinModeSet(gpioPortA, 1, gpioModePushPull, b); \}#define  gpio_set_value(a,b) \if(#a=="SDA")  \{              \if(b==1) GPIO_PinOutSet(gpioPortA,0);       \else if(b==0) GPIO_PinOutClear(gpioPortA,0);\}                \else if(#a=="SCL")         \{              \if(b==1) GPIO_PinOutSet(gpioPortA,1);       \else if(b==0) GPIO_PinOutClear(gpioPortA,1);\}\#define SDA   0
#define SCL   1
static uint8_t gpio_get_value(uint8_t sd) { return GPIO_PinInGet(gpioPortA, 0); } static void udelay(uint32_t t)
{for(; t!=0; t--);
}static void i2c_start(void)
{gpio_direction_output(SDA, 1);gpio_direction_output(SCL, 1);udelay(SCK_TIME);gpio_set_value(SDA, 0);udelay(START_TIME);gpio_set_value(SCL, 0);
}static void i2c_stop(void)
{udelay(SCK_TIME);gpio_direction_output(SDA, 0);gpio_set_value(SCL, 1);udelay(SCK_TIME);gpio_set_value(SDA, 1);
}static uint8_t i2c_read_ack(void)
{uint8_t r; gpio_direction_input(SDA);  udelay(ACK_TIME);gpio_set_value(SCL,1);udelay(1);r = gpio_get_value(SDA);   udelay(1);gpio_set_value(SCL,0);return r;
}static void i2c_send_ack(void)
{udelay(SCK_TIME);gpio_direction_output(SDA, 1);gpio_set_value(SCL,1);udelay(SCK_TIME);gpio_set_value(SCL,0);
}static void i2c_write_byte(uint8_t b)
{int i;for (i=7; i>=0; i--) {udelay(SCK_TIME);gpio_direction_output(SDA, b & (1<<i));udelay(SCK_TIME - 2);gpio_set_value(SCL, 1);udelay(SCK_TIME);gpio_set_value(SCL, 0);}i2c_read_ack();
}static uint8_t i2c_read_byte(void)
{int i;uint8_t r = 0;gpio_direction_input(SDA); for (i=7; i>=0; i--) {udelay(SCK_TIME * 5);gpio_set_value(SCL, 1);r |= (gpio_get_value(SDA) << i);udelay(SCK_TIME * 5);gpio_set_value(SCL, 0);}i2c_send_ack();return r;
}void i2c_read(uint8_t addr, uint8_t reg,uint8_t* buf, uint32_t len)
{uint8_t i,t;i2c_start();t = (addr << 1) | 0;i2c_write_byte(t);i2c_write_byte(reg);i2c_start();t = (addr << 1) | 1;i2c_write_byte(t);for (i=0; i<len; i++)buf[i] = i2c_read_byte();i2c_stop();
}void i2c_write(uint8_t addr, uint8_t reg, uint8_t* buf, uint32_t len)
{uint8_t i,t;i2c_start();t = (addr << 1) | 0;i2c_write_byte(t);i2c_write_byte(reg);for (i=0; i<len; i++)i2c_write_byte(buf[i]);i2c_stop();
}

测试

测试案例:(注,我这里使用了MPU9250  9轴传感器)void main(void)
{uint8_t res = 0;uint8_t buf[] = {0};buf[0] = 0x22;while(1){i2c_write(MPU9250_ADDR,MPU_INTBP_CFG_REG, buf, 1);delay_ms(1000);i2c_read(MPU9250_ADDR,MPU_INTBP_CFG_REG,&res,1);printf(" res : %d \r\n", res);}}

EFM32 模拟I2C通讯案例(一)相关推荐

  1. 单片机GPIO软件模拟I2C通讯程序

    文章原始地址:http://feotech.com/?p=98 本程序主要用于使用可编程芯片自身的IO管脚,模拟I2C通信的协议,实现I2C总线数据的传输. /******************** ...

  2. STM32F0+模拟I2C通讯

    所谓的硬件I2C就是STM32芯片上有其相应的外设和驱动电路,通过配置相应的寄存器,就可以完成I2C的通信.本节实验我们介绍软件模拟I2C,软件I2C一般是通过GPIO引脚,按照I2C的时序要求来控制 ...

  3. 外设驱动库开发笔记8:GPIO模拟I2C驱动

    I2C总线简单方便,是我们经常使用的一种总线.但有时候我们的MCU没有足够多的I2C控制器来实现我们的应用,所幸我可以使用普通的GPIO引脚来模拟低速的I2C总线通信.这一节我们就来实现使用软件通过普 ...

  4. STM32使用模拟I2C读取硒翔30mL流量传感器

    使用模拟I2C读取硒翔30mL/min流量传感器 该工程使用某些采样次数和时间不同会采集到的报文有问题. 我建议是可以换个次数和时间调下. 如果报文有问题的话 就修改延时就好了,延时指的是I2C每发送 ...

  5. I2C软件模拟EEPROM通讯实验

    I2C是一种串行通讯总线,由于只有串行数据线SDA和串行时钟线SCL两个总线而被广泛使用. I2C软件模拟通信的本质是用芯片上任意两个引脚模拟I2C通信,也就是说通过控制任意两个引脚电平的高低变化来模 ...

  6. I2C通讯过程中SDA被一直拉低

    I2C通讯过程中SDA被一直拉低 一.现象 二.分析原因 2.1 正常情况该部分数据 正常情况slave返回一个byte数据:0x00(该字节8bit都是0) 2.2 异常发生时该部分数据 出现该情况 ...

  7. GPIO模拟I2C程序实现

    GPIO模拟I2C程序实现. I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA).I2C是总线结构,1个 ...

  8. S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动

    目录:一. 说明 二. 驱动程序说明及问题 三. 案例一       四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...

  9. 关于stm32通信协议:软件模拟SPI、软件模拟I2C的总结(fishing_8)

    趁着帮老师代上嵌入式实验课的机会,又重新熟悉了一遍stm32的通信协议:串口协议.SPI协议.I2C协议.RS485协议.大概半年前,是过了一遍的,但也只停留于读了遍代码,跑了下例程,最近又过了一遍( ...

最新文章

  1. 怎么用计算机计算出选手最后得分,计算选手最后得分(限制分的值,且最后按n或N键结束,其他键继续)...
  2. python 多维数组删除重复
  3. 避免表格table被撑开变形的CSS代码实例
  4. github不用输入用户密码即可登录
  5. java左移、右移、无符号右移
  6. 2.3.5 操作系统之信号量机制实现进程的互斥、同步与前驱关系
  7. Mac插件分享——AE插件、PS插件、FCPX插件【持续更新中】
  8. (转)Spring Boot(四):Thymeleaf 使用详解
  9. python中split函数源代码_Pandas.split()函数用法及源码
  10. 脚本制作Minilinux
  11. Cassandra 之旅 (二) Getting Started
  12. NYOJ--71--独木舟上的旅行
  13. IJCAI2021 Person Re-identification相关论文集合推荐
  14. 2020年11月 工信部考试——Hadoop(数据应用技术)中级认证3
  15. mac SCp上传文件到阿里云服务器centos
  16. 用于说明卷积神经网络(ConvNet)的Python脚本
  17. android 手机强制关机代码,安卓手机强制重启方法
  18. xps文件的基本操作
  19. 东北大学acm暑期夏令营第七天
  20. 网站右侧广告悬浮代码html,js网站广告悬浮代码

热门文章

  1. 怪物猎人ol服务器维护,怪物猎人OL什么时候关服_2019年停运时间公布
  2. 每日一练———C语言算法题--平年闰年问题
  3. 论文阅读 - SegFormer
  4. edis面试刁难大全
  5. 电商第一站致力于电子商务职业经理人培养!
  6. 如何使用ChatGPT辅助AI绘画?
  7. 给即将创业者的建议:千万不要为当老板而去创业【转摘】
  8. 如何利用SEO技术设置文章网页标题
  9. “实现能力”与“设计能力”
  10. 如何防止开发者选项关闭动画后使其失效