STM32模拟IIC驱动sht30温湿度传感器

Posted 文某9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32模拟IIC驱动sht30温湿度传感器相关的知识,希望对你有一定的参考价值。

最近有在使用sht30这个传感器,相比于新手常用的dht11传感器,sht30更精确,自己花了半小时调好了

所以拿出来分享给大家。

sht30外观

驱动不是自己写的, 是采用CSDN上的一位朋友的 ,这里贴出来的代码不是本文的主旨, 重要是教会大

家如何配置各个端口(因为是模拟iic 所以大多数引脚都模拟为SCLK和DATA)。

串口输出图

驱动代码

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,第三副图是教你具体怎么配置,按照手册就可以选择配置你想用的端口了。 中文手册,全套代码免费分享,需要的可以关注公众号回复sht30或加群领取。

.

公众号

Q交流群 721421120 让我们一起进步

以上是关于STM32模拟IIC驱动sht30温湿度传感器的主要内容,如果未能解决你的问题,请参考以下文章

STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)

STM32F103ZE+SHT30检测环境温度与湿度(IIC模拟时序)

STM32------SHT30温湿传感器

SHT20 IIC总线驱动概述

SHT30温湿度计

STM32使用IIC总线通讯协议在OLED屏幕上显示字符串汉字温湿度(软件IIC)