EFM32 模拟I2C通讯案例(一)
概述
最近搞项目使用了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通讯案例(一)相关推荐
- 单片机GPIO软件模拟I2C通讯程序
文章原始地址:http://feotech.com/?p=98 本程序主要用于使用可编程芯片自身的IO管脚,模拟I2C通信的协议,实现I2C总线数据的传输. /******************** ...
- STM32F0+模拟I2C通讯
所谓的硬件I2C就是STM32芯片上有其相应的外设和驱动电路,通过配置相应的寄存器,就可以完成I2C的通信.本节实验我们介绍软件模拟I2C,软件I2C一般是通过GPIO引脚,按照I2C的时序要求来控制 ...
- 外设驱动库开发笔记8:GPIO模拟I2C驱动
I2C总线简单方便,是我们经常使用的一种总线.但有时候我们的MCU没有足够多的I2C控制器来实现我们的应用,所幸我可以使用普通的GPIO引脚来模拟低速的I2C总线通信.这一节我们就来实现使用软件通过普 ...
- STM32使用模拟I2C读取硒翔30mL流量传感器
使用模拟I2C读取硒翔30mL/min流量传感器 该工程使用某些采样次数和时间不同会采集到的报文有问题. 我建议是可以换个次数和时间调下. 如果报文有问题的话 就修改延时就好了,延时指的是I2C每发送 ...
- I2C软件模拟EEPROM通讯实验
I2C是一种串行通讯总线,由于只有串行数据线SDA和串行时钟线SCL两个总线而被广泛使用. I2C软件模拟通信的本质是用芯片上任意两个引脚模拟I2C通信,也就是说通过控制任意两个引脚电平的高低变化来模 ...
- I2C通讯过程中SDA被一直拉低
I2C通讯过程中SDA被一直拉低 一.现象 二.分析原因 2.1 正常情况该部分数据 正常情况slave返回一个byte数据:0x00(该字节8bit都是0) 2.2 异常发生时该部分数据 出现该情况 ...
- GPIO模拟I2C程序实现
GPIO模拟I2C程序实现. I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA).I2C是总线结构,1个 ...
- S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动
目录:一. 说明 二. 驱动程序说明及问题 三. 案例一 四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...
- 关于stm32通信协议:软件模拟SPI、软件模拟I2C的总结(fishing_8)
趁着帮老师代上嵌入式实验课的机会,又重新熟悉了一遍stm32的通信协议:串口协议.SPI协议.I2C协议.RS485协议.大概半年前,是过了一遍的,但也只停留于读了遍代码,跑了下例程,最近又过了一遍( ...
最新文章
- 怎么用计算机计算出选手最后得分,计算选手最后得分(限制分的值,且最后按n或N键结束,其他键继续)...
- python 多维数组删除重复
- 避免表格table被撑开变形的CSS代码实例
- github不用输入用户密码即可登录
- java左移、右移、无符号右移
- 2.3.5 操作系统之信号量机制实现进程的互斥、同步与前驱关系
- Mac插件分享——AE插件、PS插件、FCPX插件【持续更新中】
- (转)Spring Boot(四):Thymeleaf 使用详解
- python中split函数源代码_Pandas.split()函数用法及源码
- 脚本制作Minilinux
- Cassandra 之旅 (二) Getting Started
- NYOJ--71--独木舟上的旅行
- IJCAI2021 Person Re-identification相关论文集合推荐
- 2020年11月 工信部考试——Hadoop(数据应用技术)中级认证3
- mac SCp上传文件到阿里云服务器centos
- 用于说明卷积神经网络(ConvNet)的Python脚本
- android 手机强制关机代码,安卓手机强制重启方法
- xps文件的基本操作
- 东北大学acm暑期夏令营第七天
- 网站右侧广告悬浮代码html,js网站广告悬浮代码