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();
本博客是个人工作中记录,更深层次的问题可以提供有偿技术支持。
另外建了几个QQ技术群:
2、全栈技术群:616945527
2、硬件嵌入式开发: 75764412
3、Go语言交流群:9924600
闲置域名WWW.EXAI.CN (超级人工智能)出售。
另外建了几个QQ技术群:
2、全栈技术群:616945527
2、硬件嵌入式开发: 75764412
3、Go语言交流群:9924600
闲置域名WWW.EXAI.CN (超级人工智能)出售。