100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > STM32模拟IIC驱动sht30温湿度传感器

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

时间:2022-06-05 11:09:58

相关推荐

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);// 设置中断优先级分组2delay_init();//延时函数初始化 uart_init(9600); //串口初始化为9600SHT30_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,第三副图是教你具体怎么配置,按照手册就可以选择配置你想用的端口了。 中文手册,全套代码免费分享。 Q交流群 721421120 让我们一起进步

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。