STM32 例程-7 STM32固件库方式 读取SHT20 温湿度

SHT20 .h文件

#ifndef SHT20_H
#define SHT20_H
#include "common.h"
#include "stdio.h"
#include "string.h"
#include "stm32f4xx.h"

#define IIC_SCL_PIN  GPIO_Pin_0
#define IIC_SDA_PIN  GPIO_Pin_1
#define SHT20_ADDRESS  0x80 
#define IIC_SCL_Set()  GPIO_WriteBit(GPIOB, IIC_SCL_PIN, Bit_SET)
#define IIC_SCL_Clr()  GPIO_WriteBit(GPIOB, IIC_SCL_PIN, Bit_RESET)

#define IIC_SDA_Set()  GPIO_WriteBit(GPIOB, IIC_SDA_PIN, Bit_SET)
#define IIC_SDA_Clr()  GPIO_WriteBit(GPIOB, IIC_SDA_PIN, Bit_RESET)

#define IIC_SDA_Get()  GPIO_ReadInputDataBit(GPIOB, IIC_SDA_PIN)
#define IIC_SCL_Get()  GPIO_ReadInputDataBit(GPIOB, IIC_SCL_PIN)
#ifndef IIC_Direction_Transmitter
	#define  IIC_Direction_Transmitter      ((uint8_t)0x00)
#endif

#ifndef IIC_Direction_Receiver
	#define  IIC_Direction_Receiver         ((uint8_t)0x01)
#endif

#define  IIC_SDA_IN   0
#define  IIC_SDA_OUT  1

enum
{
	IIC_ACK,
	IIC_NACK
};


//IIC所有操作函数
void IIC_GPIOInit(void);
void IIC_SDAMode(uint8_t Mode);
void IIC_Start(void);
void IIC_Stop(void);
uint8_t IIC_WaitForAck(void);
void IIC_Ack(void);
void IIC_NAck(void);
void IIC_SendByte(uint8_t Data);
uint8_t IIC_ReadByte(unsigned char Ack);
void SHT_GPIO_Init(void);
void SHT20_Init(void);
void SHT20_read_result(void);
#endif

SHT20 .c文件

#include "SHT20.h"
#include "common.h"
#include "lcd.h"
//IO方向设置
#define SDA_IN()  {GPIOB->MODER&=~(3<<(1*2));GPIOB->MODER|=0<<1*2;}	//PB1输入模式
#define SDA_OUT() {GPIOB->MODER&=~(3<<(1*2));GPIOB->MODER|=1<<1*2;} //PB1输出模式

void SHT_GPIO_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(	RCC_AHB1Periph_GPIOB, ENABLE );//使能GPIOB
	   
	GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN|IIC_SDA_PIN;//PB0,PB1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   //开漏输出
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	IIC_SCL_Set();
	IIC_SDA_Set();
}

void iic_delay(uint16_t Time)
{
	uint8_t i;
	
	while(Time --) for(i = 0; i < 10; i ++);
}

void IIC_SDAMode(uint8_t Mode){
	if(Mode){
		SDA_OUT();
	}else{
		SDA_IN();
	}
}

//产生IIC起始信号
void IIC_Start(void)
{
	IIC_SDAMode(IIC_SDA_OUT);
	IIC_SDA_Set();
	IIC_SCL_Set();
	iic_delay(4);
	IIC_SDA_Clr();
	iic_delay(4);
	IIC_SCL_Clr();
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	IIC_SDAMode(IIC_SDA_OUT);
	IIC_SCL_Clr();
	IIC_SDA_Clr();
	iic_delay(4);
	IIC_SCL_Set();
	IIC_SDA_Set();
	iic_delay(4);
							   	
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
uint8_t IIC_WaitForAck(void)
{
	uint8_t Retry = 0;
	
//	IIC_SCL_Clr();
//	iic_delay(1);
	IIC_SDAMode(IIC_SDA_IN);
	IIC_SDA_Set();iic_delay(1);
	IIC_SCL_Set();iic_delay(1);
	while(IIC_SDA_Get())
	{
		if(++ Retry > 250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL_Clr();
	
	return 0; 
} 
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL_Clr();
	IIC_SDAMode(IIC_SDA_OUT);
	IIC_SDA_Clr();
	iic_delay(2);
	IIC_SCL_Set();
	iic_delay(2);
	IIC_SCL_Clr();
}
//产生非ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL_Clr();
	IIC_SDAMode(IIC_SDA_OUT);
	IIC_SDA_Set();
	iic_delay(2);
	IIC_SCL_Set();
	iic_delay(2);
	IIC_SCL_Clr();
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_SendByte(uint8_t Data)
{                        
  uint8_t i;
	IIC_SDAMode(IIC_SDA_OUT);
	IIC_SCL_Clr();
	for(i = 0; i < 8; i ++)
	{
		if(Data & 0x80)
			IIC_SDA_Set();
		else
			IIC_SDA_Clr();
		Data <<= 1;
		iic_delay(1);
		IIC_SCL_Set();
		iic_delay(2);
		IIC_SCL_Clr();
		iic_delay(1);
		
	} 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
uint8_t IIC_ReadByte(unsigned char Ack)
{
	uint8_t i, RecDat = 0;

	IIC_SDAMode(IIC_SDA_IN);
	for(i = 0; i < 8; i ++)
	{
		IIC_SCL_Clr();
		iic_delay(55);
		IIC_SCL_Set();
		RecDat <<= 1;
		if(IIC_SDA_Get())
			RecDat |= 0x01;
		else
			RecDat &= ~0x01;
		iic_delay(5);
	}
	if(Ack)
		IIC_Ack();
	else
		IIC_NAck();

	return RecDat;
}

void SHT20_Init(void)
{
	  SHT_GPIO_Init();
//	  iic_delay(50);
//   //0x2130  表示周期模式 周期1s
//   	IIC_Start();
//   	IIC_SendByte(0x88);
//   	IIC_WaitForAck();
//   	IIC_SendByte(0x21);
//   	IIC_WaitForAck();
//   	IIC_SendByte(0x30);
//   	IIC_WaitForAck();
//    IIC_Stop();
//	  iic_delay(5000);
}


/*******************************************************************
 温湿度获取函数               
函数原型: SHT20_read_result(uint8_t addr);
功能: 用来接收从器件采集并合成温湿度
********************************************************************/ 
void SHT20_read_result(void)
{
	 uint16_t temp_humi_buffer[6],temp,humi;
	 float temperature,humidity;
	//写命令给SHT20,这个命令是访问SHT20转换结果的寄存器的
	
		IIC_Start();
		IIC_SendByte(0x80);
		IIC_WaitForAck();
		IIC_SendByte(0xF3);
		IIC_WaitForAck();
		IIC_Stop();
	delay_ms(100);
	 IIC_Start();
   IIC_SendByte(0x81);
   IIC_WaitForAck();
	
	 temp_humi_buffer[0] = IIC_ReadByte(1);	
	 temp_humi_buffer[1] = IIC_ReadByte(1);	
	 temp_humi_buffer[2] = IIC_ReadByte(1);	 
	IIC_Stop();
	  temp= ((temp_humi_buffer[0]<<8) | temp_humi_buffer[1]);//温度拼接
	 
	 
	 
	 
		IIC_Start();
		IIC_SendByte(0x80);
		IIC_WaitForAck();
		IIC_SendByte(0xF5);
		IIC_WaitForAck();
		IIC_Stop();
	delay_ms(100);
	 IIC_Start();
   IIC_SendByte(0x81);
   IIC_WaitForAck();
	
	 temp_humi_buffer[0] = IIC_ReadByte(1);	
	 temp_humi_buffer[1] = IIC_ReadByte(1);	
	 temp_humi_buffer[2] = IIC_ReadByte(1);	 
	IIC_Stop();
	  humi= ((temp_humi_buffer[0]<<8) | temp_humi_buffer[1]);//湿度拼接
	 
	/*转换实际温度*/
	 temperature= (175.0f*(float)temp/65535.0f -45.0f);// T = -45 + 175 * tem / (2^16-1)
	 humidity= (100.0f*(float)humi/65535.0f);// RH = hum*100 / (2^16-1)
	 if((temperature>=-40)&&(temperature<=125)&&(humidity>=0)&&(humidity<=100))//过滤错误
	 {
		 u8 str[256];
		 memset(str,0x00,256);
		 sprintf((char*)str,"temp&hum:%6.2f*C %6.2f%%",temperature,humidity);
		 LCD_DisplayString(10,250,16,str);
		//  printf("温湿度:%6.2f*C %6.2f%%",temperature,humidity);
	 }else{
		 printf("温湿度故障");
	 }
	 delay_ms(1000);
}



调用方法
SHT20_Init(); //SHT20初始化
SHT20_read_result();

posted @ 2022-04-03 13:49  zhaogaojian  阅读(675)  评论(0编辑  收藏  举报