一、IIC库函数的配置

1、IIC.h

#ifndef _IIC_H
#define _IIC_H

#include "main.h"

#define us 8

#define IIC_SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define IIC_SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6)

#define IIC_SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define IIC_SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7)

#define IIC_SDA_IN (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7))

void IIc_Init(void);
void IIc_Start(void);
void IIc_End(void);
void IIc_Send_Ack(u8 ack);
u8 IIc_Rec_Ack(void);
void IIc_Send_Byte(u8 data);
u8 IIc_Res_Byte(void);


#endif

2、IIC.c

#include "iic.h"

/*************************
函数名称:IIc_Init(void)
函数功能:IIc初始化配置函数 (IO 口模拟配置)
返回值:无
形参:无
作者:me
版本:1.0 
	IIC_SCL --- PB6 --- 通用推挽输出
	IIC_SDA --- PB7 --- 通用开漏输出				AHB1			
*************************/
void IIc_Init(void)
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
  GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	//空闲状态
	IIC_SCL_H;
	IIC_SDA_H;
	
}

/*************************
函数名称:IIc_Start(void)
函数功能:IIc起始信号函数 
返回值:无
形参:无
作者:me
版本:1.0 
	在时钟线为高电平的时候去拉低数据线
*************************/
void IIc_Start(void)
{
	IIC_SDA_H;
	Delay_Us(us);
	
	IIC_SCL_H;
	Delay_Us(us);
	
	IIC_SDA_L;
	Delay_Us(us);
	
	
}

/*************************
函数名称:IIc_End(void)
函数功能:IIc结束信号函数 
返回值:无
形参:无
作者:me
版本:1.0 
	在时钟线为高电平的时候去拉高数据线
*************************/
void IIc_End(void)
{
	IIC_SDA_L;
	Delay_Us(us);
	
	IIC_SCL_H;
	Delay_Us(us);
	
	IIC_SDA_H;
	Delay_Us(us);
}

/*************************
函数名称:IIc_Send_Ack(u8 ack)
函数功能:IIc发送应答/不应答信号函数 
返回值:无
形参:u8 ack		0 发送应答 	1 发送不应答
作者:me
版本:1.0 
*************************/
void IIc_Send_Ack(u8 ack)
{
	IIC_SCL_L;
	Delay_Us(us);
	if(ack == 1)
	{
		IIC_SDA_H;
	}
	else
	{
		IIC_SDA_L;
	}
	Delay_Us(us);
	
	IIC_SCL_H;
	Delay_Us(us);
	
	IIC_SCL_L;
	Delay_Us(us);
}

/*************************
函数名称:IIc_Rec_Ack(void)
函数功能:IIc接收应答/不应答信号函数 
返回值:u8 ack		0 表示应答 	1 表示不应答
形参:无
作者:me
版本:1.0 				SCL推挽		SDA开漏
*************************/
u8 IIc_Rec_Ack(void)
{
	u8 ack;
	
	IIC_SDA_H;
	
	IIC_SCL_L;
	Delay_Us(us);
	IIC_SCL_H;
	Delay_Us(us);
	if(IIC_SDA_IN)
	{
		ack = 1;
	}
	else
	{
		ack = 0;
	}
	Delay_Us(us);
	
	
	IIC_SCL_L;
	Delay_Us(us);
	return ack;
}

/*************************
函数名称:IIc_Send_Byte(u8 data)
函数功能:IIc发送一个字节
返回值:无
形参:u8 data
作者:me
版本:1.0 
*************************/
void IIc_Send_Byte(u8 data)
{
	for(u8 i=0;i<8;i++)
	{
		IIC_SCL_L;
		if(data & (0x80 >> i))
		{
			IIC_SDA_H;	
		}
		else
		{
			IIC_SDA_L;	
		}
		Delay_Us(us);
		IIC_SCL_H;
		Delay_Us(us);
	}
	
}

/*************************
函数名称:IIc_Res_Byte(void)
函数功能:IIc接收一个字节
返回值:u8 
形参:无
作者:me
版本:1.0 
		数据是从高位开始发
*************************/
u8 IIc_Res_Byte(void)
{
	u8 data;
	IIC_SDA_H;     // ? 释放SDA,让传感器能驱动总线
	for(u8 i=0;i<8;i++)
	{
		
		IIC_SCL_L;
		Delay_Us(us);
		IIC_SCL_H;
		Delay_Us(us);
		
		data <<= 1;
		if(IIC_SDA_IN)
		{
			data |= 1;
		}
	}
	
	return data;
}

二、SHT31(温湿度传感器)

1、基本信息

2、管脚说明

3、器件地址

确认ADDR接地还是接电源    ---   原理图

4、运行流程

1)起始信号

2)发送写方向地址,并接收应答

3)发送命令高8bit(0x2c)数据,并接收应答

4)发送命令低8bit(0x06)数据,并接收应答

5)停止信号

6)数据正在测量,delay_ms(x);

7)起始信号

8)发送读方向地址,并接收应答

9)读取温度高8bit数据,并发送应答

10)读取温度低8bit数据,并发送应答

11接收温度数据的8bitCRC校验数据,并发送应答

12)读取湿度高8bit,并发送应答

13)读取湿度低8bit,并发送应答

14)接收湿度数据的8bitCRC校验数据,并发送非应答

15)停止信号

5、湿度转换公式

%RH:相对读湿度(相对湿度)

RH = 100 * SRH / (216 - 1)

SRH:读取出来高8bit湿度和低8bit湿度

6、温度转换公式

T = -45 + 175 * ST / (216 - 1)

 ST = 读取出来高8bit温度和低8bit温度

7、代码

#include "tphmsensor.h"

u16 TH_Data = 0;
u16 RH_Data = 0;
/*************************
函数名称:tphm_Init(void)
函数功能:温湿度传感器初始化
返回值:无
形参:无
作者:me
版本:1.0 	
*************************/
void tphm_Init(void)
{
	u8 tp_mb,tp_lb,hm_mb,hm_lb;
	u16 tp_raw, hm_raw; // 用于存储组合后的原始数据
	
	IIc_Start();
	IIc_Send_Byte(0x44 << 1);
	IIc_Rec_Ack();
	
	IIc_Send_Byte(0x2c);
	IIc_Rec_Ack();
	IIc_Send_Byte(0x06);
	IIc_Rec_Ack();
	
	IIc_End();
	Delay_Ms(30);
	
	IIc_Start();
	IIc_Send_Byte((0x44 << 1) | 0x01);
	IIc_Rec_Ack();
	
	tp_mb = IIc_Res_Byte();
	IIc_Send_Ack(0);
	tp_lb = IIc_Res_Byte();
	IIc_Send_Ack(0);
	IIc_Res_Byte(); // 丢弃温度CRC
	IIc_Send_Ack(0); 
	
	hm_mb = IIc_Res_Byte();
	IIc_Send_Ack(0);
	hm_lb = IIc_Res_Byte();
	IIc_Send_Ack(0);
	IIc_Res_Byte(); 
	IIc_Send_Ack(1); 

	IIc_End();
	
	tp_raw = ((u16)tp_mb << 8) | tp_lb;
  hm_raw = ((u16)hm_mb << 8) | hm_lb;
	
	RH_Data = (u32)100 * hm_raw / 65535; 
	TH_Data = (u32)175 * tp_raw / 65535 - 45;
}





三、MLX90614(红外温度传感器)

1、时钟频率支持10khz-100khz(IIC中的延时需要改为 5us )

2、读取温度的流程

3、代码

#include "infrared_tp.h"

/*************************
函数名称:infrared_tp(void)
函数功能:红外温度传感器MLX90614
返回值:无
形参:无
作者:me
版本:1.0 	
*************************/
float infrared_tp(void)
{
	u8 lb,mb;
	float temp = 0;
	u16 data = 0;
	
	
	IIc_Start();
	
	IIc_Send_Byte(0xB4);
	IIc_Rec_Ack();
	
	IIc_Send_Byte(0x07);
	IIc_Rec_Ack();

	IIc_Start();
	
	IIc_Send_Byte(0xB5);
	IIc_Rec_Ack();
	
	lb = IIc_Res_Byte();
	IIc_Send_Ack(0);
	
	mb = IIc_Res_Byte();
	IIc_Send_Ack(1);
	
	IIc_Res_Byte();
	IIc_Send_Ack(0);

	IIc_End();
	
	data = (mb << 8) | lb;
	
	temp = (data * 0.02f) - 273.15f;
	
	return temp;
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐