STM32 例程-7 STM32韌體庫方式 讀取SHT20 溫溼度
阿新 • • 發佈:2022-04-03
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();