▬▬▬▬▬▶测温湿度实验◀▬▬▬▬▬
⚔️前言
最近有在使用sht30这个传感器,相比DHT11传感器精度更高
⚔️先看现象
使用串口打印数据
⚔️外观
⚔️代码摘录
sht30.c#include "SHT30.h"
#define write 0
#define read 1
//IIC总线接口定义
#define SCL PAout(5)
#define SDA_OUT PAout(6)
#define SDA_IN PAin(6)
#define IIC_INPUT_MODE_SET() {GPIOA->CRL&=0XF0FFFFFF;GPIOA->CRL|=8<<24;}
#define IIC_OUTPUT_MODE_SET() {GPIOA->CRL&=0XF0FFFFFF;GPIOA->CRL|=3<<24;}
float humiture[4];
u8 humiture_buff1[20];
void SHT30_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SCL=1;
SDA_OUT=1;
}
/*主机发送ACK*/
void IIC_ACK(void)
{
IIC_OUTPUT_MODE_SET();
SCL=0;
delay_us(2);
SDA_OUT=0;
delay_us(2);
SCL=1;
delay_us(2);
SCL=0;
delay_us(1);
}
/*主机不发送ACK*/
void IIC_NACK(void)
{
IIC_OUTPUT_MODE_SET();
SCL=0;
delay_us(2);
SDA_OUT=1;
delay_us(2);
SCL=1;
delay_us(2);
SCL=0;
delay_us(1);
}
/*主机等待从机的ACK*/
u8 IIC_wait_ACK(void)
{
u8 t = 200;
IIC_OUTPUT_MODE_SET();
SDA_OUT=1;//8位发送完后释放数据线,准备接收应答位
delay_us(1);
SCL=0;
delay_us(1);
IIC_INPUT_MODE_SET();
delay_us(1);
while(SDA_IN)//等待SHT30应答
{
t--;
delay_us(1);
if(t==0)
{
SCL=0;
return 1;
}
delay_us(1);
}
delay_us(1);
SCL=1;
delay_us(1);
SCL=0;
delay_us(1);
return 0;
}
/*******************************************************************
功能:启动I2C总线,即发送I2C起始条件.
********************************************************************/
void IIC_Start(void)
{
IIC_OUTPUT_MODE_SET();
SDA_OUT=1;
SCL=1;
delay_us(4);
SDA_OUT=0;
delay_us(4);
SCL=0;
}
/*******************************************************************
功能:结束I2C总线,即发送I2C结束条件.
********************************************************************/
void IIC_Stop(void)
{
IIC_OUTPUT_MODE_SET();
SCL=0;
SDA_OUT=0;
delay_us(4);
SCL=1;
delay_us(4);
SDA_OUT=1;
delay_us(4);
}
/*******************************************************************
字节数据发送函数
函数原型: void SendByte(UCHAR c);
功能:将数据c发送出去,可以是地址,也可以是数据
********************************************************************/
void IIC_SendByte(u8 byte)
{
u8 BitCnt;
IIC_OUTPUT_MODE_SET();
SCL=0;
for(BitCnt=0;BitCnt<8;BitCnt++)//要传送的数据长度为8位
{
if(byte&0x80) SDA_OUT=1;//判断发送位
else SDA_OUT=0;
byte<<=1;
delay_us(2);
SCL=1;
delay_us(2);
SCL=0;
delay_us(2);
}
}
/*******************************************************************
字节数据接收函数
函数原型: UCHAR RcvByte();
功能: 用来接收从器件传来的数据
********************************************************************/
u8 IIC_RcvByte(void)
{
u8 retc;
u8 BitCnt;
retc=0;
IIC_INPUT_MODE_SET();//置数据线为输入方式
delay_us(1);
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SCL=0;//置时钟线为低,准备接收数据位
delay_us(2);
SCL=1;//置时钟线为高使数据线上数据有效
retc=retc<<1;
if(SDA_IN) retc |=1;//读数据位,接收的数据位放入retc中
delay_us(1);
}
SCL=0;
return(retc);
}
/*******************************************************************
温湿度获取函数
函数原型: SHT30_read_result(u8 addr);
功能: 用来接收从器件采集并合成温湿度
********************************************************************/
void SHT30_read_result(u8 addr)
{
u16 tem,hum;
u16 buff[6];
float Temperature=0;
float Humidity=0;
IIC_Start();
IIC_SendByte(addr<<1 | write);//写7位I2C设备地址加0作为写取位,1为读取位
IIC_wait_ACK();
IIC_SendByte(0x2C);
IIC_wait_ACK();
IIC_SendByte(0x06);
IIC_wait_ACK();
IIC_Stop();
delay_ms(50);
IIC_Start();
IIC_SendByte(addr<<1 | read);//写7位I2C设备地址加0作为写取位,1为读取位
if(IIC_wait_ACK()==0)
{
buff[0]=IIC_RcvByte();
IIC_ACK();
buff[1]=IIC_RcvByte();
IIC_ACK();
buff[2]=IIC_RcvByte();
IIC_ACK();
buff[3]=IIC_RcvByte();
IIC_ACK();
buff[4]=IIC_RcvByte();
IIC_ACK();
buff[5]=IIC_RcvByte();
IIC_NACK();
IIC_Stop();
}
tem = ((buff[0]<<8) | buff[1]);//温度拼接
hum = ((buff[3]<<8) | buff[4]);//湿度拼接
/*转换实际温度*/
Temperature= (175.0*(float)tem/65535.0-45.0) ;// T = -45 + 175 * tem / (2^16-1)
Humidity= (100.0*(float)hum/65535.0);// RH = hum*100 / (2^16-1)
if((Temperature>=-20)&&(Temperature<=125)&&(Humidity>=0)&&(Humidity<=100))//过滤错误数据
{
// humiture[0]=Temperature;
// humiture[2]=Humidity;
sprintf(humiture_buff1,"%6.2f*C %6.2f%%",Temperature,Humidity);//111.01*C 100.01%(保留2位小数)
}
printf("温湿度:%s\n",humiture_buff1);
hum=0;
tem=0;
}
sht30.h
#ifndef SHT30_H
#define SHT30_H
#include "delay.h"
#include "sys.h"
#include "stdio.h"
#include "usart.h"
#include "string.h"
extern u8 humiture_buff1[20];
void SHT30_Init(void);
void IIC_ACK(void);
void IIC_NACK(void);
u8 IIC_wait_ACK(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_SendByte(u8 byte);
u8 IIC_RcvByte(void);
void SHT30_read_result(u8 addr);
#endif
主函数(while循环可以写个测试的printf)
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "SHT30.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
delay_init(); //延时函数初始化
uart_init(9600); //串口初始化为9600
SHT30_Init();
while(1)
{
//printf("123456");
SHT30_read_result(0x44);
delay_ms(300);
}
}
⚔️进阶部分
代码实测能用 ,直接复制即可, 但是如果想改端口继续往下看。上图红色框选的是换端口所有需要改变的地方 这里漏框了上面的几个宏定义, 上面几个也要改。
GPIOA->CRL&=0XF0FFFFFF;理解为 清零了32位数据中的4位
GPIOA->CRL|=8<<24;理解为置位了32位中的(24,25,26,27)的值
上面两副图来自stm32中文手册 ,意思很明了, 有两个寄存器用来配置io口模式,CRL配置GPIO0-7, CRH配置GPIO8-15,第三副图是教你具体怎么配置,按照手册就可以选择配置你想用的端口了。 中文手册,可找我获取。
⚔️项目获取
▬▬▬▬▬▶点击下方◀▬▬▬▬▬