STM32 模拟IIC驱动MS5607气压传感器调试记录

标题 STM32 模拟IIC驱动MS5607调试记录

因项目需求,需使用MS5607的作为检测气压,再此写下自己遇见的问题以及调试记录。

硬件原理图如下:
STM32 模拟IIC驱动MS5607气压传感器调试记录_第1张图片
IIC接口总线使用了气压传感器,SHT35温度传感器,调试MS5607硬件的7位地址是0X76。所以写的地址是0xEC,读操作的地址是0XED.
在第一次写数据的时候MCU无法得到ACK回应,最后查到的问题是地址错误导致的无回馈信号,在发送正确的时序图如下:

STM32 模拟IIC驱动MS5607气压传感器调试记录_第2张图片

MS5607操作指令:
STM32 模拟IIC驱动MS5607气压传感器调试记录_第3张图片
复位指令:

void  MS5607BA_Reset(void)//复位
  {
  		
			u8 err=0;
			IIC_Start();

			IIC_Send_Byte(MS5607BA_ADR_Write);
			err = IIC_Wait_Ack();
	       IIC_Send_Byte(MS5607BA_RESET);//Send Reset CMD
			err = IIC_Wait_Ack();
			IIC_Stop();

      delay_ms(200);    
	

  }

获得ADC读取的数字的值

void MS5607_Send_CMD(u8  command)
{

	  u8 err=0;
	  IIC_Start();
	  IIC_Send_Byte(MS5607BA_ADR_Write);//发送器件地址  
	  err = IIC_Wait_Ack();
	  IIC_Send_Byte(command);//Prom Read CMD
	  err = IIC_Wait_Ack();
	  IIC_Stop();
	  
}

void MS5607_ADC_Answer(u8 *Data)
{

	  u8 err=0;

	  IIC_Start();

	  IIC_Send_Byte(MS5607BA_ADR_Read);//发送器件地址

	  err = IIC_Wait_Ack();
	  *Data++=IIC_Read_Byte(1); 

	  *Data++=IIC_Read_Byte(1); 

	  *Data=IIC_Read_Byte(0); 

	  IIC_Stop();
	  
}

读取PRPM 0xa0 —0xae

void MS5607BA_readPROM(void)
{   
			uint16_t value=0;u8 Promdata[2]={0};
			u8 i;
			u8 err=0;
			u8 Read_CMD=Prom_Read_CMD;


			for(i=0;i<8;i++)
		    {

				/*********CMD to read Memory address****************/
				IIC_Start();
				IIC_Send_Byte(MS5607BA_ADR_Write);//发送器件地址	
				err = IIC_Wait_Ack();
				IIC_Send_Byte(Read_CMD);//Prom Read CMD
				err = IIC_Wait_Ack();
				IIC_Stop();

				/*****Answer from MS5607-02********/
				IIC_Start();
				IIC_Send_Byte(MS5607BA_ADR_Read);//发送器件地址	

				err = IIC_Wait_Ack();

				Promdata[0] = IIC_Read_Byte(1);

				Promdata[1] = IIC_Read_Byte(0);	

				IIC_Stop();

				Cal_C[i]=Promdata[0]<<8|Promdata[1];//Read PromData Storage Value Cal_C
			  	
		        Read_CMD+=2;   //Read Next Promdata CMD


		   }
			 
		
  	 printf("\n The MS561101BA is reading PROM : \r\n");    // printf("\r\nC1 = %d\r\nC2 = %d\r\nC3 = %d\r\nC4 = %d\r\nC5 = %d\r\nC6 = %d\r\n",temp1[1],temp1[2],temp1[3],temp1[4],temp1[5],temp1[6]);  
  }

读取D1值

u32  MS5607BA_Conversion_GetPressure(void)
  {
  	   
		u8 Press_Temp[3]={0};

		u32 D1_PessTmp=0;

		MS5607_Send_CMD(MS5607BA_D1_OSR_4096);
	   delay_ms(50);  
		MS5607_Send_CMD(MS5607BA_ADC_READ); 
		delay_ms(50);  
		MS5607_ADC_Answer(Press_Temp);
		
		delay_ms(50);  

		D1_PessTmp= Press_Temp[0]<<16| Press_Temp[1]<<8|Press_Temp[2];

		return D1_PessTmp;
      
  
  }

读取D2 温度的数字值

u32  MS5607BA_Conversion_Temp(void)
  {
  	   
		u8 Tempbuf[3]={0};	

		u32 D2_Data;


		MS5607_Send_CMD(MS5607BA_D2_OSR_4096);
			   delay_ms(50); 
		MS5607_Send_CMD(MS5607BA_ADC_READ); 
			   delay_ms(50); 
		MS5607_ADC_Answer(Tempbuf);
			   delay_ms(50); 

		D2_Data= Tempbuf[0]<<16| Tempbuf[1]<<8|Tempbuf[2];

		return D2_Data;
      
  }

计算温度

char MS5607_GetTemperature (void)     //计算温度
{
	D2_Temp = MS5607BA_Conversion_Temp();      //循环读取 温度

	if(D2_Temp == 0)
		return 0;
	
		delay_ms ( 20 );

	if(D2_Temp > (  ( uint32_t ) Cal_C[5] * (0x00000001 << 8) ))
		dT	= D2_Temp - (  ( uint32_t ) Cal_C[5] * (0x00000001 << 8) );  //公式 dT = D2 - TREF = D2 - C5 * 2^8
	else
	{
		dT	= (  ( uint32_t ) Cal_C[5] * (0x00000001 << 8) ) - D2_Temp;   	
		dT *= -1;
	}
	Temperature	= 2000 + (( dT * Cal_C[6] ) / (0x00000001 << 23)); //算出温度值的100倍,2001表示20.01°  公式TEMP =20°C + dT * TEMPSENS =2000 + dT * C6 / 2^23

	if(Temperature<-4000) Temperature=-4000;
	if(Temperature>8500) Temperature=8500;
	return 1;
}

计算温度补偿压力

char MS5607_GetPressure (void)  //计算温度补偿压力
{
	
	
	D1_Pess = MS5607BA_Conversion_GetPressure();   //循环读取 D1 D2

	if(D1_Pess == 0)

		return 0;
	
	 delay_ms ( 20 );
	
	OFF	=  ( ( float)Cal_C[2] * (0x00000001 << 17) ) + ( ( float ) Cal_C[4] * dT ) / 64.0;    //公式 OFF = OFFT1 + TCO *dT = C2 *2^17 +(C4 *dT )/ 2^6
	SENS 		= ( ( float ) Cal_C[1] * (0x00000001 << 16) ) + ( ( float ) Cal_C[3] * dT ) / 128.0; //公式SENS = SENST1 + TCS* dT= C1 * 2^16 + (C3 * dT )/ 2^7

	//温度补偿部分    逻辑看芯片手册   
	
	if ( Temperature < 2000 ) // second order temperature compensation when under 20 degrees C
	{
		T2 = ( dT * dT ) / (( u32 )0x0000000001 << 31);
		OFF2 		= 61 *  (( Temperature - 2000 ) * ( Temperature - 2000 )) / 16;
		SENS2		= 2 * (( Temperature - 2000 ) * ( Temperature - 2000 )) ;
		if ( Temperature < -1500 )
		{
			OFF2 		= OFF2 + 15 * (( Temperature + 1500 ) * ( Temperature + 1500 )) ;
			SENS2		= SENS2 + 8 * (( Temperature + 1500 ) * ( Temperature + 1500 )) ;
		}
	}
	else		//(Temperature > 2000)
	{
		T2 = 0;
		OFF2 		= 0;
		SENS2		= 0;
	}

	Temperature = Temperature - T2;
	OFF			= OFF - OFF2;
	SENS 		= SENS - SENS2;
	
	
	Press = ( D1_Pess * SENS / (0x00000001 << 21) - OFF ) / (0x00000001 << 15); //公式 P = D1 * SENS - OFF = (D1 * SENS / 2^21 - OFF) / 2^15

    MS5607TempPress.Pressure=(float)Press/100;//单位  mbar 
	MS5607TempPress.Temperature=(float)Temperature/100;//单位  ℃
        

	if(MS5607TempPress.Temperature<-40)MS5607TempPress.Temperature=-40;
	if(MS5607TempPress.Temperature>85)  MS5607TempPress.Temperature=85;
	if(MS5607TempPress.Pressure<10) 		MS5607TempPress.Pressure=10;
	if(MS5607TempPress.Pressure>1200) 	 MS5607TempPress.Pressure=1200;

		
	return 1;
}

开始的时候全速运行的时候读数有问题,最后发现两个命令之间时间太短没有延迟时间,单步调试时好的。在进行修改了延迟时间后全速运行是可行的,在折腾了一天后终于可以检测到温度压力以及湿度的值。
温湿度以及气压的值如下变量的所示:
STM32 模拟IIC驱动MS5607气压传感器调试记录_第4张图片

你可能感兴趣的:(STM32 模拟IIC驱动MS5607气压传感器调试记录)