Pilote SHT3x du capteur de température et d'humidité de débogage de l'interface iic analogique STM8

arrière-plan

Le projet utilise en fait SHT3x pour la mesure de la température et de l'humidité, la puce de contrôle principale utilise STM8S003F3P6 et utilise la connexion matérielle de l'interface IIC analogique.

diagramme schématique

 Comme indiqué dans la figure ci-dessous, utilisez les broches STM8S003F3P6 PB4/PB5 pour l'interface de données SHT3x

SHT3x-DIS est le capteur de température et d'humidité de nouvelle génération de Sensirion avec une précision de ± 2% HR et ± 0,3 ℃, plage de tension d'entrée de 2,4 V à 5,5 V, interface de bus IIC, vitesse jusqu'à 1 MHz. Les plages de température et d'humidité de mesure sont -40°C ~ 125°C et 0 ~ 100%.

Sur la figure ci-dessous, nous pouvons voir que le capteur d'humidité et le capteur de température sont intégrés à l'intérieur du SHT3x, qui sont échantillonnés et entrés dans l'unité de traitement des données et de linéarisation via l'ADC, et ont une mémoire de correction pour faire face à l'influence de l'environnement sur la mesure de l'appareil. Lire les données via l'interface numérique IIC. Avec une broche d'alarme, le seuil peut être défini en modifiant la valeur du registre, et il sera défini lorsque la température et l'humidité mesurées dépasseront le seuil.

conception de logiciels

La configuration de base de STM8S003F3P6 est la suivante

Configuration de l'horloge, la configuration de l'horloge doit être mentionnée ici, si la configuration de l'horloge n'est pas mentionnée, le délai de temporisation de l'interface IIC analogique SHT3x

c'est difficile de juger


/************************************************
函数名称 : 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分频

}

La définition de macro d'opération de broche utilisant la broche IIC PB4/PB5 est la suivante

#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                                 //结束数据传输 

Avant le démarrage de la fonction principale, les broches utilisées doivent être initialisées et configurées comme suit

Configurer PB4/PB5 pour initialiser en tant que sortie

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;
}

Le format de données détaillé de la commande d'acquisition de données monocoup
(commandes de mesure pour le mode d'acquisition de données monocoup) est illustré dans la figure ci-dessous. Commencez d'abord par le haut du tableau. La répétabilité fait référence à la répétabilité (plus la répétabilité est élevée, plus la précision est élevée, veuillez vous reporter à la partie Performances du capteur du manuel), l'étirement de l'horloge fait référence à l'étirement de l'horloge. Leurs fonctions seront décrites ci-dessous. Le processus de flux de données est le suivant.

Envoyez le signal de démarrage et une adresse d'un octet composée de l'adresse de périphérique à 7 bits supérieure et du signal d'écriture du bit le plus bas (WR = 0), et attendez le signal de réponse. (Notez que l'adresse est située dans les 7 bits supérieurs, vous devez donc décaler l'adresse d'un bit vers la gauche et ajouter le signal de lecture 1/écriture 0 lors du transfert de l'adresse, ADDR<<1 | WR); envoyer le
haut octet de l'instruction (octet le plus significatif, MSB) et attendre le signal de réponse ;
envoyer l'octet de poids faible (octet le moins significatif, LSB) de l'instruction et attendre le signal de réponse, puis envoyer le signal d'arrêt ;
attendre une période de temps (la mesure est en cours) ;
envoyer le signal de démarrage et l'adresse de l'appareil par les 7 bits supérieurs Une adresse d'un octet composée du signal de lecture du bit le plus bas (RD=1), puis sélectionner parmi deux directions en fonction du Étirement de l'horloge. Si la fonction d'extension d'horloge est désactivée, attendez un signal de non-réponse, envoyez un signal d'arrêt, retardez pendant un certain temps (cette étape est très importante !! Le temps de retard est d'environ 50 ms) et attendez la fin de la conversion , puis envoyez un signal de réponse à huit bits et attendez le signal de réponse, puis lisez l'octet haut, l'octet bas et l'octet de contrôle CRC de la température et de l'humidité octet par octet, et envoyez un signal de réponse après la réception de chaque octet, et enfin envoyer un signal d'arrêt. Et si la fonction d'extension d'horloge est activée, le SCL du bus est contrôlé par SHT3x, il suffit de bloquer le programme pendant que (SCL==0), attendez qu'il libère le bus et ensuite le MCU peut lire les données ;

Certaines fonctions de synchronisation pour SHT3x sont les suivantes

/*---------------------------------------------------------------------
 功能描述: 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);
	}
}

Je suppose que tu aimes

Origine blog.csdn.net/li171049/article/details/130854531
conseillé
Classement