STM32F407的硬件I2C
源: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相关推荐
- STM32F407硬件I2C从机配置
公司项目需要用到I2C从机与上位机通信.在网上搜了搜,发现大部分都是说STM32硬件有问题的,与硬件I2C从机相关的资料很少.调通之后,想着把demo分享出来,丰富一下网上的例程.STM32F1系列稍 ...
- STM32单片机硬件I2C驱动程序(查询方式)
本文章原始地址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与接收. 本例程中采用I2C ...
- STM32F10x_硬件I2C读写EEPROM(标准外设库版本)
Ⅰ.写在前面 上一篇文章是"STM32F10x_模拟I2C读写EEPROM",讲述使用IO口模拟I2C总线通信,对EEPROM(AT24Xxx)进行读写操作的过程. 上一篇文章主要 ...
- 关于 STM32 的硬件I2C
首先转两个帖子 http://blog.csdn.net/mcu_hong/article/details/8149311 http://bbs.21ic.com/icview-184741-1-1. ...
- STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech
感谢原作者:FeoTech 原文网址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与 ...
- vb6编写dll读取dat文件_【STM32Cube_15】使用硬件I2C读取温湿度传感器数据(SHT30)...
寻求更好的阅读体验,请移步Mculover666的个人博客: [STM32Cube_15]使用硬件I2C读取温湿度传感器数据(SHT30)www.mculover666.cn 本篇详细的记录了如何使 ...
- 串口助手驱动_STM32Cube22(补充) | 使用硬件I2C驱动OLED(SSD1306)
点上方蓝字关注我们 每天都有好玩的东西等着你 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设驱动0.96'OLED屏幕. 1. 准备工作 硬件准备 开发板 ...
- bme280 环境传感器开发板_STM32Cube14 | 使用硬件I2C读写环境光强度传感器
更多精彩~点击上面蓝字关注我们呀! 寻求更好的阅读体验,请点击阅读原文移步:Mculover666的个人博客. 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I ...
- 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 ...
最新文章
- 位运算的应用和分治法在二进制中的应用
- PostgreSQL和MySQL技术全面剖析
- matlab如何创建callback函数_如何学好MATLAB GUI
- C和汇编---sizeof运算符和strlen函数
- css块元素与行内元素特点,CSS区分块级元素和行内元素
- (并查集 建立关系)Parity game -- POJ -1733
- hiho一下第91周《Events Arrangement》(前半部分)
- 【运维安全】-sqlmap使用
- 字符串、数组处理方法总结
- 一般毕业论文的查重要求有哪些?
- groovy语言介绍
- 通过黑客代号带你回顾九位世界顶尖的黑客大咖
- 文件操作细致详解(下)
- SQL分组查询,结果只取最新记录
- matlab画十七边形,怎么样用尺规作图画正十七边形
- 面向对象系统分析——类图包图
- Bootstrap table设置列宽和固定表头
- iOS 如何设置启动引导图
- Android 10.0去掉前置摄像头闪光灯功能
- 电脑不小心删除的文件怎么恢复?
热门文章
- android开发Proguard混淆与反射
- Mongodb在Linux下的安装和启动和配置
- C++文件操作的6种方式
- PHP中的魔术方法总结 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __uns
- centos7 firewall指定IP与端口访问(常用)
- Oracle多行函数
- 垃圾回收算法简单介绍——JVM读书笔记lt;二gt;
- jetty启动源码分析
- SQL Server2000数据库文件损坏时如何恢复
- php目的,php umask(0)的目的是什么