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

STM32模拟IIC程序--SI7020验证

[复制链接]
haifeng-388081 发布时间:2017-12-22 17:07
使用STM32F030C8T6普通IO口模拟IIC程序,已经实验验证可以使用。使用时请修改相应的管脚和延时函数即可。各个函数在程序中有备注就不一一说明了。还有一个是使用IIC读SI7020的示例程序。大家可以去使用。 QQ截图20171222170728.jpg
si7020_iic.h

  1. #ifndef __SI7020_IIC_H
  2. #define __SI7020_IIC_H
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <stm32f1xx.h>
  6. //////////////////////////////////////////////////////////////////////////////////         
  7. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  8. //IIC 驱动函数头文件          
  9. //使用普通IO口模拟IIC
  10. //////////////////////////////////////////////////////////////////////////////////

  11. typedef enum
  12. {
  13.         NACK = 0,
  14.         ACK =! NACK,
  15. } AckStatus;
  16. #define SI7020_IIC_SDA_CLK    RCC_APB2Periph_GPIOB
  17. #define SI7020_IIC_SDA_PORT   GPIOB
  18. #define SI7020_IIC_SDA_PIN    GPIO_PIN_5

  19. #define SI7020_IIC_SCL_CLK    RCC_APB2Periph_GPIOB
  20. #define SI7020_IIC_SCL_PORT   GPIOB
  21. #define SI7020_IIC_SCL_PIN    GPIO_PIN_6
  22.                                 
  23. //IO方向设置
  24. #define SET_SI7020_IIC_SDA_PIN()     HAL_GPIO_WritePin(SI7020_IIC_SDA_PORT,SI7020_IIC_SDA_PIN,GPIO_PIN_SET)
  25. #define RESET_SI7020_IIC_SDA_PIN()   HAL_GPIO_WritePin(SI7020_IIC_SDA_PORT,SI7020_IIC_SDA_PIN,GPIO_PIN_RESET)

  26. #define SET_SI7020_IIC_SCL_PIN()     HAL_GPIO_WritePin(SI7020_IIC_SCL_PORT,SI7020_IIC_SCL_PIN,GPIO_PIN_SET)
  27. #define RESET_SI7020_IIC_SCL_PIN()   HAL_GPIO_WritePin(SI7020_IIC_SCL_PORT,SI7020_IIC_SCL_PIN,GPIO_PIN_RESET)
  28.    
  29. //IIC所有操作函数
  30. void delay(unsigned int j);
  31. void SI7020_IIC_Init(void);                //初始化IIC的IO口                                 
  32. void SI7020_IIC_Start(void);                                //发送IIC开始信号
  33. void SI7020_IIC_Stop(void);                                  //发送IIC停止信号
  34. void SI7020_IIC_Send_Byte(uint8_t txd);                        //IIC发送一个字节
  35. uint8_t SI7020_IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
  36. uint8_t SI7020_IIC_Wait_Ack(void);                                 //IIC等待ACK信号
  37. void SI7020_IIC_Ack(void);                                        //IIC发送ACK信号
  38. void SI7020_IIC_NAck(void);                                //IIC不发送ACK信号  
  39. #endif
复制代码
si7020_iic.c

  1. #include "Hal_SI7020_IIC/si7020_iic.h"
  2. #include "delay/delay.h"
  3. #include "common.h"
  4. //////////////////////////////////////////////////////////////////////////////////         
  5. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  6. //IIC 驱动函数          
  7. //使用普通IO口模拟IIC
  8. //请根据程序修改相应头文件和延时函数。
  9. //////////////////////////////////////////////////////////////////////////////////
  10. //延时函数如果需要修改请修改此处:us
  11. void _delay_us(uint32_t us)
  12. {
  13.         delay_us(us);
  14. }
  15. void SI7020_IIC_Init(void)
  16. {                                             
  17.         GPIO_InitTypeDef GPIO_InitStructure;
  18.         __HAL_RCC_GPIOB_CLK_ENABLE();
  19.        
  20.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  21.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  22.     GPIO_InitStructure.Pin = SI7020_IIC_SDA_PIN;
  23.     HAL_GPIO_Init(SI7020_IIC_SDA_PORT, &GPIO_InitStructure);
  24.        
  25.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  26.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  27.     GPIO_InitStructure.Pin = SI7020_IIC_SCL_PIN;
  28.     HAL_GPIO_Init(SI7020_IIC_SCL_PORT, &GPIO_InitStructure);

  29.         HAL_GPIO_WritePin(SI7020_IIC_SDA_PORT,SI7020_IIC_SDA_PIN,GPIO_PIN_SET);
  30.         HAL_GPIO_WritePin(SI7020_IIC_SCL_PORT,SI7020_IIC_SCL_PIN,GPIO_PIN_SET);

  31. }
  32. void SI7020_SDA_IN()
  33. {
  34.         GPIO_InitTypeDef GPIO_InitStructure;
  35.         __HAL_RCC_GPIOB_CLK_ENABLE();
  36.     GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  37.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  38.     GPIO_InitStructure.Pin = SI7020_IIC_SDA_PIN;
  39.     HAL_GPIO_Init(SI7020_IIC_SDA_PORT, &GPIO_InitStructure);
  40. }
  41. void SI7020_SDA_OUT()
  42. {
  43.         GPIO_InitTypeDef GPIO_InitStructure;
  44.         __HAL_RCC_GPIOB_CLK_ENABLE();
  45.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  46.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  47.     GPIO_InitStructure.Pin = SI7020_IIC_SDA_PIN;
  48.     HAL_GPIO_Init(SI7020_IIC_SDA_PORT, &GPIO_InitStructure);
  49. }

  50. //产生IIC起始信号
  51. void SI7020_IIC_Start(void)
  52. {
  53.         SI7020_SDA_OUT();     //sda线输出
  54.         SET_SI7020_IIC_SCL_PIN();
  55.         SET_SI7020_IIC_SDA_PIN();
  56.         _delay_us(3);
  57.         RESET_SI7020_IIC_SDA_PIN();
  58.         _delay_us(3);
  59.         RESET_SI7020_IIC_SCL_PIN(); //钳住I2C总线,准备发送或接收数据
  60.         _delay_us(3);
  61. }          
  62. //产生IIC停止信号
  63. void SI7020_IIC_Stop(void)
  64. {
  65.         SI7020_SDA_OUT();//sda线输出
  66.         RESET_SI7020_IIC_SDA_PIN();
  67.         SET_SI7020_IIC_SCL_PIN();
  68.         _delay_us(4);
  69.         SET_SI7020_IIC_SDA_PIN();
  70.         _delay_us(4);                                                                  
  71. }
  72. //等待应答信号到来
  73. //返回值:ACK,接收到应答
  74. //        NACK,未接收到应答
  75. uint8_t SI7020_IIC_Wait_Ack(void)
  76. {
  77.         uint8_t ucErrTime=0;
  78.         SI7020_SDA_IN();      //SDA设置为输入   
  79.         SET_SI7020_IIC_SCL_PIN();
  80.         _delay_us(5);         
  81. //        while(HAL_GPIO_ReadPin((GPIO_TypeDef*)SI7020_IIC_SDA_PORT,SI7020_IIC_SDA_PIN))
  82. //        {
  83. //                ucErrTime++;
  84. //                if(ucErrTime>250)
  85. //                {
  86. //                        SI7020_IIC_Stop();
  87. //                        return 1;//接收应答失败
  88. //                }
  89. //        }
  90.         if(HAL_GPIO_ReadPin((GPIO_TypeDef*)SI7020_IIC_SDA_PORT,SI7020_IIC_SDA_PIN))
  91.                 return ACK;
  92.         RESET_SI7020_IIC_SCL_PIN();       
  93.         _delay_us(5);
  94.         return NACK;  
  95. }
  96. //产生ACK应答
  97. void SI7020_IIC_Ack(void)
  98. {
  99.         RESET_SI7020_IIC_SCL_PIN();
  100.         SI7020_SDA_OUT();
  101.         RESET_SI7020_IIC_SDA_PIN();
  102.         _delay_us(2);
  103.         SET_SI7020_IIC_SCL_PIN();
  104.         _delay_us(2);
  105.         RESET_SI7020_IIC_SCL_PIN();
  106. }
  107. //不产生ACK应答                    
  108. void SI7020_IIC_NAck(void)
  109. {
  110.         RESET_SI7020_IIC_SCL_PIN();
  111.         SI7020_SDA_OUT();
  112.         SET_SI7020_IIC_SDA_PIN();
  113.         _delay_us(2);
  114.         SET_SI7020_IIC_SCL_PIN();
  115.         _delay_us(2);
  116.         RESET_SI7020_IIC_SCL_PIN();
  117. }                                                                              
  118. //IIC发送一个字节
  119. void SI7020_IIC_Send_Byte(uint8_t txd)
  120. {                        
  121.         uint8_t t;   
  122.         SI7020_SDA_OUT();             
  123.         SET_SI7020_IIC_SDA_PIN();
  124.     for(t=0;t<8;t++)
  125.     {              
  126.                 if(txd&0x80)
  127.                         SET_SI7020_IIC_SDA_PIN();
  128.                 else
  129.                         RESET_SI7020_IIC_SDA_PIN();
  130.         txd<<=1;           
  131.                 _delay_us(2);   //对TEA5767这三个延时都是必须的
  132.                 SET_SI7020_IIC_SCL_PIN();
  133.                 _delay_us(2);
  134.                 RESET_SI7020_IIC_SCL_PIN();
  135.                 _delay_us(2);
  136.     }
  137. }             
  138. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
  139. uint8_t SI7020_IIC_Read_Byte(unsigned char ack)
  140. {
  141.         unsigned char i,receive=0;
  142.         SI7020_SDA_IN();//SDA设置为输入
  143.     for(i=0;i<8;i++ )
  144.         {
  145.                 RESET_SI7020_IIC_SCL_PIN();
  146.         _delay_us(2);
  147.                 SET_SI7020_IIC_SCL_PIN();
  148.         receive<<=1;
  149.         if(HAL_GPIO_ReadPin(SI7020_IIC_SDA_PORT,SI7020_IIC_SDA_PIN))receive++;   
  150.                 _delay_us(2);
  151.     }                                         
  152.     if (!ack)
  153.         SI7020_IIC_NAck();//发送nACK
  154.     else
  155.         SI7020_IIC_Ack(); //发送ACK   
  156.     return receive;
  157. }
复制代码
si7020.h
  1. #ifndef __SI7020_H
  2. #define __SI7020_H
  3. #include <stdio.h>
  4. #include <stdint.h>
  5. #include <stm32f1xx.h>
  6. typedef  uint8_t u8;
  7. typedef  uint16_t u16;
  8. typedef  uint32_t u32;
  9. #define SI7020_ADDRESS 0X80 //SI7020器件地址
  10. #define SI7020_READ 0X01        //读数据

  11. #define SI7020_TEMPERATURE      0xE3
  12. #define SI7020_HUMIDITY         0xE5
  13. #define SI7020_SOFT_RESET       0xFE

  14. void SI7020_Init(void); //初始化IIC
  15. uint16_t SI7020_ReadOneByte(uint8_t ReadAddr);
  16. int16_t SI7020_Read_Humidity(void);
  17. int16_t SI7020_Read_Temperture(void);

  18. #endif
复制代码
si7020.c
  1. #include "Hal_SI7020/si7020.h"
  2. #include "Hal_SI7020_IIC/si7020_iic.h"
  3. //#include "delay.h"
  4. //#include "delay.h"
  5. #include "Hal_OLED/oled.h"
  6. #include "delay/delay.h"
  7. #include "common.h"
  8. //SI7020串口初始化
  9. void SI7020_Init(void)
  10. {
  11.         SI7020_IIC_Init();
  12. }
  13. //在SI7020指定地址读出一个数据
  14. //ReadAddr:读取温度或温度  
  15. //返回值  :读到的数据
  16. uint16_t SI7020_ReadOneByte(uint8_t ReadAddr)
  17. {                                  
  18.         uint8_t error=1;
  19.         uint8_t temp[2];
  20.         uint16_t value=0;
  21.         SI7020_IIC_Start();
  22.         SI7020_IIC_Send_Byte(SI7020_ADDRESS);
  23.         SI7020_IIC_Wait_Ack();
  24.         SI7020_IIC_Send_Byte(ReadAddr);
  25.         SI7020_IIC_Wait_Ack();
  26.         SI7020_IIC_Start();
  27.         SI7020_IIC_Send_Byte(SI7020_ADDRESS|SI7020_READ);
  28.         SI7020_IIC_Wait_Ack();
  29.         delay_ms(20);                                                //延时一段时间,不可少。
  30. //        SI7020_IIC_Start();                                        //若使用No Hold Master Mode模式请使用此3行程序
  31. //        SI7020_IIC_Send_Byte(SI7020_ADDRESS|SI7020_READ);
  32. //        SI7020_IIC_Wait_Ack();
  33.         temp[1]=SI7020_IIC_Read_Byte(1);
  34.         temp[0]=SI7020_IIC_Read_Byte(0);
  35.         SI7020_IIC_Stop();//产生一个停止条件
  36.         value=temp[0]|(temp[1]<<8);
  37.         return value;
  38. }
  39. //读取湿度
  40. //返回值为湿度
  41. int16_t SI7020_Read_Humidity(void)
  42. {       
  43.         uint16_t value=0;
  44.         double temp;
  45.         value=SI7020_ReadOneByte(SI7020_HUMIDITY);
  46.         temp=(double)value;
  47.         temp=(temp/65536.0f)*125.0f-6.0f;
  48.         GIZWITS_LOG("Humidity = %.2lf \n", temp);//机智云的串口打印
  49.         return (int16_t)(temp*10);                                //返回湿度值,此处放大了10倍
  50. }
  51. //读取湿度
  52. //返回值为湿度
  53. int16_t SI7020_Read_Temperture(void)
  54. {

  55.         uint16_t value=0;
  56.         double temp;
  57.         value=SI7020_ReadOneByte(SI7020_TEMPERATURE);
  58.         temp=(double)value;
  59.         temp=(temp/65536.0f) * 175.72f - 46.85f;
  60.         GIZWITS_LOG("Temperature = %.2lf \n", temp);//机智云的串口打印
  61.         return (int16_t)(temp*10);                                        //返回温度值,此处放大了10倍
  62.        
  63. }












复制代码
下面附上附件

Hal_SI7020.zip (1.27 KB, 下载次数: 36)

评分

参与人数 1 ST金币 +2 收起 理由
Inc_brza + 2

查看全部评分

1 收藏 1 评论0 发布时间:2017-12-22 17:07

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版