标题 STM32 模拟IIC驱动MS5607调试记录
因项目需求,需使用MS5607的作为检测气压,再此写下自己遇见的问题以及调试记录。
硬件原理图如下:
IIC接口总线使用了气压传感器,SHT35温度传感器,调试MS5607硬件的7位地址是0X76。所以写的地址是0xEC,读操作的地址是0XED.
在第一次写数据的时候MCU无法得到ACK回应,最后查到的问题是地址错误导致的无回馈信号,在发送正确的时序图如下:
MS5607操作指令:
复位指令:
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 CMDerr = 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 CMDerr = 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 CMDerr = 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_CRead_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^8else{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^23if(Temperature<-4000) Temperature=-4000;if(Temperature>8500) Temperature=8500;return 1;
}
计算温度补偿压力
char MS5607_GetPressure (void) //计算温度补偿压力
{D1_Pess = MS5607BA_Conversion_GetPressure(); //循环读取 D1 D2if(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^6SENS = ( ( 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^15MS5607TempPress.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;
}
开始的时候全速运行的时候读数有问题,最后发现两个命令之间时间太短没有延迟时间,单步调试时好的。在进行修改了延迟时间后全速运行是可行的,在折腾了一天后终于可以检测到温度压力以及湿度的值。
温湿度以及气压的值如下变量的所示: