硬件I2C与模拟I2C解析
最近在做一个陀螺仪的项目用到I2C接口,STM32cubeMX自己生成的I2C驱动使用的是硬件I2C,HAL库函数直接调用即可。在读取24C02的时候没什么问题,可以直接用。但是在和mpu9250通讯的时候似乎有点问题,DMP自检总是通不过,后来改为模拟I2C后解决。也有可能是HAL库版本的问题,stm32cubeMX生成的代码中没有找到库版本的说明。
下面对模拟I2C的代码分析
I2C IO口宏定义
#define IIC_SCL PHout(4) //SCL
#define IIC_SDA PHout(5) //SDA
#define READ_SDA PHin(5) //输入SDA
#define SDA_IN() {GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=0<<5*2;} //PH5输入模式
#define SDA_OUT() {GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=1<<5*2;} //PH5输出模式
以I2C写为例,基本上就是将SCL、SDA引脚配置为IO输出模式,按时序要求有规律的控制SCL、和SDA引脚高低变化。I2C总线协议示意图如下:
发送一个Byte的完整过程如下:
u8 MPU_Write_Byte(u8 addr,u8 reg,u8 data)
{IIC_Start(); //起始时序IIC_Send_Byte((addr<<1)|0); //发送器件地址+写命令if(IIC_Wait_Ack()) //等待应答{IIC_Stop();return 1; //无应答退出}IIC_Send_Byte(reg); //写寄存器地址IIC_Wait_Ack(); //等待应答IIC_Send_Byte(data); //发送数据if(IIC_Wait_Ack()) //等待ACK{IIC_Stop();return 1; //无应答退出}IIC_Stop();return 0;
}
各子函数实际上也是按要求的SCL、SDA,这两个IO口读写过程
void IIC_Start(void)
{SDA_OUT(); //sda线输出IIC_SDA=1; IIC_SCL=1;delay_us(4);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
} /**********************************************************************/
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL=1; delay_us(4); IIC_SDA=1;//发送I2C总线结束信号
}/**********************************************************************/
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//时钟输出0 return 0;
}/**********************************************************************/
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}/**********************************************************************/
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
} /**********************************************************************/
void IIC_Send_Byte(u8 txd)
{ u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){ IIC_SDA=(txd&0x80)>>7;txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL=1;delay_us(2); IIC_SCL=0; delay_us(2);}
} /**********************************************************************/
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++; delay_us(1); } if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK return receive;
}
需要注意的是模拟I2C需要调用微秒级延时函数delay_us
代码参考,正点原子
硬件I2C与模拟I2C解析相关推荐
- 硬件I2C与模拟I2C
硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C:一般也较为稳定,但是程序较为繁琐.硬件(固件)I2C是直接调用内部寄存器进行配 ...
- STC8A8K64单片机关于AT24C04基本读写操作(包含硬件I2C与软件模拟I2C)
实验:AT24C04基本读写操作 步骤及现象:在下载程序前,选择stc-isp的IRC频率:12MHz. 程序下载完成后,在串口助手界面,HEX模式下,选择波 特率9600,然后点击"打开串 ...
- Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线
在drivers/i2c/busses下包含各种I2C总线驱动,如S3C2440的I2C总线驱动i2c-s3c2410.c,使用GPIO模拟I2C总线的驱动i2c-gpio.c,这里只分析i2c-gp ...
- S5PV210之GPIO模拟I2c时序之pcf8591与at24xx linux3.0.8驱动
目录:一. 说明 二. 驱动程序说明及问题 三. 案例一 四. 案例二 一. 说明 mini210开发板上带了at24c08, 看了linux内核自带的at24.c的驱动程序,编译下载到看 ...
- STM32 通用GPIO模拟I2C实现
STM32 通用GPIO模拟I2C实现 通用GPIO模拟I2C通信实现样例 1 GPIO初始化 #ifdef HW_I2C1 //硬件I2C初始化//PA8-I2C1_SCLGPIO_StructIn ...
- i2c 驱动五:gpio模拟i2c
有关linux的i2c相关文章有一下几篇,他们互相关联,应该一同看: - i2c 驱动一:简介 - i2c 驱动二:devfs文件系统 - i2c 驱动三:自己实现设备和驱动分离 - i2c 驱动四: ...
- 【龙芯1c库】封装模拟I2C接口和使用示例
龙芯1c库是把龙芯1c的常用外设的常用功能封装为一个库,类似于STM32库.Git地址:https://gitee.com/caogos/OpenLoongsonLib1c I2C接口是常用的接口之一 ...
- linux串口读取mpu9250数据,模拟 I2C 读取 MPU9250 数据的测试笔记
硬件:STM32F103ZET6 + GY9250 软件:Keil MDK(v5.27)+ STM32CUBEMX(v5.2.1) 这里我在使用STM32CUBEMX最新版本(v5.5.0)生成Kei ...
- Opencores上的i2c controller core代码解析
Opencores上的i2c controller core代码解析 一.i2c_eeprom_test.v 二.i2c_master_top.v 三.i2c_master_byte_ctrl.v 四 ...
最新文章
- 基于Android的浮动组件,可以用于应用中的新功能展示等等。
- w10安装ubuntu_Win10 + Ubuntu 16.04双系统完美安装教程【详细】
- Celery介绍及常见错误
- 数据库每日一题 2020.05.21
- carplant_mxnet
- 第一:Python安装需要的第三方库时,命令行输入pip提示不是内部或外部命令
- 1.Jenkins 2 权威指南 --- 简介
- 国外动态住宅ip怎么使用?
- 大学计算机教程王梦倩,【经验共享】中国矿业大学资源学院辅导员王梦倩
- 【语音识别入门】Python音频处理示例(含完整代码)
- Android多窗口分屏(原生方法)
- 编译错误:In function `_sbrk_r‘:sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk‘
- VS2019不能安装的WIN10更新问题
- 在Ubuntu部署gitblit步骤
- Python全栈笔记(练习题,持续更新)
- 网上下载别人的vue项目如何运行在本地
- 中国主要湖泊水库面状矢量边界图层ArcGIS使用之二篇
- D3D12渲染技术之帧资源
- 怎样将Excel里的行和列隐藏和取消隐藏
- OJ每日一练——开关灯