找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1691|回復(fù): 5
打印 上一主題 下一主題
收起左側(cè)

stm32f103zet6單片機接sht35溫濕度傳感器數(shù)據(jù)波動巨大無比不穩(wěn)定

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:341424 發(fā)表于 2024-2-21 16:17 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
某一個寶買了一個SHT35模塊,直接用STM32ZET6的正點原子開發(fā)板接的,數(shù)據(jù)波動巨大無比,各位大佬幫忙,下面是單片機代碼
/*
設(shè)定溫度閾值范圍:-20℃——125℃
設(shè)定相對濕度范圍:0%——100%
*/
#include"stm32f103xe.h"
#include"SHT30.h"
#include"stdio.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
#include "usbd_ctlreq.h"
#include "hw_config.h"
#include "usbd_core.h"
#include "usart.h"
#include <stdbool.h> // 引入標準布爾類型定義
#define write 0 //IIC設(shè)備地址一般是7位,也有10位,本程序使用7位IIC設(shè)備地址,第8位是寫命令
#define read  1 //IIC設(shè)備地址一般是7位,也有10位,本程序使用7位IIC設(shè)備地址,第8位是讀命令
// SHT30標準單次高精度測量命令
//#define MEAS_HIGHREP_STRETCH 0x2C06
//IIC總線接口定義
#define SCL PBout(6)//設(shè)置時鐘端口
//SHT30數(shù)據(jù)SDA傳輸口,有輸出也有輸入,所以需配置它的輸入和輸出
#define SDA_OUT PBout(7)//設(shè)置輸出數(shù)據(jù)端口
#define SDA_IN PBin(7)//設(shè)置輸入數(shù)據(jù)端口
//設(shè)置端口高8位的工作模式(具體可以參照端口位配置表),即I/O輸入輸出方向設(shè)置,先用與(&)對PB7引腳的四個位清0,再用或(|)置1
#define IIC_INPUT_MODE_SET()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=8<<28;}//改變PB7對應(yīng)位為1000(CNF[1:0]MODE[1:0]),設(shè)置成上拉或者下拉輸入
#define IIC_OUTPUT_MODE_SET() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=3<<28;}//改變PB7對應(yīng)位為0011,設(shè)置成通用推挽輸出
//#define IIC_INPUT_MODE_SET()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}//改變PB7對應(yīng)位為1000(CNF[1:0]MODE[1:0]),設(shè)置成上拉或者下拉輸入
//#define IIC_OUTPUT_MODE_SET() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}//改變PB7對應(yīng)位為0011,設(shè)置成通用推挽輸出

//定義溫濕度存儲變量
u8 humiture_buff1[20];

void SHT30_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;

  __HAL_RCC_GPIOB_CLK_ENABLE();

  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  //GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
}
//主機發(fā)送確認字符ACK
void IIC_ACK(void)//IIC協(xié)議,需要主機發(fā)送確認字符ACK來判斷數(shù)據(jù)是否接收無誤
{
  IIC_OUTPUT_MODE_SET();//配置PB7的SDA輸出為推挽輸出模式
  SCL=0;
  delay_us(2);
  SDA_OUT=0;
  delay_us(2);     
  SCL=1;//數(shù)據(jù)接收完成之后,將SCL拉高,以便與后面主機發(fā)送ACK給從機
  delay_us(2);                  
  SCL=0;//數(shù)據(jù)接收完成,主機發(fā)送ACK                     
  delay_us(1);   
}
//主機不發(fā)送確認字符ACK
void IIC_NACK(void)//IIC協(xié)議,數(shù)據(jù)傳輸未完成或者數(shù)據(jù)傳輸有誤,主機不發(fā)送確認字符ACK
{
  IIC_OUTPUT_MODE_SET();//配置PB7的SDA輸出為推挽輸出模式
  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)//主機等待從機發(fā)送ACK,從而判斷數(shù)據(jù)是否接收完成
{
    u8 t = 200;
    IIC_OUTPUT_MODE_SET();
    SDA_OUT=1;//8位發(fā)送完后釋放數(shù)據(jù)線,準備接收應(yīng)答位
    delay_us(1);
    SCL=0;
    delay_us(1);
    IIC_INPUT_MODE_SET();
    delay_us(1);
    while(SDA_IN)//等待SHT30應(yīng)答
    {
        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;        
}

void IIC_Start(void)//啟動IIC通訊 標準庫
{
  IIC_OUTPUT_MODE_SET();//設(shè)置PB7的SDA為推挽輸出
  SDA_OUT=1;//根據(jù)SHT30時序,啟動之前,SDA配置為高電平
  SCL=1;//根據(jù)SHT30時序,啟動之前,SCL配置為高電平
  delay_us(4);//延時4us,給硬件一個反應(yīng)時間
  SDA_OUT=0;//SDA引腳拉低,開始數(shù)據(jù)的傳輸
  delay_us(4);
  SCL=0;//SCL拉低,與SDA對應(yīng),響應(yīng)SDA數(shù)據(jù)的拉低,表示正式開始數(shù)據(jù)的傳輸
}

//結(jié)束IIC總線通訊,發(fā)送IIC通訊的結(jié)束條件
void IIC_Stop(void)
{
        IIC_OUTPUT_MODE_SET();
        SCL=0;//結(jié)束IIC通訊之前,查看SCL是否是拉低狀態(tài)
        SDA_OUT=0;//結(jié)束IIC通訊之前,查看SDA是否是拉低狀態(tài)  
        delay_us(4);        
        SCL=1;//將時鐘拉高,表示已經(jīng)結(jié)束IIC通訊
        delay_us(4);
        SDA_OUT=1;//將數(shù)據(jù)傳輸引腳拉高,表示正式結(jié)束數(shù)據(jù)的傳輸
        delay_us(4);
}

//將byte數(shù)據(jù)發(fā)送出去
void  IIC_SendByte(u8 byte)
{
        u8  Count;
        IIC_OUTPUT_MODE_SET();
        SCL=0;//將時鐘拉低,開始數(shù)據(jù)的傳輸
        for(Count=0;Count<8;Count++)//要傳送的數(shù)據(jù)長度為8位
        {
                if(byte&0x80) SDA_OUT=1;//判斷發(fā)送位,發(fā)送位為1,則還未發(fā)送數(shù)據(jù)
                else SDA_OUT=0; //判斷發(fā)送位為0,則開始數(shù)據(jù)的發(fā)送
                byte<<=1;
                delay_us(2);
                SCL=1;
                delay_us(2);
                SCL=0;
                delay_us(2);
        }
}

// 用來接收從器件傳來的數(shù)據(jù)   
u8 IIC_RcvByte(void)
{
  u8 retc;
  u8 Count;
  retc=0;
  IIC_INPUT_MODE_SET();//配置數(shù)據(jù)線為輸入方式
  delay_us(1);                    
  for(Count=0;Count<8;Count++)
  {  
        SCL=0;//配置時鐘線為低,準備接收數(shù)據(jù)位
        delay_us(1);               
        SCL=1;//配置時鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效  
        delay_us(1);      
        retc=retc<<1;
        if(SDA_IN) retc |=1;//讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中
        delay_us(1);
  }
  SCL=0;   
  return(retc);
}

//用來接收從器件采集并合成溫濕度
void SHT30_read_result(u8 addr)
{
        
    //SHT30有兩種讀取數(shù)值的方法,分別是狀態(tài)查詢和數(shù)值查詢,這里我使用的是數(shù)值查詢,發(fā)送指令為0x2C06
        u16 tem,hum;//定義存放溫濕度計算公式的變量
        u16 buff[6];//定義6個字節(jié)的數(shù)組,存放溫度高、低八位,濕度高、低八位,兩個字節(jié)的CRC校驗位
        float Temperature=0;//定義存放溫度拼接的變量Temperature,初始化溫度為0
        float Humidity=0;//定義存放濕度拼接的變量Humidity,初始化濕度為0
        //發(fā)送指令為0x2C06(默認)
        IIC_Start();
        IIC_SendByte(addr<<1 | write);//寫7位I2C設(shè)備地址加0作為寫取位,1為寫取位
        IIC_wait_ACK();
        //delay_us(1);
        IIC_SendByte(0x2C);//前半段發(fā)送指令為0x2C
        IIC_wait_ACK();
        //delay_us(1);
        IIC_SendByte(0x06);//后半段發(fā)送指令為0x06
        IIC_wait_ACK();
        //delay_us(1);
        IIC_Stop();
        delay_ms(20);//等待傳感器讀取數(shù)據(jù)
        IIC_Start();
        IIC_SendByte(addr<<1 | read);//寫7位I2C設(shè)備地址加1作為讀取位,1為讀取位

//SHT30返回的數(shù)值是6個元素的數(shù)組
        if(IIC_wait_ACK()==0)
        {
        delay_us(1);
                buff[0]=IIC_RcvByte();//返回溫度高8位
                IIC_ACK();
                buff[1]=IIC_RcvByte();//返回溫度低8位
                IIC_ACK();
                buff[2]=IIC_RcvByte();//溫度crc校驗位
                IIC_ACK();
                buff[3]=IIC_RcvByte();//返回濕度高8位
                IIC_ACK();
                buff[4]=IIC_RcvByte();//返回濕度低8位
                IIC_ACK();
                buff[5]=IIC_RcvByte();//濕度crc校驗位
                IIC_NACK();
                IIC_Stop();
        }
    tem = ((buff[0]<<8) | buff[1]);//將buff[0]采集到的溫度8位數(shù)據(jù)與buff[1]采集到的低8位數(shù)據(jù)相或,實現(xiàn)溫度拼接
    hum = ((buff[3]<<8) | buff[4]);//將buff[3]采集到的濕度8位數(shù)據(jù)與buff[4]采集到的低8位數(shù)據(jù)相或,實現(xiàn)濕度拼接

    // 將溫度和濕度轉(zhuǎn)換為浮點值
    Temperature = -45 + 175 * ((float)tem / 65535.0); // T = -45 + 175 * ST / (2^16-1)
    Humidity = 100 * ((float)hum / 65535.0); // RH = 100 * SRH / (2^16-1)
    if((Temperature>=-20)&&(Temperature<=125)&&(Humidity>=0)&&(Humidity<=100))//設(shè)定溫度和濕度的閾值,超過這個閾值則返回錯誤提示
    {
    USB_Printf("\r\n溫度:%6.2f℃\r\n",Temperature);
    USB_Printf("濕度:%6.2f%%\r\n",Humidity);
    hum=0;
    tem=0;        
    }
    else
    {
    USB_Printf("\r\n溫濕度超過給定閾值!\r\n");
    }
}
3.3V供電,SDA接PB7,SCL接PB6,電腦串口115200,能讀到溫濕度,但數(shù)據(jù)穩(wěn)定性特別差,嘗試改了部分代碼,也改了電壓,但都不太行,手里現(xiàn)在沒有別的工具,各位大佬先淺看下代碼,我是找不到什么毛病,好難

6a33d1057573061e11a69d2b698a418.jpg (546 KB, 下載次數(shù): 123)

串口工具讀到的數(shù)據(jù)

串口工具讀到的數(shù)據(jù)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:883242 發(fā)表于 2024-2-22 07:41 | 只看該作者
不是波動巨大,而是根本就沒有連接成功。
回復(fù)

使用道具 舉報

板凳
ID:226055 發(fā)表于 2024-2-22 16:50 | 只看該作者
    樓上正解,這個實驗現(xiàn)象很明顯沒有正常通信上。原因多方面的,一般軟件和硬件上。
    1、軟件原因不好幫你排查,但我手上有個測試沒有問題的SHT35的代碼。單片機也是STM32F103ZET6,所以參考價值很大,程序附件。(硬件是艾克姆的ZET6板子)


    2、如果使用上面軟件還沒有出現(xiàn)如上圖所示的實驗現(xiàn)象,那你要考慮硬件原因了。開發(fā)板是成品,出問題的概率很小。SHT35模塊要考慮是不是好的。




SHT35.7z

199.02 KB, 下載次數(shù): 9

回復(fù)

使用道具 舉報

地板
ID:341424 發(fā)表于 2024-2-25 17:56 | 只看該作者
Hephaestus 發(fā)表于 2024-2-22 07:41
不是波動巨大,而是根本就沒有連接成功。

是的老哥 軟件問題 暴風哭泣
回復(fù)

使用道具 舉報

5#
ID:341424 發(fā)表于 2024-2-25 17:58 | 只看該作者
cocolala 發(fā)表于 2024-2-22 16:50
樓上正解,這個實驗現(xiàn)象很明顯沒有正常通信上。原因多方面的,一般軟件和硬件上。
    1、軟件原因不 ...

感恩的心 確實是軟件問題
回復(fù)

使用道具 舉報

6#
ID:41656 發(fā)表于 2024-2-28 16:32 | 只看該作者
說明通信沒成功,可以去讀取一些芯片ID信息之類的去對比一下看看
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表