源:STM32F407的硬件I2C

我使用的是STM32的固件库。

硬件模块使用之前必须配置其参数,I2C的配置如下:

void IIC_Config(void)
{GPIO_InitTypeDef  GPIO_InitStructure;I2C_InitTypeDef I2C_InitStructure;RCC_ClocksTypeDef   rcc_clocks;/* GPIO Peripheral clock enable */RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2|RCC_APB1Periph_I2C3, ENABLE);/* Reset I2Cx IP */RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2|RCC_APB1Periph_I2C3, ENABLE);/* Release reset signal of I2Cx IP */RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2|RCC_APB1Periph_I2C3, DISABLE);/*I2C1 configuration*/GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); //注意,此处不能合并写成GPIO_PinSource6|GPIO_PinSource7
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);//PB6: I2C1_SCL  PB7: I2C1_SDAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;GPIO_Init(GPIOB, &GPIO_InitStructure);/* I2C Struct Initialize */I2C_DeInit(I2C1);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_ClockSpeed = 100000;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_Init(I2C1, &I2C_InitStructure);/* I2C Initialize */I2C_Cmd(I2C1, ENABLE);/*I2C2 configuration*/GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2); //注意,此处不能合并写成GPIO_PinSource6|GPIO_PinSource7
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);//PB10: I2C2_SCL  PB11: I2C2_SDAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;GPIO_Init(GPIOB, &GPIO_InitStructure);/* I2C Struct Initialize */I2C_DeInit(I2C2);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_ClockSpeed = 100000;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_Init(I2C2, &I2C_InitStructure);/* I2C Initialize */I2C_Cmd(I2C2, ENABLE);/*I2C3 configuration*/GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_I2C3);GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_I2C3);//PA8: I2C3_SCLGPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;GPIO_Init(GPIOA, &GPIO_InitStructure);//PC9: I2C3_SDAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_Init(GPIOC, &GPIO_InitStructure);/* I2C Struct Initialize */I2C_DeInit(I2C3);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_ClockSpeed = 100000;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_Init(I2C3, &I2C_InitStructure);/* I2C Initialize */I2C_Cmd(I2C3, ENABLE);/*超时设置*/RCC_GetClocksFreq(&rcc_clocks);ulTimeOut_Time = (rcc_clocks.SYSCLK_Frequency /10000);
}

注意,I2C一定要加上超时的设置,否则当IIC总线出错时,没有超时检测可能造成MCU卡死在这里。

STM32F407的硬件I2C读一个字节与STM32F103类似,代码如下:

unsigned char I2C_Err=0;
uint8_t I2C_ReadOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t Reg_addr)
{  uint8_t readout;u32 tmr;tmr = ulTimeOut_Time;while((--tmr)&&I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));if(tmr==0) I2C_Err = 1;I2C_GenerateSTART(I2Cx, ENABLE);//发送I2C的START信号,接口自动从从设备编程主设备tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)));if(tmr==0) I2C_Err = 1;I2C_Send7bitAddress(I2Cx,I2C_Addr,I2C_Direction_Transmitter);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)));if(tmr==0) I2C_Err = 1;I2C_SendData(I2Cx, Reg_addr);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)));if(tmr==0) I2C_Err = 1;I2C_GenerateSTART(I2Cx, ENABLE);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)));if(tmr==0) I2C_Err = 1;I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)));if(tmr==0) I2C_Err = 1; I2C_AcknowledgeConfig(I2Cx, DISABLE);I2C_GenerateSTOP(I2Cx, ENABLE);tmr = ulTimeOut_Time;while((--tmr)&&(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))));  /* EV7 */if(tmr==0) I2C_Err = 1;readout = I2C_ReceiveData(I2Cx);I2C_AcknowledgeConfig(I2Cx, ENABLE);return readout;
}

I2C_ReadOneByte函数输入参数有3个,分别是:I2Cx,表示使用的I2C编号,I2C_addr,表示从设备的I2C地址,reg_addr,表示要读取的从设备寄存器地址。I2C_ReadOneByte的返回值就是I2C总线上读取到的数据。读I2C数据后需要检查I2C_Err是否为0,若为0,表示读取I2C数据时出错(超时),读到的数据可能不正确。

向从设备写入一个字节的数据,代码如下:

unsigned char I2C_Err=0;
void I2C_WriteOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t Reg_addr,uint8_t value)
{u32 tmr;tmr = ulTimeOut_Time;while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));while((--tmr)&&I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));if(tmr==0) I2C_Err = 1;I2C_GenerateSTART(I2Cx, ENABLE);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))); if(tmr==0) I2C_Err = 1;I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)));if(tmr==0) I2C_Err = 1;I2C_SendData(I2Cx, Reg_addr);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)));if(tmr==0) I2C_Err = 1;I2C_SendData(I2Cx, value);tmr = ulTimeOut_Time;while((--tmr)&&(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)));if(tmr==0) I2C_Err = 1;I2C_GenerateSTOP(I2Cx, ENABLE);//I2C_AcknowledgeConfig(I2Cx, DISABLE);
}

写I2C函数比读仅多了一个输入参数,即要写入的数据。同理,在函数执行完成后,需要检查I2C_Err是否为0以判断I2C是否出错。

有了读1个字节和写入1个字节的函数,当需要一次性读或写多个数据时,可以在上述函数的基础上扩展多字节操作。

STM32F407的硬件I2C相关推荐

  1. STM32F407硬件I2C从机配置

    公司项目需要用到I2C从机与上位机通信.在网上搜了搜,发现大部分都是说STM32硬件有问题的,与硬件I2C从机相关的资料很少.调通之后,想着把demo分享出来,丰富一下网上的例程.STM32F1系列稍 ...

  2. STM32单片机硬件I2C驱动程序(查询方式)

    本文章原始地址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与接收. 本例程中采用I2C ...

  3. STM32F10x_硬件I2C读写EEPROM(标准外设库版本)

    Ⅰ.写在前面 上一篇文章是"STM32F10x_模拟I2C读写EEPROM",讲述使用IO口模拟I2C总线通信,对EEPROM(AT24Xxx)进行读写操作的过程. 上一篇文章主要 ...

  4. 关于 STM32 的硬件I2C

    首先转两个帖子 http://blog.csdn.net/mcu_hong/article/details/8149311 http://bbs.21ic.com/icview-184741-1-1. ...

  5. STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech

    感谢原作者:FeoTech   原文网址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与 ...

  6. vb6编写dll读取dat文件_【STM32Cube_15】使用硬件I2C读取温湿度传感器数据(SHT30)...

    寻求更好的阅读体验,请移步Mculover666的个人博客: [STM32Cube_15]使用硬件I2C读取温湿度传感器数据(SHT30)​www.mculover666.cn 本篇详细的记录了如何使 ...

  7. 串口助手驱动_STM32Cube22(补充) | 使用硬件I2C驱动OLED(SSD1306)

    点上方蓝字关注我们 每天都有好玩的东西等着你 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设驱动0.96'OLED屏幕. 1. 准备工作 硬件准备 开发板 ...

  8. bme280 环境传感器开发板_STM32Cube14 | 使用硬件I2C读写环境光强度传感器

    更多精彩~点击上面蓝字关注我们呀!   寻求更好的阅读体验,请点击阅读原文移步:Mculover666的个人博客. 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I ...

  9. 1.27 Cubemx_STM32H7 软\硬件I2C

    Cubemx_STM32H7 软\硬件I2C 1. I2C简介 1.1 I2C物理拓扑结构 1.2 I2C总线特征 1.3 I2C协议 1.4 I2C总线操作 1.5原理图 2.硬件IIC Cubem ...

最新文章

  1. 位运算的应用和分治法在二进制中的应用
  2. PostgreSQL和MySQL技术全面剖析
  3. matlab如何创建callback函数_如何学好MATLAB GUI
  4. C和汇编---sizeof运算符和strlen函数
  5. css块元素与行内元素特点,CSS区分块级元素和行内元素
  6. (并查集 建立关系)Parity game -- POJ -1733
  7. hiho一下第91周《Events Arrangement》(前半部分)
  8. 【运维安全】-sqlmap使用
  9. 字符串、数组处理方法总结
  10. 一般毕业论文的查重要求有哪些?
  11. groovy语言介绍
  12. 通过黑客代号带你回顾九位世界顶尖的黑客大咖
  13. 文件操作细致详解(下)
  14. SQL分组查询,结果只取最新记录
  15. matlab画十七边形,怎么样用尺规作图画正十七边形
  16. 面向对象系统分析——类图包图
  17. Bootstrap table设置列宽和固定表头
  18. iOS 如何设置启动引导图
  19. Android 10.0去掉前置摄像头闪光灯功能
  20. 电脑不小心删除的文件怎么恢复?

热门文章

  1. android开发Proguard混淆与反射
  2. Mongodb在Linux下的安装和启动和配置
  3. C++文件操作的6种方式
  4. PHP中的魔术方法总结 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __uns
  5. centos7 firewall指定IP与端口访问(常用)
  6. Oracle多行函数
  7. 垃圾回收算法简单介绍——JVM读书笔记lt;二gt;
  8. jetty启动源码分析
  9. SQL Server2000数据库文件损坏时如何恢复
  10. php目的,php umask(0)的目的是什么