最近在做一个陀螺仪的项目用到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解析相关推荐

  1. 硬件I2C与模拟I2C

    硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C:一般也较为稳定,但是程序较为繁琐.硬件(固件)I2C是直接调用内部寄存器进行配 ...

  2. STC8A8K64单片机关于AT24C04基本读写操作(包含硬件I2C与软件模拟I2C)

    实验:AT24C04基本读写操作 步骤及现象:在下载程序前,选择stc-isp的IRC频率:12MHz. 程序下载完成后,在串口助手界面,HEX模式下,选择波 特率9600,然后点击"打开串 ...

  3. Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线

    在drivers/i2c/busses下包含各种I2C总线驱动,如S3C2440的I2C总线驱动i2c-s3c2410.c,使用GPIO模拟I2C总线的驱动i2c-gpio.c,这里只分析i2c-gp ...

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

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

  5. STM32 通用GPIO模拟I2C实现

    STM32 通用GPIO模拟I2C实现 通用GPIO模拟I2C通信实现样例 1 GPIO初始化 #ifdef HW_I2C1 //硬件I2C初始化//PA8-I2C1_SCLGPIO_StructIn ...

  6. i2c 驱动五:gpio模拟i2c

    有关linux的i2c相关文章有一下几篇,他们互相关联,应该一同看: - i2c 驱动一:简介 - i2c 驱动二:devfs文件系统 - i2c 驱动三:自己实现设备和驱动分离 - i2c 驱动四: ...

  7. 【龙芯1c库】封装模拟I2C接口和使用示例

    龙芯1c库是把龙芯1c的常用外设的常用功能封装为一个库,类似于STM32库.Git地址:https://gitee.com/caogos/OpenLoongsonLib1c I2C接口是常用的接口之一 ...

  8. linux串口读取mpu9250数据,模拟 I2C 读取 MPU9250 数据的测试笔记

    硬件:STM32F103ZET6 + GY9250 软件:Keil MDK(v5.27)+ STM32CUBEMX(v5.2.1) 这里我在使用STM32CUBEMX最新版本(v5.5.0)生成Kei ...

  9. Opencores上的i2c controller core代码解析

    Opencores上的i2c controller core代码解析 一.i2c_eeprom_test.v 二.i2c_master_top.v 三.i2c_master_byte_ctrl.v 四 ...

最新文章

  1. 基于Android的浮动组件,可以用于应用中的新功能展示等等。
  2. w10安装ubuntu_Win10 + Ubuntu 16.04双系统完美安装教程【详细】
  3. Celery介绍及常见错误
  4. 数据库每日一题 2020.05.21
  5. carplant_mxnet
  6. 第一:Python安装需要的第三方库时,命令行输入pip提示不是内部或外部命令
  7. 1.Jenkins 2 权威指南 --- 简介
  8. 国外动态住宅ip怎么使用?
  9. 大学计算机教程王梦倩,【经验共享】中国矿业大学资源学院辅导员王梦倩
  10. 【语音识别入门】Python音频处理示例(含完整代码)
  11. Android多窗口分屏(原生方法)
  12. 编译错误:In function `_sbrk_r‘:sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk‘
  13. VS2019不能安装的WIN10更新问题
  14. 在Ubuntu部署gitblit步骤
  15. Python全栈笔记(练习题,持续更新)
  16. 网上下载别人的vue项目如何运行在本地
  17. 中国主要湖泊水库面状矢量边界图层ArcGIS使用之二篇
  18. D3D12渲染技术之帧资源
  19. 怎样将Excel里的行和列隐藏和取消隐藏
  20. OJ每日一练——开关灯

热门文章

  1. 废品回收行业也用起了小程序?
  2. 宝德服务器 raid制作,宝德服务器RAID设置
  3. 五款非常有趣的手机APP你都知道吗
  4. 信用风险评分模型开发流程
  5. CRC16 Modbus计算原理与代码实现
  6. opencv调试-内存泄露
  7. 阿灰-工作一年工作总结-2021-07-02
  8. 【论文笔记 fintune 】羊驼
  9. 亲,你有一份 ChatGPT4 的体验机会待查收! 一站式 AI 工具箱 - Poe 介绍
  10. 音乐数据库Genius控搜寻结果盗用该站歌词