你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 36707|回复: 66

[STM32F030] 【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(...

  [复制链接]

40

主题

1595

回帖

1

蝴蝶豆

论坛元老

最后登录
2018-7-23
发表于 2014-1-26 15:16:58 | 显示全部楼层 |阅读模式
上次给大家分享了STM32I2C结构体中的时间寄存器配置工具的使用(【STM32F030开发日志/评测/笔记】+(1)STM32F0处理器I2C时间配置工具使用),为了测试STM32F0I2C总线库变成,今天给大家分享一下I2C操作气压传感器BMP085的程序,至于完整的BMP085的说明文档及完整的程序,我放在附件中。
实现具体功能:STM32F030使用I2C1接口与BMP085通信,每个0.5s采集一次温度和气压值,然后通过USART1传送到电脑的SerialChart上,绘制曲线。
下图是用SerialChart接收到的气压和温度数据及曲线,绿色曲线是温度14.2度(温度值需要除10),红色曲线气压1.009MPa
气压-温度.png

下图是用逻辑分析仪采集的I2C波形。
I2C.png

若要使用STM32F0操作硬件I2C外设,可使用下面的步骤。

1、配置GPIO引脚功能
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_1);
  
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_1);

2、初始化I2C外设
  I2C_InitTypeDef I2C_InitStructure;
  
  RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
  I2C_InitStructure.I2C_DigitalFilter = 0x01;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_Timing = 0x30E32E44;
  I2C_Init(I2C1, &I2C_InitStructure);
  
  I2C_Cmd(I2C1, ENABLE);

3、调用I2C的外设库函数进行读写I2C
我采用的是查询方式
主要使用的库函数有:
Avoid I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode)
Buint8_t I2C_ReceiveData  ( I2C_TypeDef *  I2Cx )  
Cvoid I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)
详细说明可看标准外设库帮助文档。

1I2C设备读数据程序段
/**
  * @brief  I2C1总线上的某一器件的某一起始地址中读取一定字节的数据到数组中
  * @param  driver_AddrI2C器件地址
  * @param  start_Addr:起始字节地址
  * @param  number_Bytes:要读取的字节数量(小于一页)
  * @param  read_Buffer:存放读取数据的数组指针
  * @retval 是否读取成功
  */
I2C_Status I2C1_Read_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *read_Buffer)
{
  uint8_t read_Num;
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
  
  I2C_TransferHandling(I2C1, driver_Addr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
  
  I2C_SendData(I2C1, start_Addr);
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
  
  I2C_TransferHandling(I2C1, driver_Addr, number_Bytes,  I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
  
  for(read_Num = 0; read_Num < number_Bytes; read_Num++)
  {
    I2C_Timeout = I2C_TIMEOUT;
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
    {
      if((I2C_Timeout--) == 0)
      {
        return I2C_FAIL;
      }
    }
   
    read_Buffer[read_Num] = I2C_ReceiveData(I2C1);
  }
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }

  return I2C_OK;
}


2I2C设备写数据程序段
/**
  * @brief  I2C1的总线上的某一器件的某一起始地址中读取一定字节的数据到数组中
  * @param  driver_AddrI2C器件地址
  * @param  start_Addr:起始字节地址
  * @param  number_Bytes:要读取的字节数量(小于一页)
  * @param  write_Buffer:存放读取数据的数组指针
  * @retval 是否读取成功
  */
I2C_Status I2C1_Write_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *write_Buffer)
{
  uint8_t write_Num;
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
  
  I2C_TransferHandling(I2C1, driver_Addr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }
  
  I2C_SendData(I2C1, start_Addr);
  
  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TCR) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }

  I2C_TransferHandling(I2C1, driver_Addr, number_Bytes, I2C_AutoEnd_Mode, I2C_No_StartStop);
  
  for(write_Num = 0; write_Num < number_Bytes; write_Num++)
  {
    I2C_Timeout = I2C_TIMEOUT;
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET)
    {
      if((I2C_Timeout--) == 0)
      {
        return I2C_FAIL;
      }
    }
   
    I2C_SendData(I2C1, write_Buffer[write_Num]);
  }

  I2C_Timeout = I2C_TIMEOUT;
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET)
  {
    if((I2C_Timeout--) == 0)
    {
      return I2C_FAIL;
    }
  }

  return I2C_OK;
}

STM32F030_BMP085.rar

下载

541.18 KB, 下载次数: 2770, 下载积分: ST金币 -1

BMP085.pdf

下载

822.98 KB, 下载次数: 863, 下载积分: ST金币 -1

评分

参与人数 1ST金币 -1 收起 理由
superta2008 -1 很给力!

查看全部评分

回复

使用道具 举报

307

主题

3125

回帖

0

蝴蝶豆

论坛元老

最后登录
2020-7-17
发表于 2014-2-27 13:07:51 | 显示全部楼层

回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)

回复 支持 反对

使用道具 举报

0

主题

1

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2014-2-28 16:17:54 | 显示全部楼层

回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)

帮了大忙了
回复 支持 反对

使用道具 举报

0

主题

1

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2014-3-5 11:27:27 | 显示全部楼层

RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)

请问有关I2C中断主从收发,能不能讲解指点一下呀?
回复 支持 反对

使用道具 举报

1

主题

59

回帖

0

蝴蝶豆

中级会员

最后登录
2020-10-22
发表于 2014-4-18 09:47:19 | 显示全部楼层

RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)

谢谢分享
回复 支持 反对

使用道具 举报

1

主题

23

回帖

2

蝴蝶豆

中级会员

最后登录
2020-4-14
发表于 2014-5-5 14:02:34 | 显示全部楼层

RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)

谢谢分享,学习一下
回复 支持 反对

使用道具 举报

0

主题

11

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2014-8-23 12:44:46 | 显示全部楼层

回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)

硬件I2C不需要管SCL,SDA的时序问题吗
回复 支持 反对

使用道具 举报

0

主题

10

回帖

0

蝴蝶豆

新手上路

最后登录
2015-1-7
发表于 2015-1-7 21:46:31 | 显示全部楼层
顶顶顶顶顶顶顶顶顶顶顶顶顶顶
回复 支持 反对

使用道具 举报

40

主题

1595

回帖

1

蝴蝶豆

论坛元老

最后登录
2018-7-23
 楼主| 发表于 2015-1-9 09:41:54 | 显示全部楼层
youyou202 发表于 2014-8-23 12:44
硬件I2C不需要管SCL,SDA的时序问题吗

硬件I2C使用片内外设发送时序,当然你还是要对I2C时序非常清楚,片内外设在发送数据时,不同的时间会置不同的标志位,编程通过判断标志位的状态就来决定下一步的工作。
回复 支持 反对

使用道具 举报

0

主题

4

回帖

0

蝴蝶豆

新手上路

最后登录
2015-1-9
发表于 2015-1-9 10:17:37 | 显示全部楼层
学习了,可以看看!
回复 支持 反对

使用道具 举报

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版