STM8 analoge iic-Schnittstelle zum Debuggen des Temperatur- und Feuchtigkeitssensors SHT3x-Treiber

Hintergrund

Das Projekt verwendet tatsächlich SHT3x zur Temperatur- und Feuchtigkeitsmessung, der Hauptsteuerchip verwendet STM8S003F3P6 und nutzt die Hardwareverbindung der analogen IIC-Schnittstelle.

schematische Darstellung

 Wie in der Abbildung unten gezeigt, verwenden Sie die STM8S003F3P6-Pins PB4/PB5 für die SHT3x-Datenschnittstelle

SHT3x-DIS ist der Temperatur- und Feuchtigkeitssensor der neuen Generation von Sensirion mit einer Genauigkeit von ±2 % RH und ±0,3 °C, einem Eingangsspannungsbereich von 2,4 V bis 5,5 V, einer IIC-Bus-Schnittstelle und einer Geschwindigkeit von bis zu 1 MHz. Die Messbereiche für Temperatur und Luftfeuchtigkeit liegen bei -40 °C bis 125 °C und 0 bis 100 %.

Aus der folgenden Abbildung können wir erkennen, dass der Feuchtigkeitssensor und der Temperatursensor im SHT3x integriert sind, die abgetastet und über den ADC in die Datenverarbeitungs- und Linearisierungseinheit eingegeben werden und über einen Korrekturspeicher verfügen, um den Einfluss der Umgebung zu bewältigen auf der Gerätemessung. Daten über digitale Schnittstelle IIC auslesen. Mit einem Alarm-Pin kann der Schwellenwert durch Ändern des Registerwerts festgelegt werden. Er wird gesetzt, wenn die gemessene Temperatur und Luftfeuchtigkeit den Schwellenwert überschreiten.

Software-Design

Die Grundkonfiguration von STM8S003F3P6 ist wie folgt

Taktkonfiguration, hier muss die Taktkonfiguration erwähnt werden, wenn die Taktkonfiguration nicht erwähnt wird, die Zeitverzögerung der analogen IIC-Schnittstelle SHT3x

es ist schwer zu beurteilen


/************************************************
函数名称 : CLK_Configuration
功    能 : 时钟配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void CLK_Configuration(void)
{
/*
  ErrorStatus clk_return_status;
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); //HSI = 16M (8分频)=2MHZ
  
  //切换内部低速时钟128khz
  clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_LSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
  if (clk_return_status == SUCCESS)  //SUCCESS or ERROR
  {
                              
    CLK_ClockSwitchCmd(ENABLE);
    CLK_LSICmd(ENABLE);
    CLK_ClockSwitchCmd(DISABLE);                              
  }*/
 // CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //HSI = 16M (1分频)
  //ErrorStatus clk_return_status;
  
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //HSI = 16M (8分频)=2MHZ
 /* 
  //切换内部低速时钟8M
  clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
  if (clk_return_status == SUCCESS)  //SUCCESS or ERROR
  {
                              
    CLK_ClockSwitchCmd(ENABLE);
    CLK_HSECmd(ENABLE);
    CLK_ClockSwitchCmd(DISABLE);                              
  }*/
    
    CLK_DeInit();//设置为默认值
    CLK_HSICmd(ENABLE);//启用HSI
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//HSI分频
    CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);//CPU分频

}

Die Definition des Pin-Operationsmakros unter Verwendung des IIC-Pins PB4/PB5 lautet wie folgt

#define         SHT30_SCL      (0x01<<4)
#define         SHT30_SDA      (0x01<<5)

#define SHT30_SCL0_O    GPIOB->DDR    |=  SHT30_SCL;  GPIOB->CR1 |= SHT30_SCL            //GPIOB4 推免输出
#define SHT30_SCL0_H    GPIOB->ODR    |=  SHT30_SCL
#define SHT30_SCL0_L    GPIOB->ODR    &=  ~SHT30_SCL

#define SHT30_SCL0_I    GPIOB->DDR    &=  ~SHT30_SCL;  GPIOB->CR1 &= ~SHT30_SCL          //GPIOB4 浮空输入
#define SHT30_SCL0_DAT  ( (GPIOB->IDR>>4) & 0x01)

#define SHT30_SDA0_O    GPIOB->DDR    |=  SHT30_SDA;  GPIOB->CR1 |= SHT30_SDA            //GPIOB5 推挽输出
#define SHT30_SDA0_H    GPIOB->ODR    |=  SHT30_SDA
#define SHT30_SDA0_L    GPIOB->ODR    &=  ~SHT30_SDA

#define SHT30_SDA0_I    GPIOB->DDR    &=  ~SHT30_SDA;  GPIOB->CR1 &= ~SHT30_SDA          //GPIOB5 浮空输入
#define SHT30_SDA0_DAT  ( (GPIOB->IDR>>5) & 0x01)

#define	SHT30_SlaveAddress	  		(0x44<<1)					//7位地址0x44 左移1位 0x45 -- 0x8A

#define noACK 0                                 //用于判断是否结束通讯 
#define ACK   1                                 //结束数据传输 

Bevor die Hauptfunktion startet, müssen die verwendeten Pins wie folgt initialisiert und konfiguriert werden

Konfigurieren Sie PB4/PB5 so, dass es als Ausgang initialisiert wird

uint8 SHT30_Init(vid)
{
	uint8 	vRval = 0x00;
  
  SHT30_SCL0_O;                          	//设置SCLK为输出
  SHT30_SDA0_O;                          	//设置SDA为输出
	
	SHT30_SCL0_H;
	SHT30_SCL0_L;
	
	SHT30_SDA0_H;
	SHT30_SDA0_L;
	
	vRval += SHT30_Soft_Reset();
	
	
	
	
	SHT30_DelayMs(1);
	
	vRval += SHT30_ClearStaus();
	
	SHT30_DelayMs(1);
	
	//SHT30_Periodic_Measure(SHT30_PERIODOC_H_MEASURE_1S);
  
	return vRval;
}

Das detaillierte Datenformat des Single-Shot-Datenerfassungsbefehls
(Messbefehle für den Single-Shot-Datenerfassungsmodus) ist in der folgenden Abbildung dargestellt. Beginnen Sie zunächst am oberen Ende der Tabelle. Wiederholbarkeit bezieht sich auf die Wiederholbarkeit (je höher die Wiederholbarkeit, desto höher die Genauigkeit, siehe Abschnitt „Sensorleistung“ im Handbuch). „Clock Stretching“ bezieht sich auf die Clock-Streckung. Ihre Funktionen werden im Folgenden beschrieben. Der Datenflussprozess ist wie folgt.

Senden Sie das Startsignal und eine Ein-Byte-Adresse, die aus der oberen 7-Bit-Geräteadresse und dem niedrigsten Bit-Schreibsignal (WR = 0) besteht, und warten Sie auf das Antwortsignal. (Beachten Sie, dass sich die Adresse in den oberen 7 Bits befindet. Sie müssen daher die Adresse um ein Bit nach links verschieben und beim Übertragen der Adresse das Signal „Lesen 1/Schreiben 0“ hinzufügen, ADDR<<1 | WR). Senden Sie den High-
Wert Byte des Befehls (Most Significant Byte, MSB) und warten Sie auf das Antwortsignal;
senden Sie das Low-Byte (Least Significant Byte, LSB) des Befehls und warten Sie auf das Antwortsignal, dann senden Sie das Stoppsignal;
warten Sie einen Zeitraum von Zeit (die Messung läuft);
senden Sie das Startsignal und die Geräteadresse über die oberen 7 Bits. Eine Ein-Byte-Adresse, die aus dem niedrigsten Bit besteht, liest das Signal (RD=1) und wählt dann je nach Auswahl aus zwei Richtungen aus Uhrdehnung. Wenn die Taktverlängerungsfunktion deaktiviert ist, warten Sie auf ein Nicht-Antwortsignal, senden Sie ein Stoppsignal, verzögern Sie eine Zeit lang (dieser Schritt ist sehr wichtig!! Die Verzögerungszeit beträgt etwa 50 ms) und warten Sie auf das Ende der Konvertierung Senden Sie dann ein Acht-Bit-Antwortsignal und warten Sie auf das Antwortsignal. Lesen Sie dann Byte für Byte das High-Byte, das Low-Byte und das CRC-Prüfbyte der Temperatur und Luftfeuchtigkeit und senden Sie nach dem Empfang jedes Bytes ein Antwortsignal Endlich ein Stoppsignal senden. Und wenn die Takterweiterungsfunktion aktiviert ist, wird die SCL des Busses von SHT3x gesteuert, wir müssen das Programm nur solange blockieren (SCL==0), warten, bis es den Bus freigibt, und dann kann die MCU die Daten lesen ;

Einige Timing-Funktionen für SHT3x sind wie folgt

/*---------------------------------------------------------------------
 功能描述: SHT30 测量结果计算
 参数说明:  vTemSymbol [out] - 返回温度符号
						vTem [out] - 温度
						vHum [out] - 湿度

 函数返回: 无
 ---------------------------------------------------------------------*/
uint8 SHT30_Get_TH(uint8 *vTemSymbol, uint16 *vTem, uint16 *vHum)
{
	uint8 vDat[8];
	uint8 vRval = 0;
	
	vRval = SHT30_Single_Measure(vDat);
	if (!vRval) SHT30_calc(vDat, vTemSymbol, vTem, vHum);
	
	return vRval;
}

/*---------------------------------------------------------------------
 功能描述: SHT30单次测量
 参数说明: vBuf [out] - 测量读取结果
 函数返回: 0 - 成功  大于1出错
 ---------------------------------------------------------------------*/
uint8 SHT30_Single_Measure(uint8 *vBuf)
{
	uint8 vRval = 0;
	uint8 i = 0;
	
	SHT30_Start();
	
	vRval |= SHT30_SendByte(SHT30_SlaveAddress+0);					//地址写
	if (!vRval) vRval |= SHT30_SendByte( (SHT30_SINGLE_H_MEASURE_EN>>8)&0xFF );				//使能高精度采集
	if (!vRval) vRval |= SHT30_SendByte( (SHT30_SINGLE_H_MEASURE_EN)&0xFF );
	SHT30_Stop();
	
	if (vRval)	return vRval;
	
	SHT30_SCL0_H;
	SHT30_DelayMs(15);														//15Ms
	
	
	SHT30_Start();
	if (!vRval) vRval |= SHT30_SendByte(SHT30_SlaveAddress+1);					//地址读
	
	if (vRval)	return vRval;
	
	for(i=0; i<6; i++)
	{
		vBuf[i] = SHT30_RecvByte();                	//存储数据
    if (i == 0x06)
    {
      
      SHT30_SendACK(1);                         //最后一个数据需要回NOACK
    }
    else
    {		
      SHT30_SendACK(0);                         //回应ACK
    }
	}
	
	SHT30_Stop();
	
	return vRval;
}

/*---------------------------------------------------------------------
 功能描述: SHT30 测量结果计算
 参数说明:  vBuf [in] - 测量读取结果
						vTemSymbol [out] - 返回温度符号
						vTem [out] - 温度
						vHum [out] - 湿度

 函数返回: 无
 ---------------------------------------------------------------------*/
void SHT30_calc(uint8 *vBuf, uint8 *vTemSymbol, uint16 *vTem, uint16 *vHum)
{
	uint16 	vVal = 0x00;
	uint8 	vCrc = 0x00;
	float		vTemp = 0.00;
	
	//温度
	vCrc = SHT30_CheckCrc8(vBuf, 2);
	if (vCrc == vBuf[2])
	{
		vVal = vBuf[0];
		vVal<<=8;
		vVal |= vBuf[1];
		
		vTemp = 175.0*vVal/(65536.0-1.0);
		
		if (vTemp >= 45)
		{
			*vTemSymbol = 1;
			*vTem = (uint16)((vTemp - 45.0)*10.0);
		}
		else
		{
			*vTemSymbol = 0;
			*vTem = (uint16)((45.0 - vTemp)*10.0);
		}
		
	}
	
	vBuf += 3;
	vVal = 0x00;
	vCrc = SHT30_CheckCrc8(vBuf, 2);
	if (vCrc == vBuf[2])
	{
		vVal = vBuf[0];
		vVal<<=8;
		vVal |= vBuf[1];
		
		vTemp = 100.0*vVal/(65536.0-1.0);
		*vHum = (uint16)(vTemp*10);
	}
}

Supongo que te gusta

Origin blog.csdn.net/li171049/article/details/130854531
Recomendado
Clasificación