感谢原作者:FeoTech   原文网址:http://feotech.com/?p=69

本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与接收.

本例程中采用I2C寄存器查询的方式来实现数据传输,当I2C对应寄存器指定状态时方可执行下一步操作.

/********************************************************************************* @file    Hardware_I2C.c * @author  Ryan Zhao* @version V1.0.0* @date    2017-04-27* @brief   STM32硬件I2C底层驱动.******************************************************************************* @attention   Null* *******************************************************************************//**
* @brief  I2C引脚与寄存器功能配置.
* @param  None.
* @retval None.
*/
void I2C_Configuration(void)
{/*GPIO与IIC初始化结构体*/  GPIO_InitTypeDef GPIO_InitStructure;  I2C_InitTypeDef I2C_InitStructure;  /*GPIO与IIC时钟使能*/  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );     //GPIOB时钟使能  RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE );      //I2C时钟使能  /*初始化GPIO*/  GPIO_InitStructure.GPIO_Pin =  HW_I2C_SDA_PIN | HW_I2C_SCL_PIN;   //初始化 IIC GPIO GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //最高输出速度50Hz  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;     //输入输出模式为复用功能开漏输出  GPIO_Init( GPIOB, &GPIO_InitStructure );            //根据GPIO初始化结构体初始化GPIOB  /*初始化I2C*/  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                  //设置为I2C模式  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;          //设置I2C的占空比,低电平除以高电平值为2  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                 //使能ACK信号  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   //指定7位地址  I2C_InitStructure.I2C_ClockSpeed = 400000;                  //时钟频率,必须小于等于400KHz  I2C_Cmd( HW_I2C, ENABLE );                                    //使能I2C I2C_Init( HW_I2C, &I2C_InitStructure );                       //根据I2C初始化结构体初始化I2C  /*允许一字节一应答模式*/  I2C_AcknowledgeConfig( HW_I2C, ENABLE );                      //使能I2C应答状态
}/**
* @brief  从I2C指定地址中读取数据;
* @param  读取的地址,读取后返回的数据;
* @retval 1:读取数据成功,0:读取数据无效;
*/
unsigned char  I2C_ReadByte(unsigned char Read_Address,unsigned char * Read_Data)
{ unsigned char wait_time_out = wait_time_value;//等待I2C器件响应的延时* Read_Data = 0;while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY))   //判断IIC接口状态.当IIC状态为BUSY时,一直停在这里循环  {if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}/*发送START之后要等待,意味着START条件被正确释放,此时IIC总线上没有其它外设*/  I2C_GenerateSTART( HW_I2C, ENABLE );                                          //产生START条件     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT))             //判断开始信号是否已经发送完成  {if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter );          //发送从机地址ADXL_WRITE以选择从机,主机为发送模式  while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))  //如果主机发射模式被选中(死循环等待从机发送ACK信号)  {if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}I2C_SendData(HW_I2C, Read_Address );                                         //将write_address,即要读的地址通过IIC2发送出去 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))         //如果地址已经从IIC成功发射出去(死循环等待ACK信号{if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}I2C_GenerateSTART(HW_I2C, ENABLE );                                            //产生START条件  while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT))                //如果主机被选中(死循环等待ACK信号){if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}/***主机接收数据***/  I2C_Send7bitAddress(HW_I2C, ADXL_READ, I2C_Direction_Receiver );              //主机设置为接收模式  while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))      //如果主机接收模式被选中(死循环等待ACK信号) {if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}I2C_AcknowledgeConfig(HW_I2C, DISABLE );                                        //失能IIC的应答状态 NACK  I2C_GenerateSTOP( HW_I2C, ENABLE );                                           //产生STOP条件  while (!(I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)))           //判断数据是否接收完成       {if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}I2C_AcknowledgeConfig(HW_I2C, ENABLE );                                      //再一次使能IIC的应答状态  * Read_Data = I2C_ReceiveData(HW_I2C);                                        //返回IIC接收的数据 return 1;
}/**
* @brief  通过I2C接口将数据写入从机指定地址中.
* @param  要写入的数据,接收数据的地址;
* @retval 1:数据写入成功 0:数据写入失败
*/
unsigned char  I2C_Write_Byte(uint8_t Point_Buffer,uint8_t Write_Address)
{unsigned char wait_time_out = wait_time_value;//等待I2C器件响应的延时while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY))   //判断当前I2C接口状态是否为Busy {if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}I2C_GenerateSTARTHW_I2C, ENABLE );                                          //产生Start信号  while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT))               //判断Start信号是否已经发送{if((wait_time_out --) == 0) //延时等待{return 0;   //响应超时,返回无效标志}}I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter );              //发送从机地址以选择从机,主机为发送模式  while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))   //判断发送的地址是否与从机匹配,等待从机发送ACK信号{if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}} I2C_SendData(HW_I2C, Write_Address );                                        //将write_address,即要写的寄存器地址通过IIC发送出去     while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))          //判断数据是否发送完成{if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}/*往寄存器发送数据data*/  I2C_SendData(HW_I2C, Point_Buffer );  while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))            //判断数据是否发送完成{if((wait_time_out --) == 0) //延时等待{return 0; //响应超时,返回无效标志}}I2C_GenerateSTOP( HW_I2C, ENABLE );                                           //IIC2产生STOP条件  return 1;//数据写入完成 1
}
/********************************************************************************* @file    Hardware_I2C.h * @author  Ryan Zhao* @version V1.0.0* @date    2017-04-27* @brief   STM32硬件I2C底层驱动.******************************************************************************* @attention   Null* *******************************************************************************//*********************I2C 物理层GPIO定义*******************/
#define HW_I2C                           I2C1       //第一组I2C接口
#define HW_I2C_SDA_PIN                   GPIO_Pin_7
#define HW_I2C_SDA_GPIO_PORT             GPIOB
#define HW_I2C_SCL_PIN                   GPIO_Pin_6
#define HW_I2C_SCL_GPIO_PORT             GPIOB
#define wait_time_value                  200         //等待I2C器件响应的延时

STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech相关推荐

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

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

  2. STM32单片机硬件I2C读取AHT10温湿度传感器数据

    STM32使用硬件IIC读取AHT10温湿度传感器的数据并显示在0.96寸OLED屏上. 我用的单片机是STM32F103C8T6,程序用的是ST标准库写的. STM32使用硬件I2C读取SHTC3温 ...

  3. STM32F 单片机硬件I2C Busy标志导致的I2C卡死的处理办法

    STM32F 单片机硬件I2C Busy标志导致的I2C卡死的处理办法 在调试多用户表的时候,发现如果人为短接I2C的SDA或SLK脚后,I2C的SR2的Busy标志将会置1,并且试了很多种办法也无法 ...

  4. STM32的硬件I2C与AT24C16

    刚学STM32的时候就听闻STM32的硬件I2C存在重大bug,会导致运行卡死在等待ACK的过程中,所以一直以来对其避而远之,转而以模拟I2C取代之.最近这段时间一直在用STM32 CubeMX,图形 ...

  5. STM32串口用中断还是用轮询

    1.从轮询到中断 很多同学都不喜欢用中断,而偏爱用轮询的操作方式. 这是不是和我们的天性有关呢?每个人都喜欢一切尽在掌握中,肯定都不喜欢被打断.我们常常都有这样的经验:正在跟别人说一件事,然后突然有个 ...

  6. 使用轮询方式进行ADC转换(野火STM32 MINI开发板)

    实验器材:野火STM32 MINI开发板 任务目标:利用ADC采集电位器的电压,并通过串口调试助手输出变化的电压值 任务内容:调整开发板上的滑动变阻器,将电压值通过开发板到PC进行显示 开发板原理图: ...

  7. STC8系列单片机硬件I2C使用教程(二)

    硬件I2C(中断方式)以STC8F2K08S2单片机为例 一.I2C相关的寄存器 二.I2C中断相关的寄存器 ① I2C中断源 ② I2C中断允许位 ③ I2C中断标志位 三.程序编写 ① 寄存器和相 ...

  8. 选中断还是轮询方式?深究其中的区别

    作者 | 肖遥 来源 | 技术让梦想更伟大 摸水了一周,准备在家里好好敲敲代码,赶赶稿子,正当我专心输出的时候,被老婆打断了. 娃拉臭了,赶紧过来!语气中带着一丝丝我害怕的味道. 怎么办?没办法只有过 ...

  9. DW1000开发笔记(五)DW1000使用轮询方式接收数据

    系列文章 DW1000开发笔记(一)DW1000芯片概览 DW1000开发笔记(二)使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信 DW1000开发笔记(三)基于STM ...

最新文章

  1. 网站发送邮件的邮箱服务器,教各位站长配置邮箱让网站能够发送Email邮件
  2. 新中大oracle实列名,新中大财务软件操作流程(完整版)
  3. leetcode62. 不同路径
  4. sqoop1.4.6导出oracle实例
  5. 异常:Caused by: java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()Z
  6. 域管理中经常用到的组策略禁止修改IP及计算机名
  7. 漫谈广告竞价模式(六)
  8. 酒的基金降幅较大,这是为什么?
  9. 厉害了我的Qunar!看我工程师写轮眼!
  10. 解决VS2015社区版无法下载许可证的问题
  11. win7备份工具_调解 win7系统一键还原精灵使用的具体方法 -win7系统使用教程
  12. zigbee Zstack 中串口操作的深度解析、一
  13. html 飘窗链接,飘窗html
  14. (转载)反垃圾邮件技术解析
  15. 关于印发《计算机技术与软件专业技术资格(水平)考试暂行规定》
  16. jQuery之文档就绪事件
  17. Android App性能流畅度测评分析可以用到工具
  18. pikachu XXE (XML外部实体注入)(皮卡丘漏洞平台通关系列)
  19. 渣渣本科的2021届秋招总结-泪目
  20. Cloudxns倒下,7月17日关闭域名解析,解析任务交给谁?

热门文章

  1. centos6.9下安装composer
  2. python-模块安装方法
  3. 解决canvas画图模糊的问题
  4. 工作是老板的,生命是自己的。
  5. jdbc excute方法理解的误区
  6. 一种新的穿透防火墙的数据传输技术
  7. Go 语言:我那么值钱,我骄傲了吗?
  8. CentOS VS Ubuntu,谁才是更好的 Linux 版本?
  9. 大牛推荐的10本学习 Python 的好书
  10. php底层实现也是c语言,深入php内核,从底层c语言剖析php实现原理