1. 程式人生 > 其它 >STM32 例程-7 STM32韌體庫方式 讀取SHT20 溫溼度

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();